Mesa (main): freedreno/a6xx: Use fd6_view for non-buffer image descriptors, too.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 11 00:48:00 UTC 2021


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

Author: Emma Anholt <emma at anholt.net>
Date:   Mon Oct 18 15:18:14 2021 -0700

freedreno/a6xx: Use fd6_view for non-buffer image descriptors, too.

This deletes a whole lot of code, but there's a modest drawoverhead perf
loss:

drawoverhead 1-image change -6.48856% +/- 4.28269% (n=50)
drawoverhead 8-image change -5.29195% +/- 2.62549% (n=90)

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

---

 src/gallium/drivers/freedreno/a6xx/fd6_emit.c    |   2 +-
 src/gallium/drivers/freedreno/a6xx/fd6_image.c   | 271 ++++-------------------
 src/gallium/drivers/freedreno/a6xx/fd6_image.h   |   2 +-
 src/gallium/drivers/freedreno/a6xx/fd6_texture.h |  22 --
 4 files changed, 47 insertions(+), 250 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
index 863550ecbc6..b19e8158f70 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
@@ -434,7 +434,7 @@ fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
             if (idx & IBO_SSBO) {
                fd6_emit_ssbo_tex(ctx, state, &buf->sb[idx & ~IBO_SSBO]);
             } else {
-               fd6_emit_image_tex(state, &img->si[idx]);
+               fd6_emit_image_tex(ctx, 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 288c7666e2a..3a778b916fb 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c
@@ -77,181 +77,64 @@ fd6_ssbo_descriptor(struct fd_context *ctx,
 }
 
 static void
-fd6_image_descriptor(struct fd_context *ctx, const struct pipe_image_view *buf,
-                     uint32_t *descriptor)
+fd6_emit_image_descriptor(struct fd_context *ctx, struct fd_ringbuffer *ring, const struct pipe_image_view *buf, bool ibo)
 {
-   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;
-   enum a6xx_tex_type type;
-   bool srgb;
-   uint32_t cpp;
-   uint32_t level;
-   uint32_t width;
-   uint32_t height;
-   uint32_t depth;
-   uint32_t pitch;
-   uint32_t array_pitch;
-   struct fd_bo *bo;
-   uint32_t ubwc_offset;
-   uint32_t offset;
-   bool buffer;
-};
-
-static void
-translate_image(struct fd6_image *img, const struct pipe_image_view *pimg)
-{
-   enum pipe_format format = pimg->format;
-   struct pipe_resource *prsc = pimg->resource;
-   struct fd_resource *rsc = fd_resource(prsc);
-
-   if (!prsc) {
-      memset(img, 0, sizeof(*img));
-      return;
-   }
-
-   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;
-
-   /* Treat cube textures as 2d-array: */
-   if (img->type == A6XX_TEX_CUBE)
-      img->type = A6XX_TEX_2D;
-
-   if (prsc->target == PIPE_BUFFER) {
-      img->buffer = true;
-      img->ubwc_offset = 0; /* not valid for buffers */
-      img->offset = pimg->u.buf.offset;
-      img->pitch = 0;
-      img->array_pitch = 0;
-
-      /* size is encoded with low 15b in WIDTH and high bits in
-       * HEIGHT, in units of elements:
-       */
-      unsigned sz = pimg->u.buf.size / util_format_get_blocksize(format);
-      img->width = sz & MASK(15);
-      img->height = sz >> 15;
-      img->depth = 0;
-      img->level = 0;
-   } else {
-      img->buffer = false;
-
-      unsigned lvl = pimg->u.tex.level;
-      unsigned layers = pimg->u.tex.last_layer - pimg->u.tex.first_layer + 1;
-
-      img->ubwc_offset =
-         fd_resource_ubwc_offset(rsc, lvl, pimg->u.tex.first_layer);
-      img->offset = fd_resource_offset(rsc, lvl, pimg->u.tex.first_layer);
-      img->pitch = fd_resource_pitch(rsc, lvl);
-
-      switch (prsc->target) {
-      case PIPE_TEXTURE_RECT:
-      case PIPE_TEXTURE_1D:
-      case PIPE_TEXTURE_2D:
-         img->array_pitch = rsc->layout.layer_size;
-         img->depth = 1;
-         break;
-      case PIPE_TEXTURE_1D_ARRAY:
-      case PIPE_TEXTURE_2D_ARRAY:
-      case PIPE_TEXTURE_CUBE:
-      case PIPE_TEXTURE_CUBE_ARRAY:
-         img->array_pitch = rsc->layout.layer_size;
-         // TODO the CUBE/CUBE_ARRAY might need to be layers/6 for tex state,
-         // but empirically for ibo state it shouldn't be divided.
-         img->depth = layers;
-         break;
-      case PIPE_TEXTURE_3D:
-         img->array_pitch = fd_resource_slice(rsc, lvl)->size0;
-         img->depth = u_minify(prsc->depth0, lvl);
-         break;
-      default:
-         break;
-      }
-
-      img->level = lvl;
-      img->width = u_minify(prsc->width0, lvl);
-      img->height = u_minify(prsc->height0, lvl);
-   }
-}
-
-static void
-emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img)
-{
-   if (!img->prsc) {
+   struct fd_resource *rsc = fd_resource(buf->resource);
+   if (!rsc) {
       for (int i = 0; i < FDL6_TEX_CONST_DWORDS; i++)
          OUT_RING(ring, 0);
       return;
    }
 
-   struct fd_resource *rsc = fd_resource(img->prsc);
-   bool ubwc_enabled = fd_resource_ubwc_enabled(rsc, img->level);
-
-   OUT_RING(ring,
-            fd6_tex_const_0(img->prsc, img->level, img->pfmt, PIPE_SWIZZLE_X,
-                            PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W));
-   OUT_RING(ring, A6XX_TEX_CONST_1_WIDTH(img->width) |
-                     A6XX_TEX_CONST_1_HEIGHT(img->height));
-   OUT_RING(ring,
-            COND(img->buffer, A6XX_TEX_CONST_2_UNK4 | A6XX_TEX_CONST_2_UNK31) |
-               A6XX_TEX_CONST_2_TYPE(img->type) |
-               A6XX_TEX_CONST_2_PITCH(img->pitch));
-   OUT_RING(ring, A6XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch) |
-                     COND(ubwc_enabled, A6XX_TEX_CONST_3_FLAG) |
-                     COND(rsc->layout.tile_all, A6XX_TEX_CONST_3_TILE_ALL));
-   if (img->bo) {
-      OUT_RELOC(ring, img->bo, img->offset,
-                (uint64_t)A6XX_TEX_CONST_5_DEPTH(img->depth) << 32, 0);
+   if (buf->resource->target == PIPE_BUFFER) {
+   uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
+      fdl6_buffer_view_init(descriptor, buf->format, swiz_identity,
+                           buf->u.buf.offset, /* Using relocs for addresses */
+                           buf->u.buf.size);
+   fd6_emit_single_plane_descriptor(ring, buf->resource, descriptor);
    } else {
-      OUT_RING(ring, 0x00000000);
-      OUT_RING(ring, A6XX_TEX_CONST_5_DEPTH(img->depth));
-   }
+      struct fdl_view_args args = {
+         /* Using relocs for addresses */
+         .iova = 0,
 
-   OUT_RING(ring, 0x00000000); /* texconst6 */
-
-   if (ubwc_enabled) {
-      uint32_t block_width, block_height;
-      fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height);
-
-      OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
-      OUT_RING(ring, A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(
-                        rsc->layout.ubwc_layer_size >> 2));
-      OUT_RING(ring, A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(
-                        fdl_ubwc_pitch(&rsc->layout, img->level)) |
-                        A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(
-                           DIV_ROUND_UP(img->width, block_width))) |
-                        A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(
-                           DIV_ROUND_UP(img->height, block_height))));
-   } else {
-      OUT_RING(ring, 0x00000000); /* texconst7 */
-      OUT_RING(ring, 0x00000000); /* texconst8 */
-      OUT_RING(ring, 0x00000000); /* texconst9 */
-      OUT_RING(ring, 0x00000000); /* texconst10 */
-   }
+         .base_miplevel = buf->u.tex.level,
+         .level_count = 1,
+
+         .base_array_layer = buf->u.tex.first_layer,
+         .layer_count = buf->u.tex.last_layer - buf->u.tex.first_layer + 1,
 
-   OUT_RING(ring, 0x00000000); /* texconst11 */
-   OUT_RING(ring, 0x00000000); /* texconst12 */
-   OUT_RING(ring, 0x00000000); /* texconst13 */
-   OUT_RING(ring, 0x00000000); /* texconst14 */
-   OUT_RING(ring, 0x00000000); /* texconst15 */
+         .format = buf->format,
+         .swiz = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
+                  PIPE_SWIZZLE_W},
+
+         .type = fdl_type_from_pipe_target(buf->resource->target),
+         .chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN,
+                            FDL_CHROMA_LOCATION_COSITED_EVEN},
+      };
+
+      /* fdl6_view makes the storage descriptor treat cubes like a 2D array (so
+       * you can reference a specific layer), but we need to do that for the
+       * texture descriptor as well to get our layer.
+       */
+      if (args.type == FDL_VIEW_TYPE_CUBE)
+         args.type = FDL_VIEW_TYPE_2D;
+
+      struct fdl6_view view;
+      const struct fdl_layout *layouts[3] = {&rsc->layout, NULL, NULL};
+      fdl6_view_init(&view, layouts, &args,
+                     ctx->screen->info->a6xx.has_z24uint_s8uint);
+      if (ibo)
+         fd6_emit_single_plane_descriptor(ring, buf->resource, view.storage_descriptor);
+      else
+         fd6_emit_single_plane_descriptor(ring, buf->resource, view.descriptor);
+   }
 }
 
 void
