mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 05:28:05 +02:00
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 573d645133)
This commit is contained in:
parent
e5c982b332
commit
41f9866120
4 changed files with 27 additions and 3 deletions
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue