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 <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33929>
This commit is contained in:
Samuel Pitoiset
2025-03-06 17:28:05 +01:00
committed by Marge Bot
parent 7819b103fa
commit 0bc9d59c2e
3 changed files with 15 additions and 0 deletions
+9
View File
@@ -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.
*/
+1
View File
@@ -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;
+5
View File
@@ -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) |