radeonsi: enable DCC fast clears for non-zero mipmap levels and 0/1 clear values
authorMarek Olšák <marek.olsak@amd.com>
Sun, 21 Mar 2021 16:01:04 +0000 (12:01 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 13 Apr 2021 03:17:42 +0000 (03:17 +0000)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10003>

src/gallium/drivers/radeonsi/si_clear.c

index 59da19c..fdf2772 100644 (file)
@@ -535,11 +535,8 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
    while (color_buffer_mask) {
       unsigned i = u_bit_scan(&color_buffer_mask);
 
-      unsigned level = fb->cbufs[i]->u.tex.level;
-      if (level > 0)
-         continue;
-
       struct si_texture *tex = (struct si_texture *)fb->cbufs[i]->texture;
+      unsigned level = fb->cbufs[i]->u.tex.level;
       unsigned num_layers = util_num_layers(&tex->buffer.b.b, level);
 
       /* the clear is allowed if all layers are bound */
@@ -598,7 +595,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
       }
 
       /* Try to clear DCC first, otherwise try CMASK. */
-      if (vi_dcc_enabled(tex, 0)) {
+      if (vi_dcc_enabled(tex, level)) {
          uint32_t reset_value;
 
          if (sctx->screen->debug_flags & DBG(NO_DCC_CLEAR))
@@ -623,13 +620,20 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
          if (eliminate_needed && too_small)
             continue;
 
+         /* We can clear any level, but we only set up the clear value registers for the first
+          * level. Therefore, all other levels can be cleared only if the clear value registers
+          * are not used, which is only the case with DCC constant encoding and 0/1 clear values.
+          */
+         if (level > 0 && (eliminate_needed || !sctx->screen->info.has_dcc_constant_encode))
+            continue;
+
          /* TODO: This DCC+CMASK clear doesn't work with MSAA. */
          if (tex->buffer.b.b.nr_samples >= 2 && tex->cmask_buffer && eliminate_needed)
             continue;
 
          assert(num_clears < ARRAY_SIZE(info));
 
-         if (!vi_dcc_get_clear_info(sctx, tex, 0, reset_value, &info[num_clears]))
+         if (!vi_dcc_get_clear_info(sctx, tex, level, reset_value, &info[num_clears]))
             continue;
 
          num_clears++;
@@ -647,6 +651,9 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
             fmask_decompress_needed = true;
          }
       } else {
+         if (level > 0)
+            continue;
+
          /* Shared textures can't use fast clear without an explicit flush
           * because the clear color is not exported.
           */