radv,ac: Split has_tc_compat_zrange_bug into Z and ZS, document it

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Signed-off-by: Vitaliy Triang3l Kuzmin <triang3l@yandex.ru>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33962>
This commit is contained in:
Vitaliy Triang3l Kuzmin
2025-08-12 02:25:16 +03:00
committed by Marge Bot
parent 5243f292ef
commit 4e3a5f60e1
5 changed files with 55 additions and 15 deletions
+25 -2
View File
@@ -938,7 +938,29 @@ ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info,
/* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */
info->has_htile_stencil_mipmap_bug = info->gfx_level == GFX10;
info->has_tc_compat_zrange_bug = info->gfx_level >= GFX8 && info->gfx_level <= GFX9;
/* When drawing, if all samples covered in a cleared tile in HTILE are discarded (by the fragment
* shader, alpha to coverage, etc.), the tile stays cleared, but on the chips with this bug, the
* Z range in the tile still gets expanded by the depth test, and that may flip the upper bit of
* the HTILE encoding (of the maximum Z without stencil, or the base Z with stencil), inverting
* the clear value that texture reads will use for the tile.
*
* has_htile_tc_z_clear_bug_without/with_stencil indicate whether the TILE_STENCIL_DISABLE =
* 1 and 0 HTILE encodings respectively are subject to this bug.
*
* One possible workaround is to use the depth/stencil HTILE that encodes the Z range as base and
* delta, setting ZRANGE_PRECISION to 0 (base Z is min Z) when the depth is cleared to 0, and to
* 1 (base Z is max Z) when it's cleared to 1, so the Z delta gets expanded, but the base Z,
* which contains the TC clear value bit, stays the same.
* See DepthStencilView::UpdateZRangePrecision in PAL.
*
* Affects dEQP-VK.dynamic_state.*.discard.depth on has_htile_tc_z_clear_bug_without_stencil = 1
* chips as of the CTS commit 698abf5f6b7073562cc951617a58e5803c7ead3f (clearing a depth-only
* image to 0, drawing geometry with Z = 1 to it discarding all fragments in the shader, then
* reading it in vkCmdCopyImageToBuffer fetching 1 where 0 is supposed to be).
*/
info->has_htile_tc_z_clear_bug_without_stencil = info->gfx_level == GFX8;
info->has_htile_tc_z_clear_bug_with_stencil = info->has_htile_tc_z_clear_bug_without_stencil ||
info->gfx_level == GFX9;
info->has_small_prim_filter_sample_loc_bug =
(info->family >= CHIP_POLARIS10 && info->family <= CHIP_POLARIS12) ||
@@ -1714,7 +1736,8 @@ void ac_print_gpu_info(const struct radeon_info *info, FILE *f)
fprintf(f, " cpdma_prefetch_writes_memory = %u\n", info->cpdma_prefetch_writes_memory);
fprintf(f, " has_gfx9_scissor_bug = %i\n", info->has_gfx9_scissor_bug);
fprintf(f, " has_htile_stencil_mipmap_bug = %i\n", info->has_htile_stencil_mipmap_bug);
fprintf(f, " has_tc_compat_zrange_bug = %i\n", info->has_tc_compat_zrange_bug);
fprintf(f, " has_htile_tc_z_clear_bug_without_stencil = %i\n", info->has_htile_tc_z_clear_bug_without_stencil);
fprintf(f, " has_htile_tc_z_clear_bug_with_stencil = %i\n", info->has_htile_tc_z_clear_bug_with_stencil);
fprintf(f, " has_small_prim_filter_sample_loc_bug = %i\n", info->has_small_prim_filter_sample_loc_bug);
fprintf(f, " has_ls_vgpr_init_bug = %i\n", info->has_ls_vgpr_init_bug);
fprintf(f, " has_pops_missed_overlap_bug = %i\n", info->has_pops_missed_overlap_bug);
+2 -1
View File
@@ -97,7 +97,8 @@ struct radeon_info {
bool cpdma_prefetch_writes_memory;
bool has_gfx9_scissor_bug;
bool has_htile_stencil_mipmap_bug;
bool has_tc_compat_zrange_bug;
bool has_htile_tc_z_clear_bug_without_stencil;
bool has_htile_tc_z_clear_bug_with_stencil;
bool has_small_prim_filter_sample_loc_bug;
bool has_ls_vgpr_init_bug;
bool has_pops_missed_overlap_bug;
+3 -3
View File
@@ -4621,7 +4621,8 @@ radv_update_zrange_precision(struct radv_cmd_buffer *cmd_buffer, struct radv_ds_
uint32_t db_z_info = ds->ac.db_z_info;
uint32_t db_z_info_reg;
if (!pdev->info.has_tc_compat_zrange_bug || !radv_tc_compat_htile_enabled(image, iview->vk.base_mip_level))
if (!radv_image_has_tc_compat_zrange_metadata(device, image) ||
!radv_tc_compat_htile_enabled(image, iview->vk.base_mip_level))
return;
db_z_info &= C_028040_ZRANGE_PRECISION;
@@ -4979,10 +4980,9 @@ radv_set_tc_compat_zrange_metadata(struct radv_cmd_buffer *cmd_buffer, struct ra
const VkImageSubresourceRange *range, uint32_t value)
{
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
const struct radv_physical_device *pdev = radv_device_physical(device);
struct radv_cmd_stream *cs = cmd_buffer->cs;
if (!pdev->info.has_tc_compat_zrange_bug)
if (!radv_image_has_tc_compat_zrange_metadata(device, image))
return;
uint64_t va = radv_get_tc_compat_zrange_va(image, range->baseMipLevel);
+1 -1
View File
@@ -884,7 +884,7 @@ radv_image_alloc_values(const struct radv_device *device, struct radv_image *ima
image->size += 8 * image->vk.mip_levels;
}
if (radv_image_is_tc_compat_htile(image) && pdev->info.has_tc_compat_zrange_bug) {
if (radv_image_has_tc_compat_zrange_metadata(device, image)) {
/* Metadata for the TC-compatible HTILE hardware bug which
* have to be fixed by updating ZRANGE_PRECISION when doing
* fast depth clears to 0.0f.
+24 -8
View File
@@ -199,16 +199,32 @@ radv_tc_compat_htile_enabled(const struct radv_image *image, unsigned level)
static inline bool
radv_image_tile_stencil_disabled(const struct radv_device *device, const struct radv_image *image)
{
if (vk_format_has_stencil(image->vk.format))
return false;
const struct radv_physical_device *pdev = radv_device_physical(device);
if (pdev->info.gfx_level >= GFX9) {
return !vk_format_has_stencil(image->vk.format) && !radv_image_has_vrs_htile(device, image);
} else {
/* Due to a hw bug, TILE_STENCIL_DISABLE must be set to 0 for
* the TC-compat ZRANGE issue even if no stencil is used.
*/
return !vk_format_has_stencil(image->vk.format) && !radv_image_is_tc_compat_htile(image);
}
/* Need to use the base and delta Z encoding for the workaround. */
if (pdev->info.has_htile_tc_z_clear_bug_without_stencil && radv_image_is_tc_compat_htile(image))
return false;
return !radv_image_has_vrs_htile(device, image);
}
/**
* Return whether the image requires setting ZRANGE_PRECISION based on the last depth clear value to work around the
* hardware bug that may cause the HTILE depth clear value used by the TC to be changed.
*/
static inline bool
radv_image_has_tc_compat_zrange_metadata(const struct radv_device *device, const struct radv_image *image)
{
if (!radv_image_is_tc_compat_htile(image))
return false;
const struct radv_physical_device *pdev = radv_device_physical(device);
return radv_image_tile_stencil_disabled(device, image) ? pdev->info.has_htile_tc_z_clear_bug_without_stencil
: pdev->info.has_htile_tc_z_clear_bug_with_stencil;
}
static inline bool