From 0bc9d59c2e312ca95031266fb4ac93f7166506a6 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 6 Mar 2025 17:28:05 +0100 Subject: [PATCH] ac,radv: add a workaround for a hw bug with primitive restart on GFX10-GFX10.3 At least, NAVI10, NAVI21 and NAVI24 are affected by this what looks like a hardware bug when primitive restart is changed and no context registers are written between draws. It seems the hardware doesn't consider primitive restart at all in this situation. Adding SQ_NON_EVENT(0) as suggested by Marek seems to fix it reliably without introducing any overhead. It's basically a NOP packet that adds a small delay. Fixes new VKCTS coverage dEQP-VK.transform_feedback.primitive_restart.*. Also fixes this old vkd3d-proton issue. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7258 Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/common/ac_gpu_info.c | 9 +++++++++ src/amd/common/ac_gpu_info.h | 1 + src/amd/vulkan/radv_cmd_buffer.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index fdd12d2cad8..47f31b9e835 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -1261,6 +1261,15 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info, info->has_vgt_flush_ngg_legacy_bug = info->gfx_level == GFX10 || info->family == CHIP_NAVI21; + /* GFX10-GFX10.3 (tested on NAVI10, NAVI21 and NAVI24 but likely all) are + * affected by a hw bug when primitive restart is updated and no context + * registers are written between draws. One workaround is to emit + * SQ_NON_EVENT(0) which is a NOP packet that adds a small delay and seems + * to fix it reliably. + */ + info->has_prim_restart_sync_bug = info->gfx_level == GFX10 || + info->gfx_level == GFX10_3; + /* First Navi2x chips have a hw bug that doesn't allow to write * depth/stencil from a FS for multi-pixel fragments. */ diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h index 933267386c4..47867e75996 100644 --- a/src/amd/common/ac_gpu_info.h +++ b/src/amd/common/ac_gpu_info.h @@ -104,6 +104,7 @@ struct radeon_info { bool has_image_load_dcc_bug; bool has_two_planes_iterate256_bug; bool has_vgt_flush_ngg_legacy_bug; + bool has_prim_restart_sync_bug; bool has_cs_regalloc_hang_bug; bool has_async_compute_threadgroup_bug; bool has_async_compute_align32_bug; diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 8742d60489a..1e5ae5dd5c4 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -3363,6 +3363,11 @@ radv_emit_primitive_restart_enable(struct radv_cmd_buffer *cmd_buffer) struct radeon_cmdbuf *cs = cmd_buffer->cs; const bool en = d->vk.ia.primitive_restart_enable; + if (pdev->info.has_prim_restart_sync_bug) { + radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); + radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_SQ_NON_EVENT) | EVENT_INDEX(0)); + } + if (gfx_level >= GFX11) { radeon_set_uconfig_reg(cs, R_03092C_GE_MULTI_PRIM_IB_RESET_EN, S_03092C_RESET_EN(en) |