Mesa (main): v3d: support for texture buffer objects

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Dec 3 16:10:51 UTC 2021


Module: Mesa
Branch: main
Commit: 60a1968fa19a6f936bda2a34e80e3164676ffaaa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=60a1968fa19a6f936bda2a34e80e3164676ffaaa

Author: Alejandro Piñeiro <apinheiro at igalia.com>
Date:   Thu Oct 17 15:27:07 2019 +0200

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 at igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez at igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13409>

---

 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);



More information about the mesa-commit mailing list