anv: Support fast-clears in vkCmdClearDepthStencilImage

Signed-off-by: Rohan Garg <rohan.garg@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Closes: #11897
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34824>
This commit is contained in:
Rohan Garg 2025-05-05 18:20:00 +02:00
parent db8b07f88d
commit 658b89ac86
3 changed files with 101 additions and 0 deletions

View file

@ -1666,6 +1666,7 @@ void anv_CmdClearDepthStencilImage(
bool clear_depth = pRanges[r].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
bool clear_stencil = pRanges[r].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
assert(clear_depth || clear_stencil);
unsigned base_layer = pRanges[r].baseArrayLayer;
uint32_t layer_count =
@ -1681,6 +1682,22 @@ void anv_CmdClearDepthStencilImage(
if (image->vk.image_type == VK_IMAGE_TYPE_3D)
layer_count = u_minify(image->vk.extent.depth, level);
const VkRect2D area = {
.offset.x = 0,
.offset.y = 0,
.extent.width = level_width,
.extent.height = level_height,
};
if (anv_can_hiz_clear_image(cmd_buffer, image, imageLayout,
pRanges[r].aspectMask,
pDepthStencil->depth, area, level)) {
anv_image_hiz_clear(cmd_buffer, image, pRanges[r].aspectMask,
level, base_layer, layer_count, area,
pDepthStencil);
continue;
}
blorp_clear_depth_stencil(&batch, &depth, &stencil,
level, base_layer, layer_count,
0, 0, level_width, level_height,

View file

@ -3560,6 +3560,81 @@ anv_can_fast_clear_color(const struct anv_cmd_buffer *cmd_buffer,
return true;
}
bool
anv_can_hiz_clear_image(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
VkImageLayout layout,
VkImageAspectFlags clear_aspects,
float depth_clear_value,
VkRect2D render_area,
const unsigned level)
{
const struct anv_device *device = cmd_buffer->device;
const VkQueueFlagBits queue_flags = cmd_buffer->queue_family->queueFlags;
if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
return false;
/* If we're just clearing stencil, we can always HiZ clear */
if (!(clear_aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
return true;
const enum isl_aux_usage clear_aux_usage =
anv_layout_to_aux_usage(device->info, image,
VK_IMAGE_ASPECT_DEPTH_BIT, 0,
layout, queue_flags);
const uint32_t plane =
anv_image_aspect_to_plane(image, VK_IMAGE_ASPECT_DEPTH_BIT);
const struct isl_surf *surf = &image->planes[plane].primary_surface.isl;
if (!isl_aux_usage_has_fast_clears(clear_aux_usage))
return false;
if (isl_aux_usage_has_ccs(clear_aux_usage)) {
/* From the TGL PRM, Vol 9, "Compressed Depth Buffers" (under the
* "Texture performant" and "ZCS" columns):
*
* Update with clear at either 16x8 or 8x4 granularity, based on
* fs_clr or otherwise.
*
* Although alignment requirements are only listed for the texture
* performant mode, test results indicate that requirements exist for
* the non-texture performant mode as well. Disable partial clears.
*/
if (render_area.offset.x > 0 ||
render_area.offset.y > 0 ||
render_area.extent.width !=
u_minify(image->vk.extent.width, level) ||
render_area.extent.height !=
u_minify(image->vk.extent.height, level)) {
return false;
}
/* When fast-clearing, hardware behaves in unexpected ways if the clear
* rectangle, aligned to 16x8, could cover neighboring LODs.
* Fortunately, ISL guarantees that LOD0 will be 8-row aligned and
* LOD0's height seems to not matter. Also, few applications ever clear
* LOD1+. Only allow fast-clearing upper LODs if no overlap can occur.
*/
assert(surf->dim_layout == ISL_DIM_LAYOUT_GFX4_2D);
assert(surf->array_pitch_el_rows % 8 == 0);
if (clear_aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT &&
level >= 1 &&
(image->vk.extent.width % 32 != 0 ||
surf->image_alignment_el.h % 8 != 0)) {
return false;
}
}
if (device->info->ver <= 12 &&
depth_clear_value != anv_image_hiz_clear_value(image).f32[0])
return false;
/* If we got here, then we can fast clear */
return true;
}
/**
* This function determines if the layout & usage of an image can have
* untracked aux writes. When we see a transition that matches this criteria,

View file

@ -6106,6 +6106,15 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
VkRect2D render_area,
const VkQueueFlagBits queue_flags);
bool
anv_can_hiz_clear_image(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
VkImageLayout layout,
VkImageAspectFlags clear_aspects,
float depth_clear_value,
VkRect2D render_area,
const unsigned level);
bool
anv_can_fast_clear_color(const struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,