X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_clear.c;h=30e09861491e90b3b66d6cf557f189d805d1c97f;hb=030b6efcfdeff5cc079d5b6d8e682e180570ce71;hp=7fbaa3a47d471fa28cf1768e7fc9515a82257849;hpb=b08981009d9bf127436be84aadb2e88b889e56c0;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c index 7fbaa3a47d4..30e09861491 100644 --- a/src/mesa/drivers/dri/i965/brw_clear.c +++ b/src/mesa/drivers/dri/i965/brw_clear.c @@ -30,7 +30,6 @@ #include "drivers/common/meta.h" #include "intel_batchbuffer.h" -#include "intel_blit.h" #include "intel_fbo.h" #include "intel_mipmap_tree.h" @@ -107,8 +106,9 @@ brw_fast_clear_depth(struct gl_context *ctx) 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 (devinfo->gen < 6) return false; if (!intel_renderbuffer_has_hiz(depth_irb)) @@ -121,7 +121,8 @@ brw_fast_clear_depth(struct gl_context *ctx) if ((ctx->Scissor.EnableFlags & 1) && !noop_scissor(fb)) { perf_debug("Failed to fast clear %dx%d depth because of scissors. " "Possible 5%% performance win if avoided.\n", - mt->logical_width0, mt->logical_height0); + mt->surf.logical_level0_px.width, + mt->surf.logical_level0_px.height); return false; } @@ -148,8 +149,8 @@ brw_fast_clear_depth(struct gl_context *ctx) * width of the map (LOD0) is not multiple of 16, fast clear * optimization must be disabled. */ - if (brw->gen == 6 && - (minify(mt->physical_width0, + if (devinfo->gen == 6 && + (minify(mt->surf.phys_level0_sa.width, depth_irb->mt_level - mt->first_level) % 16) != 0) return false; break; @@ -158,37 +159,77 @@ brw_fast_clear_depth(struct gl_context *ctx) 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 : + (unsigned)(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) { - intel_miptree_prepare_access(brw, mt, 0, INTEL_REMAINING_LEVELS, - 0, INTEL_REMAINING_LAYERS, true, false); - 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; + + const unsigned level_layers = brw_get_num_logical_layers(mt, level); + + for (uint32_t layer = 0; layer < level_layers; layer++) { + if (level == depth_irb->mt_level && + layer >= depth_irb->mt_layer && + layer < depth_irb->mt_layer + num_layers) { + /* We're going to clear this layer anyway. Leave it alone. */ + continue; + } + + enum isl_aux_state aux_state = + intel_miptree_get_aux_state(mt, level, layer); + + if (aux_state != ISL_AUX_STATE_CLEAR && + aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) { + /* This slice doesn't have any fast-cleared bits. */ + continue; + } + + /* If we got here, then the level may have fast-clear bits that + * use the old clear value. We need to do a depth resolve to get + * rid of their use of the clear value before we can change it. + * Fortunately, few applications ever change their depth clear + * value so this shouldn't happen often. + */ + intel_hiz_exec(brw, mt, level, layer, 1, + ISL_AUX_OP_FULL_RESOLVE); + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_RESOLVED); + } + } - if (depth_att->Layered) { - intel_hiz_exec(brw, mt, depth_irb->mt_level, - depth_irb->mt_layer, depth_irb->layer_count, - BLORP_HIZ_OP_DEPTH_CLEAR); - } else { - intel_hiz_exec(brw, mt, depth_irb->mt_level, depth_irb->mt_layer, 1, - BLORP_HIZ_OP_DEPTH_CLEAR); + const union isl_color_value clear_color = { .f32 = {clear_value, } }; + intel_miptree_set_clear_color(brw, mt, clear_color); } - /* Now, the HiZ buffer contains data that needs to be resolved to the depth - * buffer. - */ - if (depth_att->Layered) { - intel_miptree_set_aux_state(brw, mt, depth_irb->mt_level, - depth_irb->mt_layer, depth_irb->layer_count, - ISL_AUX_STATE_CLEAR); - } else { - intel_miptree_set_aux_state(brw, mt, depth_irb->mt_level, - depth_irb->mt_layer, 1, - ISL_AUX_STATE_CLEAR); + 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) { + intel_hiz_exec(brw, mt, depth_irb->mt_level, + depth_irb->mt_layer + a, 1, + ISL_AUX_OP_FAST_CLEAR); + } } + intel_miptree_set_aux_state(brw, mt, depth_irb->mt_level, + depth_irb->mt_layer, num_layers, + ISL_AUX_STATE_CLEAR); return true; } @@ -200,6 +241,7 @@ brw_clear(struct gl_context *ctx, GLbitfield mask) { 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)) @@ -219,14 +261,6 @@ brw_clear(struct gl_context *ctx, GLbitfield mask) } } - 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); @@ -234,7 +268,7 @@ brw_clear(struct gl_context *ctx, GLbitfield mask) 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;