Mesa (main): freedreno/a6xx: Use the fdl buffer view setup for img/ssbo descriptors.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Nov 3 20:02:41 UTC 2021


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

Author: Emma Anholt <emma at anholt.net>
Date:   Fri Oct 29 16:57:02 2021 -0700

freedreno/a6xx: Use the fdl buffer view setup for img/ssbo descriptors.

The single-plane descriptor emit helper doesn't strictly need the UBWC
reloc, since imageBuffer can't be UBWC, but it means the function is ready
to be used for non-buffer image descriptors later.

no-hw drawoverhead 1-imageBuffer change throughput 1.95457% +/- 1.44325%
(n=127).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13635>

---

 src/gallium/drivers/freedreno/a6xx/fd6_emit.c  |   2 +-
 src/gallium/drivers/freedreno/a6xx/fd6_image.c | 121 +++++++++++++++----------
 src/gallium/drivers/freedreno/a6xx/fd6_image.h |   2 +-
 3 files changed, 73 insertions(+), 52 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
index 85cbf0996d5..e7484d5d4b4 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
@@ -432,7 +432,7 @@ fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
          for (unsigned i = 0; i < mapping->num_tex; i++) {
             unsigned idx = mapping->tex_to_image[i];
             if (idx & IBO_SSBO) {
-               fd6_emit_ssbo_tex(state, &buf->sb[idx & ~IBO_SSBO]);
+               fd6_emit_ssbo_tex(ctx, state, &buf->sb[idx & ~IBO_SSBO]);
             } else {
                fd6_emit_image_tex(state, &img->si[idx]);
             }
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c
index 347d83a239a..288c7666e2a 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c
@@ -35,6 +35,58 @@
 #include "fd6_resource.h"
 #include "fd6_texture.h"
 
+static const uint8_t swiz_identity[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+                                         PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W};
+
+static void
+fd6_emit_single_plane_descriptor(struct fd_ringbuffer *ring,
+                                 struct pipe_resource *prsc,
+                                 uint32_t *descriptor)
+{
+   /* If the resource isn't present (holes are allowed), zero-fill the slot. */
+   if (!prsc) {
+      for (int i = 0; i < 16; i++)
+         OUT_RING(ring, 0);
+      return;
+   }
+
+   struct fd_resource *rsc = fd_resource(prsc);
+   for (int i = 0; i < 4; i++)
+      OUT_RING(ring, descriptor[i]);
+
+   OUT_RELOC(ring, rsc->bo, descriptor[4], (uint64_t)descriptor[5] << 32, 0);
+
+   OUT_RING(ring, descriptor[6]);
+
+   OUT_RELOC(ring, rsc->bo, descriptor[7], (uint64_t)descriptor[8] << 32, 0);
+
+   for (int i = 9; i < FDL6_TEX_CONST_DWORDS; i++)
+      OUT_RING(ring, descriptor[i]);
+}
+
+static void
+fd6_ssbo_descriptor(struct fd_context *ctx,
+                    const struct pipe_shader_buffer *buf, uint32_t *descriptor)
+{
+   fdl6_buffer_view_init(
+      descriptor,
+      ctx->screen->info->a6xx.storage_16bit ? PIPE_FORMAT_R16_UINT
+                                            : PIPE_FORMAT_R32_UINT,
+      swiz_identity, buf->buffer_offset, /* Using relocs for addresses */
+      buf->buffer_size);
+}
+
+static void
+fd6_image_descriptor(struct fd_context *ctx, const struct pipe_image_view *buf,
+                     uint32_t *descriptor)
+{
+   assert(buf->resource->target == PIPE_BUFFER);
+
+   fdl6_buffer_view_init(descriptor, buf->format, swiz_identity,
+                         buf->u.buf.offset, /* Using relocs for addresses */
+                         buf->u.buf.size);
+}
+
 struct fd6_image {
    struct pipe_resource *prsc;
    enum pipe_format pfmt;
@@ -132,45 +184,6 @@ translate_image(struct fd6_image *img, const struct pipe_image_view *pimg)
    }
 }
 
-static void
-translate_buf(struct fd6_image *img, const struct pipe_shader_buffer *pimg)
-{
-   struct pipe_resource *prsc = pimg->buffer;
-   struct fd_resource *rsc = fd_resource(prsc);
-
-   if (!prsc) {
-      memset(img, 0, sizeof(*img));
-      return;
-   }
-
-   const struct fd_dev_info *dev_info = fd_screen(prsc->screen)->info;
-   enum pipe_format format = dev_info->a6xx.storage_16bit
-                                ? PIPE_FORMAT_R16_UINT
-                                : PIPE_FORMAT_R32_UINT;
-
-   img->prsc = prsc;
-   img->pfmt = format;
-   img->type = fd6_tex_type(prsc->target);
-   img->srgb = util_format_is_srgb(format);
-   img->cpp = rsc->layout.cpp;
-   img->bo = rsc->bo;
-   img->buffer = true;
-
-   img->ubwc_offset = 0; /* not valid for buffers */
-   img->offset = pimg->buffer_offset;
-   img->pitch = 0;
-   img->array_pitch = 0;
-   img->level = 0;
-
-   /* size is encoded with low 15b in WIDTH and high bits in HEIGHT,
-    * in units of elements:
-    */
-   unsigned sz = pimg->buffer_size / (dev_info->a6xx.storage_16bit ? 2 : 4);
-   img->width = sz & MASK(15);
-   img->height = sz >> 15;
-   img->depth = 0;
-}
-
 static void
 emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img)
 {
@@ -242,12 +255,12 @@ fd6_emit_image_tex(struct fd_ringbuffer *ring,
 }
 
 void
-fd6_emit_ssbo_tex(struct fd_ringbuffer *ring,
+fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
                   const struct pipe_shader_buffer *pbuf)
 {
-   struct fd6_image img;
-   translate_buf(&img, pbuf);
-   emit_image_tex(ring, &img);
+   uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
+   fd6_ssbo_descriptor(ctx, pbuf, descriptor);
+   fd6_emit_single_plane_descriptor(ring, pbuf->buffer, descriptor);
 }
 
 static void
@@ -266,7 +279,8 @@ emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img)
    enum a6xx_tile_mode tile_mode = fd_resource_tile_mode(img->prsc, img->level);
    bool ubwc_enabled = fd_resource_ubwc_enabled(rsc, img->level);
 
-   OUT_RING(ring, A6XX_IBO_0_FMT(fd6_texture_format(img->pfmt, rsc->layout.tile_mode)) |
+   OUT_RING(ring, A6XX_IBO_0_FMT(
+                     fd6_texture_format(img->pfmt, rsc->layout.tile_mode)) |
                      A6XX_IBO_0_TILE_MODE(tile_mode));
    OUT_RING(ring,
             A6XX_IBO_1_WIDTH(img->width) | A6XX_IBO_1_HEIGHT(img->height));
@@ -320,16 +334,23 @@ fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
 
    assert(shader == PIPE_SHADER_COMPUTE || shader == PIPE_SHADER_FRAGMENT);
 
+   uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
    for (unsigned i = 0; i < v->shader->nir->info.num_ssbos; i++) {
-      struct fd6_image img;
-      translate_buf(&img, &bufso->sb[i]);
-      emit_image_ssbo(state, &img);
+      fd6_ssbo_descriptor(ctx, &bufso->sb[i], descriptor);
+      fd6_emit_single_plane_descriptor(state, bufso->sb[i].buffer, descriptor);
    }
 
    for (unsigned i = 0; i < v->shader->nir->info.num_images; i++) {
-      struct fd6_image img;
-      translate_image(&img, &imgso->si[i]);
-      emit_image_ssbo(state, &img);
+      if (imgso->si[i].resource &&
+          imgso->si[i].resource->target == PIPE_BUFFER) {
+         fd6_image_descriptor(ctx, &imgso->si[i], descriptor);
+         fd6_emit_single_plane_descriptor(state, imgso->si[i].resource,
+                                          descriptor);
+      } else {
+         struct fd6_image img;
+         translate_image(&img, &imgso->si[i]);
+         emit_image_ssbo(state, &img);
+      }
    }
 
    return state;
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.h b/src/gallium/drivers/freedreno/a6xx/fd6_image.h
index 84838b9627a..da7b21c1faf 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_image.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.h
@@ -32,7 +32,7 @@
 
 void fd6_emit_image_tex(struct fd_ringbuffer *ring,
                         const struct pipe_image_view *pimg) assert_dt;
-void fd6_emit_ssbo_tex(struct fd_ringbuffer *ring,
+void fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        const struct pipe_shader_buffer *pbuf) assert_dt;
 
 struct ir3_shader_variant;



More information about the mesa-commit mailing list