v3d: support for texture buffer objects

This commit handles the support for texture buffer objects. In general
it is mostly about using the buffer info from the pipe_image_view
instead of the texture info.

v2:
 - Rework some assertions (Iago)
 - Remove needless comment (Alejandro)
 - Fix comment typos (Iago)

v3:
 - Fix typos (Iago)

Signed-off-by: Alejandro Piñeiro <apinheiro@igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13409>
This commit is contained in:
Alejandro Piñeiro 2019-10-17 15:27:07 +02:00 committed by Marge Bot
parent a2d8c5b26d
commit 60a1968fa1
4 changed files with 95 additions and 18 deletions

View File

@ -457,10 +457,16 @@ v3d_setup_shared_key(struct v3d_context *v3d, struct v3d_key *key,
if (!sampler)
continue;
assert(sampler->target == PIPE_BUFFER || sampler_state);
unsigned compare_mode = sampler_state ?
sampler_state->compare_mode :
PIPE_TEX_COMPARE_NONE;
key->sampler[i].return_size =
v3d_get_tex_return_size(devinfo,
sampler->format,
sampler_state->compare_mode);
compare_mode);
/* For 16-bit, we set up the sampler to always return 2
* channels (meaning no recompiles for most statechanges),

View File

@ -764,7 +764,11 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen,
/* Use a tiled layout if we can, for better 3D performance. */
bool should_tile = true;
/* VBOs/PBOs are untiled (and 1 height). */
assert(tmpl->target != PIPE_BUFFER ||
(tmpl->format == PIPE_FORMAT_NONE ||
util_format_get_blocksize(tmpl->format) == 1));
/* VBOs/PBOs/Texture Buffer Objects are untiled (and 1 height). */
if (tmpl->target == PIPE_BUFFER)
should_tile = false;

View File

