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