summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Justen <jordan.l.justen@intel.com>2013-10-09 16:58:23 -0700
committerJordan Justen <jordan.l.justen@intel.com>2014-01-09 22:59:28 -0800
commitdd0d899c13be609b64d98d951cfdec9f01aef9b1 (patch)
tree602e44fb344f8c4f8ac005d38b2bc371decccdef
parent752f40c3b71e09d40eb78bb3c18ba954f4945254 (diff)
i965 clear: enable using hiz fast clears with GL scissorspartial-fast-depth-clear
If GL Scissors were in use, when we would unconditionally disable hiz fast depth clears. Now, we will use hiz fast depth clears for as much of the clear operation as possible based on the scissor definition along with the hiz operation alignment requirements. If hiz operation alignment requirements leave part of the depth buffer uncleared, then we use _mesa_meta_glsl_Clear_except to clear the remainder of the depth buffer. Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_clear.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
index 3de94e3d87..d5e9c89628 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -117,15 +117,29 @@ brw_fast_clear_depth(struct gl_context *ctx)
if (!intel_renderbuffer_has_hiz(depth_irb))
return false;
- /* We only handle full buffer clears -- otherwise you'd have to track whether
- * a previous clear had happened at a different clear value and resolve it
- * first.
+ bool scissors_used = !noop_scissor(fb);
+
+ unsigned int align_x, align_y;
+ get_intel_hiz_alignment(&align_x, &align_y);
+
+ int hiz_x = ALIGN(fb->_Xmin, align_x), hiz_y = ALIGN(fb->_Ymin, align_y);
+ int hiz_w = (fb->_Xmax - hiz_x) & ~(align_x - 1);
+ int hiz_h = (fb->_Ymax - hiz_y) & ~(align_y - 1);
+
+ bool extra_scissor_clear_needed =
+ scissors_used &&
+ (hiz_x != fb->_Xmin || hiz_y != fb->_Ymin ||
+ (hiz_x + hiz_w) != fb->_Xmax || (hiz_y + hiz_h) != fb->_Ymax);
+
+ /* ES1 can't use _mesa_meta_glsl_Clear_except. We'd need a non GLSL
+ * version to support ES1.
*/
- if (ctx->Scissor.Enabled && !noop_scissor(fb)) {
- perf_debug("Failed to fast clear depth due to scissor being enabled. "
- "Possible 5%% performance win if avoided.\n");
+ if (extra_scissor_clear_needed && ctx->API == API_OPENGLES)
+ return false;
+
+ /* The scissors have prevented a hiz clear from being usable */
+ if (hiz_w <= 0 || hiz_h <= 0)
return false;
- }
uint32_t depth_clear_value;
switch (mt->format) {
@@ -181,15 +195,30 @@ brw_fast_clear_depth(struct gl_context *ctx)
*/
intel_batchbuffer_emit_mi_flush(brw);
+ unsigned start_layer, end_layer;
+
if (fb->NumLayers > 0) {
assert(fb->NumLayers == depth_irb->mt->level[depth_irb->mt_level].depth);
- for (unsigned layer = 0; layer < fb->NumLayers; layer++) {
- intel_hiz_exec(brw, mt, depth_irb->mt_level, layer,
- GEN6_HIZ_OP_DEPTH_CLEAR);
- }
+ start_layer = 0;
+ end_layer = fb->NumLayers;
} else {
- intel_hiz_exec(brw, mt, depth_irb->mt_level, depth_irb->mt_layer,
- GEN6_HIZ_OP_DEPTH_CLEAR);
+ start_layer = depth_irb->mt_layer;
+ end_layer = start_layer + 1;
+ }
+
+ for (unsigned layer = start_layer; layer < end_layer; layer++) {
+ if (scissors_used)
+ intel_hiz_range_exec(brw, mt, depth_irb->mt_level, depth_irb->mt_layer,
+ hiz_x, hiz_y, hiz_w, hiz_h,
+ GEN6_HIZ_OP_DEPTH_CLEAR);
+ else
+ /* When scissors are not used, we call intel_hiz_exec, because it
+ * can clear non-aligned depth buffers. It does this by clearing
+ * a slightly larger region, but this is safe due to padding/alignment
+ * in the surface data structure.
+ */
+ intel_hiz_exec(brw, mt, depth_irb->mt_level, depth_irb->mt_layer,
+ GEN6_HIZ_OP_DEPTH_CLEAR);
}
if (brw->gen == 6) {
@@ -207,6 +236,13 @@ brw_fast_clear_depth(struct gl_context *ctx)
*/
intel_renderbuffer_att_set_needs_depth_resolve(depth_att);
+ if (extra_scissor_clear_needed) {
+ perf_debug("Falling back to slower clear for unaligned scissor regions\n"
+ "Optimal scissor alignments: x/width=%d, y/height=%d\n",
+ align_x, align_y);
+ _mesa_meta_glsl_Clear_except(ctx, BUFFER_BIT_DEPTH, hiz_x, hiz_y, hiz_w, hiz_h);
+ }
+
return true;
}