#include "drivers/common/meta.h"
#include "intel_batchbuffer.h"
-#include "intel_blit.h"
#include "intel_fbo.h"
#include "intel_mipmap_tree.h"
intel_get_renderbuffer(fb, BUFFER_DEPTH);
struct intel_mipmap_tree *mt = depth_irb->mt;
struct gl_renderbuffer_attachment *depth_att = &fb->Attachment[BUFFER_DEPTH];
+ const struct gen_device_info *devinfo = &brw->screen->devinfo;
- if (brw->gen < 6)
+ if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
+ return false;
+
+ if (devinfo->gen < 6)
return false;
if (!intel_renderbuffer_has_hiz(depth_irb))
* width of the map (LOD0) is not multiple of 16, fast clear
* optimization must be disabled.
*/
- if (brw->gen == 6 &&
+ if (devinfo->gen == 6 &&
(minify(mt->surf.phys_level0_sa.width,
depth_irb->mt_level - mt->first_level) % 16) != 0)
return false;
break;
}
+ /* Quantize the clear value to what can be stored in the actual depth
+ * buffer. This makes the following check more accurate because it now
+ * checks if the actual depth bits will match. It also prevents us from
+ * getting a too-accurate depth value during depth testing or when sampling
+ * with HiZ enabled.
+ */
+ float clear_value =
+ mt->format == MESA_FORMAT_Z_FLOAT32 ? ctx->Depth.Clear :
+ _mesa_lroundeven(ctx->Depth.Clear * fb->_DepthMax) / (float)(fb->_DepthMax);
+
const uint32_t num_layers = depth_att->Layered ? depth_irb->layer_count : 1;
/* If we're clearing to a new clear value, then we need to resolve any clear
* flags out of the HiZ buffer into the real depth buffer.
*/
- if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) {
+ if (mt->fast_clear_color.f32[0] != clear_value) {
for (uint32_t level = mt->first_level; level <= mt->last_level; level++) {
if (!intel_miptree_level_has_hiz(mt, level))
continue;
* value so this shouldn't happen often.
*/
intel_hiz_exec(brw, mt, level, layer, 1,
- BLORP_HIZ_OP_DEPTH_RESOLVE);
+ ISL_AUX_OP_FULL_RESOLVE);
intel_miptree_set_aux_state(brw, mt, level, layer, 1,
ISL_AUX_STATE_RESOLVED);
}
}
- mt->fast_clear_color.f32[0] = ctx->Depth.Clear;
- }
-
- bool need_clear = false;
- for (unsigned a = 0; a < num_layers; a++) {
- enum isl_aux_state aux_state =
- intel_miptree_get_aux_state(mt, depth_irb->mt_level,
- depth_irb->mt_layer + a);
-
- if (aux_state != ISL_AUX_STATE_CLEAR) {
- need_clear = true;
- break;
- }
- }
-
- if (!need_clear) {
- /* If all of the layers we intend to clear are already in the clear
- * state then simply updating the miptree fast clear value is sufficient
- * to change their clear value.
- */
- return true;
+ const union isl_color_value clear_color = { .f32 = {clear_value, } };
+ intel_miptree_set_clear_color(brw, mt, clear_color);
}
for (unsigned a = 0; a < num_layers; a++) {
if (aux_state != ISL_AUX_STATE_CLEAR) {
intel_hiz_exec(brw, mt, depth_irb->mt_level,
depth_irb->mt_layer + a, 1,
- BLORP_HIZ_OP_DEPTH_CLEAR);
+ ISL_AUX_OP_FAST_CLEAR);
}
}
- /* Now, the HiZ buffer contains data that needs to be resolved to the depth
- * buffer.
- */
intel_miptree_set_aux_state(brw, mt, depth_irb->mt_level,
depth_irb->mt_layer, num_layers,
ISL_AUX_STATE_CLEAR);
-
return true;
}
{
struct brw_context *brw = brw_context(ctx);
struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const struct gen_device_info *devinfo = &brw->screen->devinfo;
bool partial_clear = ctx->Scissor.EnableFlags && !noop_scissor(fb);
if (!_mesa_check_conditional_render(ctx))
}
}
- if (mask & BUFFER_BIT_STENCIL) {
- struct intel_renderbuffer *stencil_irb =
- intel_get_renderbuffer(fb, BUFFER_STENCIL);
- struct intel_mipmap_tree *mt = stencil_irb->mt;
- if (mt && mt->stencil_mt)
- mt->stencil_mt->r8stencil_needs_update = true;
- }
-
if (mask & BUFFER_BITS_COLOR) {
brw_blorp_clear_color(brw, fb, mask, partial_clear,
ctx->Color.sRGBEnabled);
mask &= ~BUFFER_BITS_COLOR;
}
- if (brw->gen >= 6 && (mask & BUFFER_BITS_DEPTH_STENCIL)) {
+ if (devinfo->gen >= 6 && (mask & BUFFER_BITS_DEPTH_STENCIL)) {
brw_blorp_clear_depth_stencil(brw, fb, mask, partial_clear);
debug_mask("blorp depth/stencil", mask & BUFFER_BITS_DEPTH_STENCIL);
mask &= ~BUFFER_BITS_DEPTH_STENCIL;