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