@ -54,20 +54,27 @@ get_texture_size(struct v3d_texture_stateobj *texstate,
uint32_t data)
{
struct pipe_sampler_view *texture = texstate->textures[data];
switch (contents) {
case QUNIFORM_TEXTURE_WIDTH:
return u_minify(texture->texture->width0,
texture->u.tex.first_level);
if (texture->target == PIPE_BUFFER) {
return texture->u.buf.size /
util_format_get_blocksize(texture->format);
} else {
return u_minify(texture->texture->width0,
texture->u.tex.first_level);
}
case QUNIFORM_TEXTURE_HEIGHT:
return u_minify(texture->texture->height0,
texture->u.tex.first_level);
case QUNIFORM_TEXTURE_DEPTH:
assert(texture->target != PIPE_BUFFER);
return u_minify(texture->texture->depth0,
texture->u.tex.first_level);
case QUNIFORM_TEXTURE_ARRAY_SIZE:
assert(texture->target != PIPE_BUFFER);
return texture->texture->array_size;
case QUNIFORM_TEXTURE_LEVELS:
assert(texture->target != PIPE_BUFFER);
return (texture->u.tex.last_level -
texture->u.tex.first_level) + 1;
default:
@ -84,15 +91,23 @@ get_image_size(struct v3d_shaderimg_stateobj *shaderimg,
switch (contents) {
case QUNIFORM_IMAGE_WIDTH:
return u_minify(image->base.resource->width0,
image->base.u.tex.level);
if (image->base.resource->target == PIPE_BUFFER) {
return image->base.u.buf.size /
util_format_get_blocksize(image->base.format);
} else {
return u_minify(image->base.resource->width0,
image->base.u.tex.level);
}
case QUNIFORM_IMAGE_HEIGHT:
assert(image->base.resource->target != PIPE_BUFFER);
return u_minify(image->base.resource->height0,
image->base.u.tex.level);
case QUNIFORM_IMAGE_DEPTH:
assert(image->base.resource->target != PIPE_BUFFER);
return u_minify(image->base.resource->depth0,
image->base.u.tex.level);
case QUNIFORM_IMAGE_ARRAY_SIZE:
assert(image->base.resource->target != PIPE_BUFFER);
return image->base.resource->array_size;
default:
unreachable("Bad texture size field");
@ -199,6 +214,15 @@ write_tmu_p1(struct v3d_job *job,
struct v3d_sampler_view *sview = v3d_sampler_view(psview);
int variant = 0;
/* If we are being asked by the compiler to write parameter 1, then we
* need that. So if we are at this point, we should expect to have a
* sampler and psampler. As an additional assert, we can check that we
* are not on a texel buffer case, as these don't have a sampler.
*/
assert(psview->target != PIPE_BUFFER);
assert(sampler);
assert(psampler);
if (sampler->border_color_variants)
variant = sview->sampler_variant;

View File

@ -824,6 +824,34 @@ translate_swizzle(unsigned char pipe_swizzle)
}
#endif
static void
v3d_setup_texture_shader_state_from_buffer(struct V3DX(TEXTURE_SHADER_STATE) *tex,
struct pipe_resource *prsc,
enum pipe_format format,
unsigned offset,
unsigned size)
{
struct v3d_resource *rsc = v3d_resource(prsc);
tex->image_depth = 1;
tex->image_width = size / util_format_get_blocksize(format);
/* On 4.x, the height of a 1D texture is redefined to be the
* upper 14 bits of the width (which is only usable with txf).
*/
tex->image_height = tex->image_width >> 14;
tex->image_width &= (1 << 14) - 1;
tex->image_height &= (1 << 14) - 1;
/* Note that we don't have a job to reference the texture's sBO
* at state create time, so any time this sampler view is used
* we need to add the texture to the job.
*/
tex->texture_base_pointer =
cl_address(NULL, rsc->bo->offset + offset);
}
static void
v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex,
struct pipe_resource *prsc,
@ -912,11 +940,18 @@ v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,
#endif
v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {
v3d_setup_texture_shader_state(&tex, prsc,
cso->u.tex.first_level,
cso->u.tex.last_level,
cso->u.tex.first_layer,
cso->u.tex.last_layer);
if (prsc->target != PIPE_BUFFER) {
v3d_setup_texture_shader_state(&tex, prsc,
cso->u.tex.first_level,
cso->u.tex.last_level,
cso->u.tex.first_layer,
cso->u.tex.last_layer);
} else {
v3d_setup_texture_shader_state_from_buffer(&tex, prsc,
cso->format,
cso->u.buf.offset,
cso->u.buf.size);
}
tex.srgb = util_format_is_srgb(cso->format);
@ -1093,7 +1128,8 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
* have to copy to a temporary tiled texture.
*/
if (!rsc->tiled && !(prsc->target == PIPE_TEXTURE_1D ||
prsc->target == PIPE_TEXTURE_1D_ARRAY)) {
prsc->target == PIPE_TEXTURE_1D_ARRAY ||
prsc->target == PIPE_BUFFER)) {
struct v3d_resource *shadow_parent = rsc;
struct pipe_resource tmpl = {
.target = prsc->target,
@ -1315,11 +1351,18 @@ v3d_create_image_view_texture_shader_state(struct v3d_context *v3d,
struct pipe_resource *prsc = iview->base.resource;
v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {
v3d_setup_texture_shader_state(&tex, prsc,
iview->base.u.tex.level,
iview->base.u.tex.level,
iview->base.u.tex.first_layer,
iview->base.u.tex.last_layer);
if (prsc->target != PIPE_BUFFER) {
v3d_setup_texture_shader_state(&tex, prsc,
iview->base.u.tex.level,
iview->base.u.tex.level,
iview->base.u.tex.first_layer,
iview->base.u.tex.last_layer);
} else {
v3d_setup_texture_shader_state_from_buffer(&tex, prsc,
iview->base.format,
iview->base.u.buf.offset,
iview->base.u.buf.size);
}
tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);
tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);