radeonsi: emit framebuffer state after allocating cmask
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Thu, 21 Sep 2023 07:42:53 +0000 (09:42 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 21 Sep 2023 16:12:06 +0000 (16:12 +0000)
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>

src/gallium/drivers/radeonsi/si_clear.c

index c6051a3..4ad97bc 100644 (file)
@@ -108,6 +108,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);
 
@@ -709,6 +712,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)) {
@@ -805,6 +809,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);
@@ -857,6 +862,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) &&
@@ -877,7 +886,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);
       }