[Mesa-dev] [PATCH 09/14] i965: Allow failure when setting the depth clear value
Nanley Chery
nanleychery at gmail.com
Fri Mar 30 18:12:22 UTC 2018
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
More information about the mesa-dev
mailing list