diff --git a/.pick_status.json b/.pick_status.json index 8ca5dc1e15e..fa0069b1d57 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 }, diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index eda8845282f..e5e3639d493 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -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); }