-fd6_emit_image_tex(struct fd_ringbuffer *ring,
+fd6_emit_image_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
                    const struct pipe_image_view *pimg)
 {
-   struct fd6_image img;
-   translate_image(&img, pimg);
-   emit_image_tex(ring, &img);
+   fd6_emit_image_descriptor(ctx, ring, pimg, false);
 }
 
 void
@@ -263,61 +146,6 @@ fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
    fd6_emit_single_plane_descriptor(ring, pbuf->buffer, descriptor);
 }
 
-static void
-emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img)
-{
-   /* If the SSBO isn't present (becasue gallium doesn't pack atomic
-    * counters), zero-fill the slot.
-    */
-   if (!img->prsc) {
-      for (int i = 0; i < 16; i++)
-         OUT_RING(ring, 0);
-      return;
-   }
-
-   struct fd_resource *rsc = fd_resource(img->prsc);
-   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)) |
-                     A6XX_IBO_0_TILE_MODE(tile_mode));
-   OUT_RING(ring,
-            A6XX_IBO_1_WIDTH(img->width) | A6XX_IBO_1_HEIGHT(img->height));
-   OUT_RING(ring, A6XX_IBO_2_PITCH(img->pitch) |
-                     COND(img->buffer, A6XX_IBO_2_UNK4 | A6XX_IBO_2_UNK31) |
-                     A6XX_IBO_2_TYPE(img->type));
-   OUT_RING(ring, A6XX_IBO_3_ARRAY_PITCH(img->array_pitch) |
-                     COND(ubwc_enabled, A6XX_IBO_3_FLAG | A6XX_IBO_3_UNK27));
-   if (img->bo) {
-      OUT_RELOC(ring, img->bo, img->offset,
-                (uint64_t)A6XX_IBO_5_DEPTH(img->depth) << 32, 0);
-   } else {
-      OUT_RING(ring, 0x00000000);
-      OUT_RING(ring, A6XX_IBO_5_DEPTH(img->depth));
-   }
-   OUT_RING(ring, 0x00000000);
-
-   if (ubwc_enabled) {
-      OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
-      OUT_RING(ring, A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(
-                        rsc->layout.ubwc_layer_size >> 2));
-      OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(
-                        fdl_ubwc_pitch(&rsc->layout, img->level)));
-   } else {
-      OUT_RING(ring, 0x00000000);
-      OUT_RING(ring, 0x00000000);
-      OUT_RING(ring, 0x00000000);
-      OUT_RING(ring, 0x00000000);
-   }
-
-   OUT_RING(ring, 0x00000000);
-   OUT_RING(ring, 0x00000000);
-   OUT_RING(ring, 0x00000000);
-   OUT_RING(ring, 0x00000000);
-   OUT_RING(ring, 0x00000000);
-}
-
 /* Build combined image/SSBO "IBO" state, returns ownership of state reference */
 struct fd_ringbuffer *
 fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
