i965/clear: Don't perform redundant depth clears
authorJason Ekstrand <jason@jlekstrand.net>
Thu, 15 Jun 2017 01:54:29 +0000 (18:54 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 26 Jul 2017 21:43:01 +0000 (14:43 -0700)
We already have this little optimization for color clears.  Now that
we're actually tracking whether or not a slice has any fast-clear
blocks, it's easy enough to add for depth clears too.

Improves performance of GFXBench 4 TRex at 1920x1080 by:
- Skylake GT4: 0.905932% +/- 0.0620197% (n = 30)
- Apollolake:  0.382434% +/- 0.1134730% (n = 25)

v2: (by Ken) Rebase and drop intel_mipmap_tree.c changes, as they're
    no longer necessary (other patches already landed to do that part)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_clear.c

index 0429b3b6f5130e0fbcdfeaf64cff7ff13dcb8047..5eb24237927cf6f261810a77377ccc2991e2942e 100644 (file)
@@ -204,9 +204,37 @@ brw_fast_clear_depth(struct gl_context *ctx)
       mt->fast_clear_color.f32[0] = ctx->Depth.Clear;
    }
 
-   intel_hiz_exec(brw, mt, depth_irb->mt_level,
-                  depth_irb->mt_layer, num_layers,
-                  BLORP_HIZ_OP_DEPTH_CLEAR);
+   bool need_clear = false;
+   for (unsigned a = 0; a < num_layers; a++) {
+      enum isl_aux_state aux_state =
+         intel_miptree_get_aux_state(mt, depth_irb->mt_level,
+                                     depth_irb->mt_layer + a);
+
+      if (aux_state != ISL_AUX_STATE_CLEAR) {
+         need_clear = true;
+         break;
+      }
+   }
+
+   if (!need_clear) {
+      /* If all of the layers we intend to clear are already in the clear
+       * state then simply updating the miptree fast clear value is sufficient
+       * to change their clear value.
+       */
+      return true;
+   }
+
+   for (unsigned a = 0; a < num_layers; a++) {
+      enum isl_aux_state aux_state =
+         intel_miptree_get_aux_state(mt, depth_irb->mt_level,
+                                     depth_irb->mt_layer + a);
+
+      if (aux_state != ISL_AUX_STATE_CLEAR) {
+         intel_hiz_exec(brw, mt, depth_irb->mt_level,
+                        depth_irb->mt_layer + a, 1,
+                        BLORP_HIZ_OP_DEPTH_CLEAR);
+      }
+   }
 
    /* Now, the HiZ buffer contains data that needs to be resolved to the depth
     * buffer.