Mesa (staging/21.3): radeonsi: fix fast clear / depth decompression corruption
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Dec 17 19:44:18 UTC 2021
Module: Mesa
Branch: staging/21.3
Commit: e71b82818af9e5c9a46b296f26ca2897aa491252
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e71b82818af9e5c9a46b296f26ca2897aa491252
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date: Thu Dec 2 11:56:41 2021 +0100
radeonsi: fix fast clear / depth decompression corruption
Insert a flush after a depth decompression pass if the texture
was fast cleared.
This fixes a corruption which seems to only affect gfx10.3 chips.
Ideally we should also clear tex->need_flush_after_depth_decompression
after a flush but there's no easy way for this so this commit will
introduce extra flushes.
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14089>
(cherry picked from commit 573d6451335a0b3c947aa2823619e31017d0362c)
---
.pick_status.json | 2 +-
src/gallium/drivers/radeonsi/si_blit.c | 23 +++++++++++++++++++++--
src/gallium/drivers/radeonsi/si_clear.c | 4 ++++
src/gallium/drivers/radeonsi/si_pipe.h | 1 +
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/.pick_status.json b/.pick_status.json
index b9dcf9126b4..9ef1aae6133 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1588,7 +1588,7 @@
"description": "radeonsi: fix fast clear / depth decompression corruption",
"nominated": true,
"nomination_type": 0,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": null
},
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index bf5ccb1cc9a..5653ff233ab 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -395,11 +395,12 @@ static void si_decompress_depth(struct si_context *sctx, struct si_texture *tex,
si_make_CB_shader_coherent(sctx, tex->buffer.b.b.nr_samples, false, true /* no DCC */);
}
-static void si_decompress_sampler_depth_textures(struct si_context *sctx,
+static bool si_decompress_sampler_depth_textures(struct si_context *sctx,
struct si_samplers *textures)
{
unsigned i;
unsigned mask = textures->needs_depth_decompress_mask;
+ bool need_flush = false;
while (mask) {
struct pipe_sampler_view *view;
@@ -418,7 +419,14 @@ static void si_decompress_sampler_depth_textures(struct si_context *sctx,
si_decompress_depth(sctx, tex, sview->is_stencil_sampler ? PIPE_MASK_S : PIPE_MASK_Z,
view->u.tex.first_level, view->u.tex.last_level, 0,
util_max_layer(&tex->buffer.b.b, view->u.tex.first_level));
+
+ if (tex->need_flush_after_depth_decompression) {
+ need_flush = true;
+ tex->need_flush_after_depth_decompression = false;
+ }
}
+
+ return need_flush;
}
static void si_blit_decompress_color(struct si_context *sctx, struct si_texture *tex,
@@ -757,6 +765,7 @@ static void si_decompress_resident_images(struct si_context *sctx)
void si_decompress_textures(struct si_context *sctx, unsigned shader_mask)
{
unsigned compressed_colortex_counter, mask;
+ bool need_flush = false;
if (sctx->blitter_running)
return;
@@ -774,7 +783,7 @@ void si_decompress_textures(struct si_context *sctx, unsigned shader_mask)
unsigned i = u_bit_scan(&mask);
if (sctx->samplers[i].needs_depth_decompress_mask) {
- si_decompress_sampler_depth_textures(sctx, &sctx->samplers[i]);
+ need_flush |= si_decompress_sampler_depth_textures(sctx, &sctx->samplers[i]);
}
if (sctx->samplers[i].needs_color_decompress_mask) {
si_decompress_sampler_color_textures(sctx, &sctx->samplers[i]);
@@ -784,6 +793,16 @@ void si_decompress_textures(struct si_context *sctx, unsigned shader_mask)
}
}
+ if (sctx->chip_class == GFX10_3 && need_flush) {
+ /* This fixes a corruption with the following sequence:
+ * - fast clear depth
+ * - decompress depth
+ * - draw
+ * (see https://gitlab.freedesktop.org/drm/amd/-/issues/1810#note_1170171)
+ */
+ sctx->b.flush(&sctx->b, NULL, RADEON_FLUSH_ASYNC_START_NEXT_GFX_IB_NOW);
+ }
+
if (shader_mask & u_bit_consecutive(0, SI_NUM_GRAPHICS_SHADERS)) {
if (sctx->uses_bindless_samplers)
si_decompress_resident_textures(sctx);
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index aa73131bb24..63ff2c893c2 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -829,6 +829,8 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
clear_value = !zstex->htile_stencil_disabled ? 0xfffff30f : 0xfffc000f;
}
+ zstex->need_flush_after_depth_decompression = sctx->chip_class == GFX10_3;
+
assert(num_clears < ARRAY_SIZE(info));
si_init_buffer_clear(&info[num_clears++], &zstex->buffer.b.b,
zstex->surface.meta_offset, zstex->surface.meta_size, clear_value);
@@ -934,6 +936,8 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
}
}
+ zstex->need_flush_after_depth_decompression = update_db_depth_clear && sctx->chip_class == GFX10_3;
+
/* Update DB_DEPTH_CLEAR. */
if (update_db_depth_clear &&
zstex->depth_clear_value[level] != (float)depth) {
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index d9a6abec609..2408346c31b 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -374,6 +374,7 @@ struct si_texture {
bool db_compatible : 1;
bool can_sample_z : 1;
bool can_sample_s : 1;
+ bool need_flush_after_depth_decompression: 1;
/* We need to track DCC dirtiness, because st/dri usually calls
* flush_resource twice per frame (not a bug) and we don't wanna
More information about the mesa-commit
mailing list