From: Jason Ekstrand Date: Sat, 20 May 2017 22:00:42 +0000 (-0700) Subject: i965/miptree: Store fast clear colors in an isl_color_value X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f9fd976e8adba733b08dacd597e09a513503c116;p=mesa.git i965/miptree: Store fast clear colors in an isl_color_value This commit, out of necessity, makes a number of changes at once: 1) Changes intel_mipmap_tree to store the clear color for both color and depth as an isl_color_value. 2) Changes the depth/stencil emit code to do the format conversion of the depth clear value on Haswell and earlier instead of pulling a uint32_t directly from the miptree. 3) Changes ISL's depth/stencil emit code to perform the format conversion of the depth clear value on Haswell and earlier instead of assuming that the depth value in the float is pre-converted. 4) Changes blorp to pass the depth value through as a float. 5) Changes the Vulkan driver to pass the depth value to blorp as a float rather than a uint. Reviewed-by: Topi Pohjolainen Reviewed-by: Kenneth Graunke Reviewed-by: Chad Versace --- diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h index 59c1d364947..a354cea117a 100644 --- a/src/intel/blorp/blorp_genX_exec.h +++ b/src/intel/blorp/blorp_genX_exec.h @@ -1402,7 +1402,7 @@ blorp_emit_depth_stencil_config(struct blorp_batch *batch, blorp_emit_reloc(batch, dw + isl_dev->ds.hiz_offset / 4, hiz_address, 0); - info.depth_clear_value = params->depth.clear_color.u32[0]; + info.depth_clear_value = params->depth.clear_color.f32[0]; } } diff --git a/src/intel/isl/isl_emit_depth_stencil.c b/src/intel/isl/isl_emit_depth_stencil.c index 41a01be6f16..339da28bb84 100644 --- a/src/intel/isl/isl_emit_depth_stencil.c +++ b/src/intel/isl/isl_emit_depth_stencil.c @@ -177,7 +177,26 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch, #endif clear.DepthClearValueValid = true; +#if GEN_GEN >= 8 clear.DepthClearValue = info->depth_clear_value; +#else + switch (info->depth_surf->format) { + case ISL_FORMAT_R32_FLOAT: { + union { float f; uint32_t u; } fu; + fu.f = info->depth_clear_value; + clear.DepthClearValue = fu.u; + break; + } + case ISL_FORMAT_R24_UNORM_X8_TYPELESS: + clear.DepthClearValue = info->depth_clear_value * ((1u << 24) - 1); + break; + case ISL_FORMAT_R16_UNORM: + clear.DepthClearValue = info->depth_clear_value * ((1u << 16) - 1); + break; + default: + unreachable("Invalid depth type"); + } +#endif } #endif /* GEN_GEN >= 6 */ diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 45cbbb86900..3ba65d40c52 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -1721,7 +1721,7 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, }; surf.aux_usage = ISL_AUX_USAGE_HIZ; - surf.clear_color.u32[0] = (uint32_t) ANV_HZ_FC_VAL; + surf.clear_color.f32[0] = ANV_HZ_FC_VAL; blorp_gen6_hiz_op(&batch, &surf, 0, 0, op); blorp_batch_finish(&batch); diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index 28be6204293..5ea6b0cb1ea 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -193,7 +193,7 @@ blorp_surf_for_miptree(struct brw_context *brw, /* We only really need a clear color if we also have an auxiliary * surface. Without one, it does nothing. */ - surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt); + surf->clear_color = mt->fast_clear_color; surf->aux_surf = aux_surf; surf->aux_addr = (struct blorp_address) { @@ -790,24 +790,20 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, can_fast_clear = false; if (can_fast_clear) { - union gl_color_union override_color = + union isl_color_value clear_color = brw_meta_convert_fast_clear_color(brw, irb->mt, &ctx->Color.ClearColor); - /* Record the clear color in the miptree so that it will be - * programmed in SURFACE_STATE by later rendering and resolve - * operations. - */ - const bool color_updated = brw_meta_set_fast_clear_color( - brw, &irb->mt->gen9_fast_clear_color, - &override_color); - /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear * is redundant and can be skipped. */ - if (!color_updated && fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR) + if (fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR && + memcmp(&irb->mt->fast_clear_color, + &clear_color, sizeof(clear_color)) == 0) return true; + irb->mt->fast_clear_color = clear_color; + /* If the MCS buffer hasn't been allocated yet, we need to allocate * it now. */ diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c index 664342d452f..adaf250f746 100644 --- a/src/mesa/drivers/dri/i965/brw_clear.c +++ b/src/mesa/drivers/dri/i965/brw_clear.c @@ -125,7 +125,6 @@ brw_fast_clear_depth(struct gl_context *ctx) return false; } - uint32_t depth_clear_value; switch (mt->format) { case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: case MESA_FORMAT_Z24_UNORM_S8_UINT: @@ -139,10 +138,6 @@ brw_fast_clear_depth(struct gl_context *ctx) */ return false; - case MESA_FORMAT_Z_FLOAT32: - depth_clear_value = float_as_int(ctx->Depth.Clear); - break; - case MESA_FORMAT_Z_UNORM16: /* From the Sandy Bridge PRM, volume 2 part 1, page 314: * @@ -157,22 +152,18 @@ brw_fast_clear_depth(struct gl_context *ctx) (minify(mt->physical_width0, depth_irb->mt_level - mt->first_level) % 16) != 0) return false; - /* FALLTHROUGH */ + break; default: - if (brw->gen >= 8) - depth_clear_value = float_as_int(ctx->Depth.Clear); - else - depth_clear_value = fb->_DepthMax * ctx->Depth.Clear; break; } /* 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->depth_clear_value != depth_clear_value) { + if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) { intel_miptree_all_slices_resolve_depth(brw, mt); - mt->depth_clear_value = depth_clear_value; + mt->fast_clear_color.f32[0] = ctx->Depth.Clear; } if (brw->gen == 6) { diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c index cbc2dedde83..24160796bdf 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.c +++ b/src/mesa/drivers/dri/i965/brw_meta_util.c @@ -329,12 +329,19 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw, * Convert the given color to a bitfield suitable for ORing into DWORD 7 of * SURFACE_STATE (DWORD 12-15 on SKL+). */ -union gl_color_union +union isl_color_value brw_meta_convert_fast_clear_color(const struct brw_context *brw, const struct intel_mipmap_tree *mt, const union gl_color_union *color) { - union gl_color_union override_color = *color; + union isl_color_value override_color = { + .u32 = { + color->ui[0], + color->ui[1], + color->ui[2], + color->ui[3], + }, + }; /* The sampler doesn't look at the format of the surface when the fast * clear color is used so we need to implement luminance, intensity and @@ -342,65 +349,36 @@ brw_meta_convert_fast_clear_color(const struct brw_context *brw, */ switch (_mesa_get_format_base_format(mt->format)) { case GL_INTENSITY: - override_color.ui[3] = override_color.ui[0]; + override_color.u32[3] = override_color.u32[0]; /* flow through */ case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - override_color.ui[1] = override_color.ui[0]; - override_color.ui[2] = override_color.ui[0]; + override_color.u32[1] = override_color.u32[0]; + override_color.u32[2] = override_color.u32[0]; break; default: for (int i = 0; i < 3; i++) { if (!_mesa_format_has_color_component(mt->format, i)) - override_color.ui[i] = 0; + override_color.u32[i] = 0; } break; } if (!_mesa_format_has_color_component(mt->format, 3)) { if (_mesa_is_format_integer_color(mt->format)) - override_color.ui[3] = 1; + override_color.u32[3] = 1; else - override_color.f[3] = 1.0f; + override_color.f32[3] = 1.0f; } /* Handle linear to SRGB conversion */ if (brw->ctx.Color.sRGBEnabled && _mesa_get_srgb_format_linear(mt->format) != mt->format) { for (int i = 0; i < 3; i++) { - override_color.f[i] = - util_format_linear_to_srgb_float(override_color.f[i]); + override_color.f32[i] = + util_format_linear_to_srgb_float(override_color.f32[i]); } } return override_color; } - -/* Returned boolean tells if the given color differs from the current. */ -bool -brw_meta_set_fast_clear_color(struct brw_context *brw, - union gl_color_union *curr_color, - const union gl_color_union *new_color) -{ - bool updated; - - if (brw->gen >= 9) { - updated = memcmp(curr_color, new_color, sizeof(*curr_color)); - *curr_color = *new_color; - } else { - const uint32_t old_color_value = *(uint32_t *)curr_color; - uint32_t adjusted = 0; - - for (int i = 0; i < 4; i++) { - /* Testing for non-0 works for integer and float colors */ - if (new_color->f[i] != 0.0f) { - adjusted |= 1 << (GEN7_SURFACE_CLEAR_COLOR_SHIFT + (3 - i)); - } - } - - updated = (old_color_value != adjusted); - *(uint32_t *)curr_color = adjusted; - } - - return updated; -} diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.h b/src/mesa/drivers/dri/i965/brw_meta_util.h index 207a54b382b..4b3408df15a 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.h +++ b/src/mesa/drivers/dri/i965/brw_meta_util.h @@ -42,16 +42,11 @@ brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx, GLfloat *dstX1, GLfloat *dstY1, bool *mirror_x, bool *mirror_y); -union gl_color_union +union isl_color_value brw_meta_convert_fast_clear_color(const struct brw_context *brw, const struct intel_mipmap_tree *mt, const union gl_color_union *color); -bool -brw_meta_set_fast_clear_color(struct brw_context *brw, - union gl_color_union *curr_color, - const union gl_color_union *new_color); - bool brw_is_color_fast_clear_compatible(struct brw_context *brw, const struct intel_mipmap_tree *mt, diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index afa7e0861fa..79bdda9adf8 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -42,6 +42,7 @@ #include "main/framebuffer.h" #include "main/fbobject.h" +#include "main/format_utils.h" #include "main/glformats.h" /** @@ -523,6 +524,21 @@ brw_emit_depthbuffer(struct brw_context *brw) width, height, tile_x, tile_y); } +uint32_t +brw_convert_depth_value(mesa_format format, float value) +{ + switch (format) { + case MESA_FORMAT_Z_FLOAT32: + return float_as_int(value); + case MESA_FORMAT_Z_UNORM16: + return value * ((1u << 16) - 1); + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return value * ((1u << 24) - 1); + default: + unreachable("Invalid depth format"); + } +} + void brw_emit_depth_stencil_hiz(struct brw_context *brw, struct intel_mipmap_tree *depth_mt, @@ -656,7 +672,12 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw, OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | GEN5_DEPTH_CLEAR_VALID | (2 - 2)); - OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); + if (depth_mt) { + OUT_BATCH(brw_convert_depth_value(depth_mt->format, + depth_mt->fast_clear_color.f32[0])); + } else { + OUT_BATCH(0); + } ADVANCE_BATCH(); } } diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index cbfb8e775e4..08064fe577b 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -132,6 +132,9 @@ void brw_upload_invariant_state(struct brw_context *brw); uint32_t brw_depthbuffer_format(struct brw_context *brw); +uint32_t +brw_convert_depth_value(mesa_format format, float value); + void brw_upload_state_base_address(struct brw_context *brw); /* gen8_depth_state.c */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 3d54c141d0b..ae6b3d1db98 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -154,7 +154,7 @@ brw_emit_surface_state(struct brw_context *brw, /* We only really need a clear color if we also have an auxiliary * surface. Without one, it does nothing. */ - clear_color = intel_miptree_get_isl_clear_color(brw, mt); + clear_color = mt->fast_clear_color; } void *state = brw_state_batch(brw, diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c b/src/mesa/drivers/dri/i965/gen6_depth_state.c index a77e4616dc5..20992d53290 100644 --- a/src/mesa/drivers/dri/i965/gen6_depth_state.c +++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c @@ -234,6 +234,11 @@ gen6_emit_depth_stencil_hiz(struct brw_context *brw, OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | GEN5_DEPTH_CLEAR_VALID | (2 - 2)); - OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); + if (depth_mt) { + OUT_BATCH(brw_convert_depth_value(depth_mt->format, + depth_mt->fast_clear_color.f32[0])); + } else { + OUT_BATCH(0); + } ADVANCE_BATCH(); } diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c index af9be66ff8e..16b08ed8687 100644 --- a/src/mesa/drivers/dri/i965/gen7_misc_state.c +++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c @@ -192,7 +192,12 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw, BEGIN_BATCH(3); OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2)); - OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); + if (depth_mt) { + OUT_BATCH(brw_convert_depth_value(depth_mt->format, + depth_mt->fast_clear_color.f32[0])); + } else { + OUT_BATCH(0); + } OUT_BATCH(1); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i965/gen8_depth_state.c b/src/mesa/drivers/dri/i965/gen8_depth_state.c index 2a19b7961ae..0fafd7c7459 100644 --- a/src/mesa/drivers/dri/i965/gen8_depth_state.c +++ b/src/mesa/drivers/dri/i965/gen8_depth_state.c @@ -136,7 +136,7 @@ emit_depth_packets(struct brw_context *brw, BEGIN_BATCH(3); OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2)); - OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); + OUT_BATCH(depth_mt ? depth_mt->fast_clear_color.u32[0] : 0); OUT_BATCH(1); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 07e9ecf4f4f..9e9c1d08f01 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -3399,34 +3399,3 @@ intel_miptree_get_aux_isl_surf(struct brw_context *brw, surf->array_pitch_el_rows = aux_qpitch / isl_format_get_layout(surf->format)->bh; } - -union isl_color_value -intel_miptree_get_isl_clear_color(struct brw_context *brw, - const struct intel_mipmap_tree *mt) -{ - union isl_color_value clear_color; - - if (_mesa_get_format_base_format(mt->format) == GL_DEPTH_COMPONENT) { - clear_color.i32[0] = mt->depth_clear_value; - clear_color.i32[1] = 0; - clear_color.i32[2] = 0; - clear_color.i32[3] = 0; - } else if (brw->gen >= 9) { - clear_color.i32[0] = mt->gen9_fast_clear_color.i[0]; - clear_color.i32[1] = mt->gen9_fast_clear_color.i[1]; - clear_color.i32[2] = mt->gen9_fast_clear_color.i[2]; - clear_color.i32[3] = mt->gen9_fast_clear_color.i[3]; - } else if (_mesa_is_format_integer(mt->format)) { - clear_color.i32[0] = (mt->fast_clear_color_value & (1u << 31)) != 0; - clear_color.i32[1] = (mt->fast_clear_color_value & (1u << 30)) != 0; - clear_color.i32[2] = (mt->fast_clear_color_value & (1u << 29)) != 0; - clear_color.i32[3] = (mt->fast_clear_color_value & (1u << 28)) != 0; - } else { - clear_color.f32[0] = (mt->fast_clear_color_value & (1u << 31)) != 0; - clear_color.f32[1] = (mt->fast_clear_color_value & (1u << 30)) != 0; - clear_color.f32[2] = (mt->fast_clear_color_value & (1u << 29)) != 0; - clear_color.f32[3] = (mt->fast_clear_color_value & (1u << 28)) != 0; - } - - return clear_color; -} diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index 6096cabbdff..546d904b0be 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -551,15 +551,6 @@ struct intel_mipmap_tree GLuint total_width; GLuint total_height; - /** - * The depth value used during the most recent fast depth clear performed - * on the surface. This field is invalid only if surface has never - * underwent a fast depth clear. - * - * @see 3DSTATE_CLEAR_PARAMS.DepthClearValue - */ - uint32_t depth_clear_value; - /* Includes image offset tables: */ struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; @@ -645,25 +636,10 @@ struct intel_mipmap_tree struct intel_mipmap_tree *plane[2]; /** - * The SURFACE_STATE bits associated with the last fast color clear to this - * color mipmap tree, if any. - * - * Prior to GEN9 there is a single bit for RGBA clear values which gives you - * the option of 2^4 clear colors. Each bit determines if the color channel - * is fully saturated or unsaturated (Cherryview does add a 32b value per - * channel, but it is globally applied instead of being part of the render - * surface state). Starting with GEN9, the surface state accepts a 32b value - * for each color channel. - * - * @see RENDER_SURFACE_STATE.RedClearColor - * @see RENDER_SURFACE_STATE.GreenClearColor - * @see RENDER_SURFACE_STATE.BlueClearColor - * @see RENDER_SURFACE_STATE.AlphaClearColor + * Fast clear color for this surface. For depth surfaces, the clear value + * is stored as a float32 in the red component. */ - union { - uint32_t fast_clear_color_value; - union gl_color_union gen9_fast_clear_color; - }; + union isl_color_value fast_clear_color; /** * Disable allocation of auxiliary buffers, such as the HiZ buffer and MCS @@ -819,10 +795,6 @@ intel_miptree_get_aux_isl_surf(struct brw_context *brw, struct isl_surf *surf, enum isl_aux_usage *usage); -union isl_color_value -intel_miptree_get_isl_clear_color(struct brw_context *brw, - const struct intel_mipmap_tree *mt); - void intel_get_image_dims(struct gl_texture_image *image, int *width, int *height, int *depth);