radeonsi: emit framebuffer state after allocating cmask

tex->cmask_base_address_reg and tex->cb_color_info are used in
si_emit_framebuffer_state so we have to re-emit the state when
they're modified.

It's not done in si_alloc_separate_cmask because it cannot
update framebuffer.dirty_cbufs.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9830
Cc: mesa-stable
Reviewed-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25317>
(cherry picked from commit 60a7c9688c)
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2023-09-21 09:42:53 +02:00 committed by Eric Engestrom
parent 3c439d3b95
commit df00f802d8
2 changed files with 11 additions and 2 deletions

View file

@ -1687,7 +1687,7 @@
"description": "radeonsi: emit framebuffer state after allocating cmask",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -122,6 +122,9 @@ static bool si_alloc_separate_cmask(struct si_screen *sscreen, struct si_texture
if (tex->cmask_buffer == NULL)
return false;
/* These 2 fields are part of the framebuffer state but dirtying the atom
* will be done by the caller.
*/
tex->cmask_base_address_reg = tex->cmask_buffer->gpu_address >> 8;
tex->cb_color_info |= S_028C70_FAST_CLEAR(1);
@ -723,6 +726,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
bool too_small = tex->buffer.b.b.nr_samples <= 1 && fb_too_small;
bool eliminate_needed = false;
bool fmask_decompress_needed = false;
bool need_dirtying_fb = false;
/* Try to clear DCC first, otherwise try CMASK. */
if (vi_dcc_enabled(tex, level)) {
@ -819,6 +823,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
uint64_t cmask_offset = 0;
unsigned clear_size = 0;
bool had_cmask_buffer = tex->cmask_buffer != NULL;
if (sctx->gfx_level >= GFX10) {
assert(level == 0);
@ -871,6 +876,10 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
cmask_offset, clear_size, 0);
clear_types |= SI_CLEAR_TYPE_CMASK;
eliminate_needed = true;
/* If we allocated a cmask buffer for this tex we need to re-emit
* the fb state.
*/
need_dirtying_fb = !had_cmask_buffer;
}
if ((eliminate_needed || fmask_decompress_needed) &&
@ -892,7 +901,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
/* There are no clear color registers on GFX11. */
assert(sctx->gfx_level < GFX11);
if (si_set_clear_color(tex, fb->cbufs[i]->format, color)) {
if (si_set_clear_color(tex, fb->cbufs[i]->format, color) || need_dirtying_fb) {
sctx->framebuffer.dirty_cbufs |= 1 << i;
si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
}