radv: fix a perf issue when clearing depth/stencil images on GFX12

Clearing on graphics updates HiZ correctly and expanding it always
after the clear might hurt because it means HiZ will be disabled.

This probably helps performance with the full GFX12 HiZ WA.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40176>
This commit is contained in:
Samuel Pitoiset 2026-03-02 19:12:42 +01:00 committed by Marge Bot
parent cea75b3d95
commit fbcc4565c1

View file

@ -448,11 +448,9 @@ get_depth_stencil_pipeline(struct radv_device *device, int samples, VkImageAspec
static void
emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, VkClearDepthStencilValue clear_value,
VkImageAspectFlags aspects, const VkClearRect *clear_rect, uint32_t view_mask,
enum radv_cmd_flush_bits *pre_flush, enum radv_cmd_flush_bits *post_flush)
VkImageAspectFlags aspects, const VkClearRect *clear_rect, uint32_t view_mask)
{
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_physical_device *pdev = radv_device_physical(device);
const bool unrestricted = device->vk.enabled_extensions.EXT_depth_range_unrestricted;
const struct radv_rendering_state *render = &cmd_buffer->state.render;
struct radv_image_view *iview = render->ds_att.iview;
@ -462,27 +460,6 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, VkClearDepthStencilV
VkPipeline pipeline;
VkResult result;
const bool need_hiz_expand =
iview && radv_image_has_hiz_metadata(iview->image) && radv_is_clear_rect_full(iview, clear_rect, view_mask);
if (need_hiz_expand && pre_flush) {
assert(pdev->info.gfx_level == GFX12);
const VkImageSubresourceRange range = {
.aspectMask = aspects,
.baseMipLevel = iview->vk.base_mip_level,
.levelCount = iview->vk.level_count,
.baseArrayLayer = iview->vk.base_array_layer,
.layerCount = iview->vk.layer_count,
};
enum radv_cmd_flush_bits bits =
radv_src_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0, iview->image, &range);
cmd_buffer->state.flush_bits |= bits & ~*pre_flush;
*pre_flush |= cmd_buffer->state.flush_bits;
}
/* When a framebuffer is bound to the current command buffer, get the
* number of samples from it. Otherwise, get the number of samples from
* the render pass because it's likely a secondary command buffer.
@ -530,7 +507,8 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, VkClearDepthStencilV
radv_meta_set_stencil_reference(cmd_buffer, VK_STENCIL_FACE_FRONT_BIT, prev_reference);
}
if (need_hiz_expand) {
if (iview && radv_image_has_hiz_metadata(iview->image) && (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
radv_is_clear_rect_full(iview, clear_rect, view_mask)) {
const VkImageSubresourceRange range = {
.aspectMask = aspects,
.baseMipLevel = iview->vk.base_mip_level,
@ -539,14 +517,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, VkClearDepthStencilV
.layerCount = iview->vk.layer_count,
};
enum radv_cmd_flush_bits flush_bits =
radv_clear_hiz(cmd_buffer, iview->image, &range, radv_gfx12_get_hiz_initial_value());
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
radv_update_hiz_metadata(cmd_buffer, iview->image, &range, true);
if (post_flush)
*post_flush |= flush_bits;
radv_update_hiz_metadata(cmd_buffer, iview->image, &range, true);
}
}
@ -1545,14 +1516,14 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_at
pre_flush, post_flush);
} else if (!can_fast_clear_depth && !can_fast_clear_stencil) {
emit_depthstencil_clear(cmd_buffer, clear_att->clearValue.depthStencil, clear_att->aspectMask, clear_rect,
view_mask, pre_flush, post_flush);
view_mask);
} else {
if (can_fast_clear_depth) {
radv_fast_clear_depth(cmd_buffer, ds_att->iview, clear_att->clearValue.depthStencil,
VK_IMAGE_ASPECT_DEPTH_BIT, pre_flush, post_flush);
} else {
emit_depthstencil_clear(cmd_buffer, clear_att->clearValue.depthStencil, VK_IMAGE_ASPECT_DEPTH_BIT,
clear_rect, view_mask, pre_flush, post_flush);
clear_rect, view_mask);
}
if (can_fast_clear_stencil) {
@ -1560,7 +1531,7 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_at
VK_IMAGE_ASPECT_STENCIL_BIT, pre_flush, post_flush);
} else {
emit_depthstencil_clear(cmd_buffer, clear_att->clearValue.depthStencil, VK_IMAGE_ASPECT_STENCIL_BIT,
clear_rect, view_mask, pre_flush, post_flush);
clear_rect, view_mask);
}
}
}