@@ -341,16 +169,7 @@ fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
    }
 
    for (unsigned i = 0; i < v->shader->nir->info.num_images; i++) {
-      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);
-      }
+      fd6_emit_image_descriptor(ctx, state, &imgso->si[i], true);
    }
 
    return state;
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.h b/src/gallium/drivers/freedreno/a6xx/fd6_image.h
index da7b21c1faf..439317ea572 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_image.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.h
@@ -30,7 +30,7 @@
 
 #include "freedreno_context.h"
 
-void fd6_emit_image_tex(struct fd_ringbuffer *ring,
+void fd6_emit_image_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
                         const struct pipe_image_view *pimg) assert_dt;
 void fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        const struct pipe_shader_buffer *pbuf) assert_dt;
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h
index d02278866db..6882aaa639f 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h
@@ -77,28 +77,6 @@ void fd6_sampler_view_update(struct fd_context *ctx,
 void fd6_texture_init(struct pipe_context *pctx);
 void fd6_texture_fini(struct pipe_context *pctx);
 
-static inline enum a6xx_tex_type
-fd6_tex_type(unsigned target)
-{
-   switch (target) {
-   default:
-      assert(0);
-   case PIPE_BUFFER:
-   case PIPE_TEXTURE_1D:
-   case PIPE_TEXTURE_1D_ARRAY:
-      return A6XX_TEX_1D;
-   case PIPE_TEXTURE_RECT:
-   case PIPE_TEXTURE_2D:
-   case PIPE_TEXTURE_2D_ARRAY:
-      return A6XX_TEX_2D;
-   case PIPE_TEXTURE_3D:
-      return A6XX_TEX_3D;
-   case PIPE_TEXTURE_CUBE:
-   case PIPE_TEXTURE_CUBE_ARRAY:
-      return A6XX_TEX_CUBE;
-   }
-}
-
 static inline unsigned
 fd6_border_color_offset(struct fd_context *ctx, enum pipe_shader_type type,
                         struct fd_texture_stateobj *tex) assert_dt



More information about the mesa-commit mailing list