Mesa (main): radeonsi: don't invoke si_decompress_depth if textures are not dirty at binding

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 29 07:32:52 UTC 2021


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

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri Oct 22 13:49:00 2021 -0400

radeonsi: don't invoke si_decompress_depth if textures are not dirty at binding

This eliminates the overhead of invoking si_decompress_depth.

The complication here is that we need to update needs_depth_decompress_mask
every time we update dirty_level_mask.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13492>

---

 src/gallium/drivers/radeonsi/si_clear.c       |  1 +
 src/gallium/drivers/radeonsi/si_descriptors.c | 35 +++++++++++++++++++--------
 src/gallium/drivers/radeonsi/si_pipe.h        |  2 ++
 src/gallium/drivers/radeonsi/si_state.c       | 17 +++++++++++++
 src/gallium/drivers/radeonsi/si_state.h       |  1 +
 5 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index b8cf49a6b47..7e19b89e030 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -741,6 +741,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
       if ((eliminate_needed || fmask_decompress_needed) &&
           !(tex->dirty_level_mask & (1 << level))) {
          tex->dirty_level_mask |= 1 << level;
+         si_set_sampler_depth_decompress_mask(sctx, tex);
          p_atomic_inc(&sctx->screen->compressed_colortex_counter);
       }
 
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index bab6654df1b..6ea4610f774 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -490,14 +490,14 @@ static bool color_needs_decompression(struct si_texture *tex)
           (tex->dirty_level_mask && (tex->cmask_buffer || tex->surface.meta_offset));
 }
 
