We'd like for the caller to use the miptree clear color helper
functions. Unfortunately, to fast-clear depth with good performance, you
have to know if the current clear color differs from the pending one.
Adjust the setter to reject a clear color if doing so would hurt
performance by introducing resolves.

Only update the function here to help bisection and review.
---
 src/mesa/drivers/dri/i965/brw_clear.c         |  6 +++-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 47 ++++++++++++++++++++++++---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |  8 ++++-
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_clear.c 
b/src/mesa/drivers/dri/i965/brw_clear.c
index 8f7594baf59..3b5f6122439 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -212,7 +212,11 @@ brw_fast_clear_depth(struct gl_context *ctx)
          }
       }
 
-      intel_miptree_set_depth_clear_value(brw, mt, clear_value);
+      MAYBE_UNUSED bool new_clear =
+         intel_miptree_set_depth_clear_value(brw, mt, depth_irb->mt_level,
+                                             depth_irb->mt_layer, num_layers,
+                                             false, clear_value);
+      assert(new_clear);
    }
 
    bool need_clear = false;
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c 
b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index dec2e614938..bbf09153be7 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -3794,14 +3794,53 @@ intel_miptree_set_clear_color(struct brw_context *brw,
 bool
 intel_miptree_set_depth_clear_value(struct brw_context *brw,
                                     struct intel_mipmap_tree *mt,
-                                    float clear_value)
-{
+                                    uint32_t level,
+                                    uint32_t start_layer, uint32_t num_layers,
+                                    bool partial_clear, float clear_value)
+{
+   /* To avoid resolves when fast-clearing, we allow a miptree range to be set
+    * with a clear value if the following statements hold true:
+    *    1. The clear value is valid.
+    *    2. If the clear value is different from the current value, then:
+    *       a) the full RT of each slice in the desired range will be cleared.
+    *       b) the desired range includes pre-existing clear blocks.
+    */
    if (mt->fast_clear_color.f32[0] != clear_value) {
+      if (partial_clear)
+         return false;
+
+      /* The desired range is problematic if it isn't a superset of the range
+       * of the miptree which already contains clear blocks. Try to find a
+       * slice outside the desired range which contains clear blocks, and won't
+       * be cleared at this time.
+       */
+      for (unsigned mlev = mt->first_level; mlev <= mt->last_level; mlev++) {
+         if (!intel_miptree_level_has_hiz(mt, mlev))
+            continue;
+
+         const unsigned level_layers = brw_get_num_logical_layers(mt, mlev);
+
+         for (unsigned layer = 0; layer < level_layers; layer++) {
+            const enum isl_aux_state aux_state =
+               intel_miptree_get_aux_state(mt, mlev, layer);
+            const bool contains_cleared_blocks =
+               aux_state == ISL_AUX_STATE_CLEAR ||
+               aux_state == ISL_AUX_STATE_COMPRESSED_CLEAR;
+            const bool wont_be_cleared =
+               mlev != level ||
+               layer < start_layer ||
+               layer >= start_layer + num_layers;
+
+            if (contains_cleared_blocks && wont_be_cleared)
+               return false;
+         }
+      }
+
       mt->fast_clear_color.f32[0] = clear_value;
       brw->ctx.NewDriverState |= BRW_NEW_AUX_STATE;
-      return true;
    }
-   return false;
+
+   return true;
 }
 
 union isl_color_value
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h 
b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index edf9a619218..4915198ce1c 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -727,10 +727,16 @@ intel_miptree_get_clear_color(const struct 
gen_device_info *devinfo,
                               enum isl_format view_format,
                               bool sampling);
 
+/* Try to mark a range of slices in the miptree as having a given clear value.
+ * Upon success, the caller must ensure that the range's aux bits will
+ * represent the clear value. This may involve performing a fast-clear.
+ */
 bool
 intel_miptree_set_depth_clear_value(struct brw_context *brw,
                                     struct intel_mipmap_tree *mt,
-                                    float clear_value);
+                                    uint32_t level,
+                                    uint32_t start_layer, uint32_t num_layers,
+                                    bool partial_clear, float clear_value);
 
 /* Get a clear value suitable for filling out an ISL depth state. */
 uint32_t
-- 
2.16.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to