intel: Move depth clear value writes to drivers
This improves drivers in the following ways: * iris_hiz_exec() and crocus_hiz_exec() gets rid of the narrowly-used update_clear_depth parameters. * iris avoids fast-clearing if the aux state is CLEAR. crocus avoids this too, but didn't actually need it in the first place. * iris updates the value once per fast_clear_depth() call instead of doing an update for each layer being cleared. * anv now updates the clear value when transitioning from an undefined layout instead of doing so on every fast-clear. This should be safer because we don't perform state cache invalidates when changing the clear value. So, existing surface states won't have any stale values. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30520>
This commit is contained in:
@@ -456,8 +456,6 @@ fast_clear_depth(struct crocus_context *ice,
|
||||
{
|
||||
struct crocus_batch *batch = &ice->batches[CROCUS_BATCH_RENDER];
|
||||
|
||||
bool update_clear_depth = false;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
@@ -492,14 +490,13 @@ fast_clear_depth(struct crocus_context *ice,
|
||||
* value so this shouldn't happen often.
|
||||
*/
|
||||
crocus_hiz_exec(ice, batch, res, res_level, layer, 1,
|
||||
ISL_AUX_OP_FULL_RESOLVE, false);
|
||||
ISL_AUX_OP_FULL_RESOLVE);
|
||||
crocus_resource_set_aux_state(ice, res, res_level, layer, 1,
|
||||
ISL_AUX_STATE_RESOLVED);
|
||||
}
|
||||
}
|
||||
const union isl_color_value clear_value = { .f32 = {depth, } };
|
||||
crocus_resource_set_clear_color(ice, res, clear_value);
|
||||
update_clear_depth = true;
|
||||
}
|
||||
|
||||
for (unsigned l = 0; l < box->depth; l++) {
|
||||
@@ -507,14 +504,9 @@ fast_clear_depth(struct crocus_context *ice,
|
||||
crocus_resource_level_has_hiz(res, level) ?
|
||||
crocus_resource_get_aux_state(res, level, box->z + l) :
|
||||
ISL_AUX_STATE_AUX_INVALID;
|
||||
if (update_clear_depth || aux_state != ISL_AUX_STATE_CLEAR) {
|
||||
if (aux_state == ISL_AUX_STATE_CLEAR) {
|
||||
perf_debug(&ice->dbg, "Performing HiZ clear just to update the "
|
||||
"depth clear value\n");
|
||||
}
|
||||
if (aux_state != ISL_AUX_STATE_CLEAR) {
|
||||
crocus_hiz_exec(ice, batch, res, level,
|
||||
box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
|
||||
update_clear_depth);
|
||||
box->z + l, 1, ISL_AUX_OP_FAST_CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -604,8 +604,7 @@ crocus_hiz_exec(struct crocus_context *ice,
|
||||
struct crocus_batch *batch,
|
||||
struct crocus_resource *res,
|
||||
unsigned int level, unsigned int start_layer,
|
||||
unsigned int num_layers, enum isl_aux_op op,
|
||||
bool update_clear_depth)
|
||||
unsigned int num_layers, enum isl_aux_op op)
|
||||
{
|
||||
struct crocus_screen *screen = batch->screen;
|
||||
const struct intel_device_info *devinfo = &batch->screen->devinfo;
|
||||
@@ -686,9 +685,7 @@ crocus_hiz_exec(struct crocus_context *ice,
|
||||
&res->base.b, res->aux.usage, level, true);
|
||||
|
||||
struct blorp_batch blorp_batch;
|
||||
enum blorp_batch_flags flags = 0;
|
||||
flags |= update_clear_depth ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR;
|
||||
blorp_batch_init(&ice->blorp, &blorp_batch, batch, flags);
|
||||
blorp_batch_init(&ice->blorp, &blorp_batch, batch, 0);
|
||||
blorp_hiz_op(&blorp_batch, &surf, level, start_layer, num_layers, op);
|
||||
blorp_batch_finish(&blorp_batch);
|
||||
|
||||
@@ -860,7 +857,7 @@ crocus_resource_prepare_access(struct crocus_context *ice,
|
||||
assert(aux_op == ISL_AUX_OP_PARTIAL_RESOLVE);
|
||||
crocus_mcs_partial_resolve(ice, batch, res, layer, 1);
|
||||
} else if (isl_aux_usage_has_hiz(res->aux.usage)) {
|
||||
crocus_hiz_exec(ice, batch, res, level, layer, 1, aux_op, false);
|
||||
crocus_hiz_exec(ice, batch, res, level, layer, 1, aux_op);
|
||||
} else if (res->aux.usage == ISL_AUX_USAGE_STC_CCS) {
|
||||
unreachable("crocus doesn't resolve STC_CCS resources");
|
||||
} else {
|
||||
|
@@ -381,8 +381,7 @@ crocus_hiz_exec(struct crocus_context *ice,
|
||||
struct crocus_batch *batch,
|
||||
struct crocus_resource *res,
|
||||
unsigned int level, unsigned int start_layer,
|
||||
unsigned int num_layers, enum isl_aux_op op,
|
||||
bool update_clear_depth);
|
||||
unsigned int num_layers, enum isl_aux_op op);
|
||||
|
||||
/**
|
||||
* Prepare a miptree for access
|
||||
|
@@ -526,8 +526,7 @@ fast_clear_depth(struct iris_context *ice,
|
||||
float depth)
|
||||
{
|
||||
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
|
||||
|
||||
bool update_clear_depth = false;
|
||||
const struct intel_device_info *devinfo = batch->screen->devinfo;
|
||||
|
||||
if (res->aux.usage == ISL_AUX_USAGE_HIZ_CCS_WT) {
|
||||
/* From Bspec 47010 (Depth Buffer Clear):
|
||||
@@ -581,16 +580,27 @@ fast_clear_depth(struct iris_context *ice,
|
||||
* value so this shouldn't happen often.
|
||||
*/
|
||||
iris_hiz_exec(ice, batch, res, res_level, layer, 1,
|
||||
ISL_AUX_OP_FULL_RESOLVE, false);
|
||||
ISL_AUX_OP_FULL_RESOLVE);
|
||||
iris_resource_set_aux_state(ice, res, res_level, layer, 1,
|
||||
ISL_AUX_STATE_RESOLVED);
|
||||
}
|
||||
}
|
||||
const union isl_color_value clear_value = { .f32 = {depth, } };
|
||||
iris_resource_set_clear_color(ice, res, clear_value);
|
||||
update_clear_depth = true;
|
||||
|
||||
/* Also set the indirect clear color if it exists. */
|
||||
if (res->aux.clear_color_bo) {
|
||||
uint32_t packed_depth;
|
||||
isl_color_value_pack(&clear_value, res->surf.format, &packed_depth);
|
||||
|
||||
const uint64_t clear_pixel_offset = res->aux.clear_color_offset +
|
||||
isl_get_sampler_clear_field_offset(devinfo, res->surf.format);
|
||||
|
||||
iris_emit_pipe_control_write(batch, "update fast clear value (Z)",
|
||||
PIPE_CONTROL_WRITE_IMMEDIATE,
|
||||
res->aux.clear_color_bo,
|
||||
clear_pixel_offset, packed_depth);
|
||||
|
||||
/* From the TGL PRMs, Volume 9: Render Engine, State Caching :
|
||||
*
|
||||
* "Any values referenced by pointers within the
|
||||
@@ -603,6 +613,7 @@ fast_clear_depth(struct iris_context *ice,
|
||||
* Invalidate the state cache as suggested.
|
||||
*/
|
||||
iris_emit_pipe_control_flush(batch, "flush fast clear values (z)",
|
||||
PIPE_CONTROL_FLUSH_ENABLE |
|
||||
PIPE_CONTROL_STATE_CACHE_INVALIDATE);
|
||||
}
|
||||
}
|
||||
@@ -610,14 +621,9 @@ fast_clear_depth(struct iris_context *ice,
|
||||
for (unsigned l = 0; l < box->depth; l++) {
|
||||
enum isl_aux_state aux_state =
|
||||
iris_resource_get_aux_state(res, level, box->z + l);
|
||||
if (update_clear_depth || aux_state != ISL_AUX_STATE_CLEAR) {
|
||||
if (aux_state == ISL_AUX_STATE_CLEAR) {
|
||||
perf_debug(&ice->dbg, "Performing HiZ clear just to update the "
|
||||
"depth clear value\n");
|
||||
}
|
||||
if (aux_state != ISL_AUX_STATE_CLEAR) {
|
||||
iris_hiz_exec(ice, batch, res, level,
|
||||
box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
|
||||
update_clear_depth);
|
||||
box->z + l, 1, ISL_AUX_OP_FAST_CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -675,8 +675,7 @@ iris_hiz_exec(struct iris_context *ice,
|
||||
struct iris_batch *batch,
|
||||
struct iris_resource *res,
|
||||
unsigned int level, unsigned int start_layer,
|
||||
unsigned int num_layers, enum isl_aux_op op,
|
||||
bool update_clear_depth)
|
||||
unsigned int num_layers, enum isl_aux_op op)
|
||||
{
|
||||
ASSERTED const struct intel_device_info *devinfo = batch->screen->devinfo;
|
||||
|
||||
@@ -738,9 +737,7 @@ iris_hiz_exec(struct iris_context *ice,
|
||||
res->aux.usage, level, true);
|
||||
|
||||
struct blorp_batch blorp_batch;
|
||||
enum blorp_batch_flags flags = 0;
|
||||
flags |= update_clear_depth ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR;
|
||||
blorp_batch_init(&ice->blorp, &blorp_batch, batch, flags);
|
||||
blorp_batch_init(&ice->blorp, &blorp_batch, batch, 0);
|
||||
blorp_hiz_op(&blorp_batch, &surf, level, start_layer, num_layers, op);
|
||||
blorp_batch_finish(&blorp_batch);
|
||||
|
||||
@@ -914,7 +911,7 @@ iris_resource_prepare_access(struct iris_context *ice,
|
||||
} else if (isl_aux_usage_has_mcs(res->aux.usage)) {
|
||||
iris_mcs_exec(ice, batch, res, layer, 1, aux_op);
|
||||
} else if (isl_aux_usage_has_hiz(res->aux.usage)) {
|
||||
iris_hiz_exec(ice, batch, res, level, layer, 1, aux_op, false);
|
||||
iris_hiz_exec(ice, batch, res, level, layer, 1, aux_op);
|
||||
} else if (res->aux.usage == ISL_AUX_USAGE_STC_CCS) {
|
||||
unreachable("iris doesn't resolve STC_CCS resources");
|
||||
} else {
|
||||
|
@@ -350,8 +350,7 @@ iris_hiz_exec(struct iris_context *ice,
|
||||
struct iris_batch *batch,
|
||||
struct iris_resource *res,
|
||||
unsigned int level, unsigned int start_layer,
|
||||
unsigned int num_layers, enum isl_aux_op op,
|
||||
bool update_clear_depth);
|
||||
unsigned int num_layers, enum isl_aux_op op);
|
||||
|
||||
/**
|
||||
* Prepare a miptree for access
|
||||
|
@@ -1546,24 +1546,6 @@ blorp_update_clear_color(UNUSED struct blorp_batch *batch,
|
||||
|
||||
#else
|
||||
|
||||
#if GFX_VER == 12
|
||||
if (isl_surf_usage_is_depth(info->surf.usage)) {
|
||||
const struct intel_device_info *devinfo =
|
||||
batch->blorp->compiler->brw->devinfo;
|
||||
blorp_emit(batch, GENX(MI_STORE_DATA_IMM), sdi) {
|
||||
sdi.Address = info->clear_color_addr;
|
||||
sdi.Address.offset +=
|
||||
isl_get_sampler_clear_field_offset(devinfo, info->surf.format);
|
||||
|
||||
isl_color_value_pack(&info->clear_color, info->surf.format,
|
||||
(uint32_t *)&sdi.ImmediateData);
|
||||
|
||||
sdi.ForceWriteCompletionCheck = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
blorp_emit(batch, GENX(MI_STORE_DATA_IMM), sdi) {
|
||||
sdi.Address = info->clear_color_addr;
|
||||
@@ -1591,16 +1573,10 @@ blorp_uses_bti_rt_writes(const struct blorp_batch *batch, const struct blorp_par
|
||||
static void
|
||||
blorp_exec_3d(struct blorp_batch *batch, const struct blorp_params *params)
|
||||
{
|
||||
if (!(batch->flags & BLORP_BATCH_NO_UPDATE_CLEAR_COLOR)) {
|
||||
if (params->fast_clear_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->dst.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->dst);
|
||||
}
|
||||
|
||||
if (params->hiz_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->depth.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->depth);
|
||||
}
|
||||
if (!(batch->flags & BLORP_BATCH_NO_UPDATE_CLEAR_COLOR) &&
|
||||
params->fast_clear_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->dst.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->dst);
|
||||
}
|
||||
|
||||
if (params->hiz_op != ISL_AUX_OP_NONE) {
|
||||
|
@@ -1879,16 +1879,10 @@ blorp_uses_bti_rt_writes(const struct blorp_batch *batch, const struct blorp_par
|
||||
static void
|
||||
blorp_exec_3d(struct blorp_batch *batch, const struct blorp_params *params)
|
||||
{
|
||||
if (!(batch->flags & BLORP_BATCH_NO_UPDATE_CLEAR_COLOR)) {
|
||||
if (params->fast_clear_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->dst.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->dst);
|
||||
}
|
||||
|
||||
if (params->hiz_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->depth.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->depth);
|
||||
}
|
||||
if (!(batch->flags & BLORP_BATCH_NO_UPDATE_CLEAR_COLOR) &&
|
||||
params->fast_clear_op == ISL_AUX_OP_FAST_CLEAR &&
|
||||
params->dst.clear_color_addr.buffer != NULL) {
|
||||
blorp_update_clear_color(batch, ¶ms->dst);
|
||||
}
|
||||
|
||||
#if GFX_VER >= 8
|
||||
|
@@ -464,6 +464,33 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer,
|
||||
if (image->planes[depth_plane].aux_usage == ISL_AUX_USAGE_NONE)
|
||||
return;
|
||||
|
||||
/* Initialize the indirect clear color prior to first use. */
|
||||
const struct anv_address clear_color_addr =
|
||||
anv_image_get_clear_color_addr(cmd_buffer->device, image,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
if (!anv_address_is_null(clear_color_addr) &&
|
||||
(initial_layout == VK_IMAGE_LAYOUT_UNDEFINED ||
|
||||
initial_layout == VK_IMAGE_LAYOUT_PREINITIALIZED)) {
|
||||
const enum isl_format depth_format =
|
||||
image->planes[depth_plane].primary_surface.isl.format;
|
||||
assert(ANV_HZ_FC_VAL == 1.0f);
|
||||
const uint32_t depth_value = depth_format == ISL_FORMAT_R32_FLOAT ?
|
||||
0x3f800000 : ~0;
|
||||
|
||||
const uint32_t clear_pixel_offset = clear_color_addr.offset +
|
||||
isl_get_sampler_clear_field_offset(cmd_buffer->device->info,
|
||||
depth_format);
|
||||
const struct anv_address clear_pixel_addr = {
|
||||
.bo = clear_color_addr.bo,
|
||||
.offset = clear_pixel_offset,
|
||||
};
|
||||
|
||||
struct mi_builder b;
|
||||
mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
|
||||
mi_builder_set_write_check(&b, true);
|
||||
mi_store(&b, mi_mem32(clear_pixel_addr), mi_imm(depth_value));
|
||||
}
|
||||
|
||||
/* If will_full_fast_clear is set, the caller promises to fast-clear the
|
||||
* largest portion of the specified range as it can.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user