From 60a1968fa19a6f936bda2a34e80e3164676ffaaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Thu, 17 Oct 2019 15:27:07 +0200 Subject: [PATCH] v3d: support for texture buffer objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Juan A. Suarez Romero Reviewed-by: Iago Toral Quiroga Part-of: --- src/gallium/drivers/v3d/v3d_program.c | 8 +++- src/gallium/drivers/v3d/v3d_resource.c | 6 ++- src/gallium/drivers/v3d/v3d_uniforms.c | 34 ++++++++++++-- src/gallium/drivers/v3d/v3dx_state.c | 65 +++++++++++++++++++++----- 4 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_program.c b/src/gallium/drivers/v3d/v3d_program.c index 1fbffbe2a22..8737dde551b 100644 --- a/src/gallium/drivers/v3d/v3d_program.c +++ b/src/gallium/drivers/v3d/v3d_program.c @@ -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), diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index 0885a2cb80f..d7746bf9cfd 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -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; diff --git a/src/gallium/drivers/v3d/v3d_uniforms.c b/src/gallium/drivers/v3d/v3d_uniforms.c index d633eb709b8..4bcf92cd149 100644 --- a/src/gallium/drivers/v3d/v3d_uniforms.c +++ b/src/gallium/drivers/v3d/v3d_uniforms.c @@ -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; diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index e266588a2a0..34b72353c2b 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -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);