mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 14:50:10 +01:00
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 <topi.pohjolainen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Chad Versace <chadversary@chromium.org>
This commit is contained in:
parent
1253d58983
commit
f9fd976e8a
15 changed files with 91 additions and 137 deletions
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue