diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 3521a22114e..2bc04a1cda8 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -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); diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h index b13c2d06359..b8cb8e26638 100644 --- a/src/amd/common/ac_gpu_info.h +++ b/src/amd/common/ac_gpu_info.h @@ -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; diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 111fae2fdcd..2ec10505676 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -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); diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 218a3de1323..8ed2f0f23db 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -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. diff --git a/src/amd/vulkan/radv_image.h b/src/amd/vulkan/radv_image.h index cec3440d962..d9b6d3e2885 100644 --- a/src/amd/vulkan/radv_image.h +++ b/src/amd/vulkan/radv_image.h @@ -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