-static bool depth_needs_decompression(struct si_texture *tex)
+static bool depth_needs_decompression(struct si_texture *tex, bool is_stencil)
 {
    /* If the depth/stencil texture is TC-compatible, no decompression
     * will be done. The decompression function will only flush DB caches
     * to make it coherent with shaders. That's necessary because the driver
     * doesn't flush DB caches in any other case.
     */
-   return tex->db_compatible;
+   return tex->db_compatible && (tex->dirty_level_mask || (is_stencil && tex->stencil_dirty_level_mask));
 }
 
 static void si_reset_sampler_view_slot(struct si_samplers *samplers, unsigned slot,
@@ -548,15 +548,24 @@ static void si_set_sampler_views(struct si_context *sctx, unsigned shader,
                samplers->needs_depth_decompress_mask &= ~(1u << slot);
                samplers->needs_color_decompress_mask &= ~(1u << slot);
             } else {
-               if (depth_needs_decompression(tex)) {
-                  samplers->needs_depth_decompress_mask |= 1u << slot;
+               if (tex->is_depth) {
+                  samplers->has_depth_tex_mask |= 1u << slot;
+                  samplers->needs_color_decompress_mask &= ~(1u << slot);
+
+                  if (depth_needs_decompression(tex, sview->is_stencil_sampler)) {
+                     samplers->needs_depth_decompress_mask |= 1u << slot;
+                  } else {
+                     samplers->needs_depth_decompress_mask &= ~(1u << slot);
+                  }
                } else {
+                  samplers->has_depth_tex_mask &= ~(1u << slot);
                   samplers->needs_depth_decompress_mask &= ~(1u << slot);
-               }
-               if (color_needs_decompression(tex)) {
-                  samplers->needs_color_decompress_mask |= 1u << slot;
-               } else {
-                  samplers->needs_color_decompress_mask &= ~(1u << slot);
+
+                  if (color_needs_decompression(tex)) {
+                     samplers->needs_color_decompress_mask |= 1u << slot;
+                  } else {
+                     samplers->needs_color_decompress_mask &= ~(1u << slot);
+                  }
                }
 
                if (vi_dcc_enabled(tex, sview->base.u.tex.first_level) &&
@@ -597,6 +606,7 @@ static void si_set_sampler_views(struct si_context *sctx, unsigned shader,
 
    unbound_mask |= BITFIELD_RANGE(start_slot + count, unbind_num_trailing_slots);
    samplers->enabled_mask &= ~unbound_mask;
+   samplers->has_depth_tex_mask &= ~unbound_mask;
    samplers->needs_depth_decompress_mask &= ~unbound_mask;
    samplers->needs_color_decompress_mask &= ~unbound_mask;
 
@@ -613,6 +623,11 @@ static void si_update_shader_needs_decompress_mask(struct si_context *sctx, unsi
       sctx->shader_needs_decompress_mask |= shader_bit;
    else
       sctx->shader_needs_decompress_mask &= ~shader_bit;
+
+   if (samplers->has_depth_tex_mask)
+      sctx->shader_has_depth_tex |= shader_bit;
+   else
+      sctx->shader_has_depth_tex &= ~shader_bit;
 }
 
 static void si_pipe_set_sampler_views(struct pipe_context *ctx, enum pipe_shader_type shader,
@@ -2434,7 +2449,7 @@ static void si_make_texture_handle_resident(struct pipe_context *ctx, uint64_t h
       if (sview->base.texture->target != PIPE_BUFFER) {
          struct si_texture *tex = (struct si_texture *)sview->base.texture;
 
-         if (depth_needs_decompression(tex)) {
+         if (depth_needs_decompression(tex, sview->is_stencil_sampler)) {
             util_dynarray_append(&sctx->resident_tex_needs_depth_decompress,
                                  struct si_texture_handle *, tex_handle);
          }
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 6782069deec..26f32d42c36 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -732,6 +732,7 @@ struct si_samplers {
 
    /* The i-th bit is set if that element is enabled (non-NULL resource). */
    unsigned enabled_mask;
+   uint32_t has_depth_tex_mask;
    uint32_t needs_depth_decompress_mask;
    uint32_t needs_color_decompress_mask;
 };
@@ -1072,6 +1073,7 @@ struct si_context {
    unsigned descriptors_dirty;
    unsigned shader_pointers_dirty;
    unsigned shader_needs_decompress_mask;
+   unsigned shader_has_depth_tex;
    struct si_buffer_resources internal_bindings;
    struct si_buffer_resources const_and_shader_buffers[SI_NUM_SHADERS];
    struct si_samplers samplers[SI_NUM_SHADERS];
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index c5724f4bdea..1b46fe0885e 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2671,6 +2671,21 @@ static void si_init_depth_surface(struct si_context *sctx, struct si_surface *su
    surf->depth_initialized = true;
 }
 
+void si_set_sampler_depth_decompress_mask(struct si_context *sctx, struct si_texture *tex)
+{
+   /* Check all sampler bindings in all shaders where depth textures are bound, and update
+    * which samplers should be decompressed.
+    */
+   u_foreach_bit(sh, sctx->shader_has_depth_tex) {
+      u_foreach_bit(i, sctx->samplers[sh].has_depth_tex_mask) {
+         if (sctx->samplers[sh].views[i]->texture == &tex->buffer.b.b) {
+            sctx->samplers[sh].needs_depth_decompress_mask |= 1 << i;
+            sctx->shader_needs_decompress_mask |= 1 << sh;
+         }
+      }
+   }
+}
+
 void si_update_fb_dirtiness_after_rendering(struct si_context *sctx)
 {
    if (sctx->decompression_enabled)
@@ -2684,6 +2699,8 @@ void si_update_fb_dirtiness_after_rendering(struct si_context *sctx)
 
       if (tex->surface.has_stencil)
          tex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
+
+      si_set_sampler_depth_decompress_mask(sctx, tex);
    }
 
    unsigned compressed_cb_mask = sctx->framebuffer.compressed_cb_mask;
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 29965f83b43..e9dcb1da65b 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -539,6 +539,7 @@ struct pipe_sampler_view *si_create_sampler_view_custom(struct pipe_context *ctx
                                                         const struct pipe_sampler_view *state,
                                                         unsigned width0, unsigned height0,
                                                         unsigned force_level);
+void si_set_sampler_depth_decompress_mask(struct si_context *sctx, struct si_texture *tex);
 void si_update_fb_dirtiness_after_rendering(struct si_context *sctx);
 void si_mark_display_dcc_dirty(struct si_context *sctx, struct si_texture *tex);
 void si_update_ps_iter_samples(struct si_context *sctx);



More information about the mesa-commit mailing list