intel: Use a simpler workaround for HiZ WT fast-clears

The new workaround tries to strike a balance between simplicity and
functionality (for testing purposes). Instead of checking for the
alignment of a specific LOD when fast-clearing, we take an
all-or-nothing approach for LOD1+.

I haven't found any app to clear LOD1+ except for a Dirt Rally trace
some time ago. If I remember correctly, that trace clears all LODs,
doesn't render to them, then clears again with a different color,
incurring resolves. So, skipping LOD1+ fast clears will avoid those
resolves. Other apps I tested include Synmark2, glmark2, GfxBench5, and
the Vulkan games in internal our benchmarking tool.

Now that we've added updated and simplified checks in the drivers
themselves, we delete blorp_can_hiz_clear_depth.

Reviewed-by: Rohan Garg <rohan.garg@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30250>
This commit is contained in:
Nanley Chery
2024-07-17 11:55:06 -04:00
committed by Marge Bot
parent a28bd0abdf
commit 07e0834774
5 changed files with 36 additions and 88 deletions
+14 -4
View File
@@ -498,10 +498,20 @@ can_fast_clear_depth(struct iris_context *ice,
if (!iris_resource_level_has_hiz(devinfo, res, level))
return false;
if (!blorp_can_hiz_clear_depth(devinfo, &res->surf, res->aux.usage,
level, box->z, box->x, box->y,
box->x + box->width,
box->y + box->height)) {
/* 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.
*
* 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.
*/
if (res->aux.usage == ISL_AUX_USAGE_HIZ_CCS_WT && level >= 1 &&
(p_res->width0 % 32 != 0 || res->surf.image_alignment_el.h % 8 != 0)) {
return false;
}
+1 -6
View File
@@ -314,12 +314,7 @@ blorp_clear_depth_stencil(struct blorp_batch *batch,
uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
bool clear_depth, float depth_value,
uint8_t stencil_mask, uint8_t stencil_value);
bool
blorp_can_hiz_clear_depth(const struct intel_device_info *devinfo,
const struct isl_surf *surf,
enum isl_aux_usage aux_usage,
uint32_t level, uint32_t layer,
uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1);
void
blorp_hiz_clear_depth_stencil(struct blorp_batch *batch,
const struct blorp_surf *depth,
-56
View File
@@ -916,62 +916,6 @@ blorp_clear_depth_stencil(struct blorp_batch *batch,
}
}
bool
blorp_can_hiz_clear_depth(const struct intel_device_info *devinfo,
const struct isl_surf *surf,
enum isl_aux_usage aux_usage,
uint32_t level, uint32_t layer,
uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
{
/* This function currently doesn't support any gen prior to gfx8 */
assert(devinfo->ver >= 8);
if (aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT && level > 0) {
/* We have to set the WM_HZ_OP::FullSurfaceDepthandStencilClear bit
* whenever we clear an uninitialized HIZ buffer (as some drivers
* currently do). However, this bit seems liable to clear 16x8 pixels in
* the ZCS on Gfx12 - greater than the slice alignments of many depth
* buffers.
*
* This is the hypothesis behind some corruption that was seen with the
* amd_vertex_shader_layer-layered-depth-texture-render piglit test.
*
* From the Compressed Depth Buffers section of the Bspec, under the
* Gfx12 texture performant and ZCS columns:
*
* Update with clear at either 16x8 or 8x4 granularity, based on
* fs_clr or otherwise.
*
* There are a number of ways to avoid full surface CCS clears that
* overlap other slices, but for now we choose to disable fast-clears
* when an initializing clear could hit another miplevel.
*
* NOTE: Because the CCS compresses the depth buffer and not a version
* of it that has been rearranged with different alignments (like Gfx8+
* HIZ), we have to make sure that the x0 and y0 are at least 16x8
* aligned in the context of the entire surface.
*/
uint32_t slice_x0, slice_y0, slice_z0, slice_a0;
isl_surf_get_image_offset_el(surf, level,
surf->dim == ISL_SURF_DIM_3D ? 0 : layer,
surf->dim == ISL_SURF_DIM_3D ? layer: 0,
&slice_x0, &slice_y0, &slice_z0, &slice_a0);
const bool max_x1_y1 =
x1 == u_minify(surf->logical_level0_px.width, level) &&
y1 == u_minify(surf->logical_level0_px.height, level);
const uint32_t haligned_x1 = ALIGN(x1, surf->image_alignment_el.w);
const uint32_t valigned_y1 = ALIGN(y1, surf->image_alignment_el.h);
const bool unaligned = (slice_x0 + x0) % 16 || (slice_y0 + y0) % 8 ||
(max_x1_y1 ? haligned_x1 % 16 || valigned_y1 % 8 :
x1 % 16 || y1 % 8);
if (unaligned)
return false;
}
return isl_aux_usage_has_hiz(aux_usage);
}
static bool
blorp_can_clear_full_surface(const struct blorp_surf *depth,
const struct blorp_surf *stencil,
+20 -11
View File
@@ -192,17 +192,8 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
layout, queue_flags);
if (!blorp_can_hiz_clear_depth(device->info,
&iview->image->planes[0].primary_surface.isl,
clear_aux_usage,
iview->planes[0].isl.base_level,
iview->planes[0].isl.base_array_layer,
render_area.offset.x,
render_area.offset.y,
render_area.offset.x +
render_area.extent.width,
render_area.offset.y +
render_area.extent.height))
if (!isl_aux_usage_has_fast_clears(clear_aux_usage))
return false;
if (isl_aux_usage_has_ccs(clear_aux_usage)) {
@@ -224,6 +215,24 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
u_minify(iview->vk.extent.height, iview->vk.base_mip_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.
*/
const struct isl_surf *surf =
&iview->image->planes[0].primary_surface.isl;
assert(isl_surf_usage_is_depth(surf->usage));
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 &&
iview->vk.base_mip_level >= 1 &&
(iview->vk.extent.width % 32 != 0 ||
surf->image_alignment_el.h % 8 != 0)) {
return false;
}
}
if (depth_clear_value != ANV_HZ_FC_VAL)
+1 -11
View File
@@ -414,17 +414,7 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
layout);
if (!blorp_can_hiz_clear_depth(device->info,
&iview->image->planes[0].primary_surface.isl,
clear_aux_usage,
iview->planes[0].isl.base_level,
iview->planes[0].isl.base_array_layer,
render_area.offset.x,
render_area.offset.y,
render_area.offset.x +
render_area.extent.width,
render_area.offset.y +
render_area.extent.height))
if (!isl_aux_usage_has_fast_clears(clear_aux_usage))
return false;
assert(GFX_VER == 8);