diff options
author | Jordan Justen <jordan.l.justen@intel.com> | 2013-10-09 16:58:23 -0700 |
---|---|---|
committer | Jordan Justen <jordan.l.justen@intel.com> | 2014-01-09 22:59:28 -0800 |
commit | dd0d899c13be609b64d98d951cfdec9f01aef9b1 (patch) | |
tree | 602e44fb344f8c4f8ac005d38b2bc371decccdef | |
parent | 752f40c3b71e09d40eb78bb3c18ba954f4945254 (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.c | 62 |
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; } |