fix(vk): RADV's mesh shaders off by default on Linux AMD (issue 2245) #2362
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2362
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/radv-mesh-compute-default"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #2245.
Until this lands, setting Mesh shaders to Compute avoids the crash.
On Linux, Automatic now means Compute on AMD cards: RADV's task/mesh path hangs the GPU, so native mesh shaders stay off unless Native is picked by hand. Windows keeps what it had. RDNA1 and older never had mesh shaders on RADV, so nothing changes there.
Why full Compute and not the fallback: on the native path the gfx ring and RADV's gang compute ring end up waiting on each other with no waves running (the RX 6800 devcoredump in #2245). With RX_VK_TASK_MESH_FALLBACK=1 the hang moves to a mesh-only draw instead: waves on gfx, compute queue empty. So pushing only task and mesh draws to the fallback, like the Windows default from #1747, is not enough on RADV. Which programs hang moves around between runs (the checkpoint culprits follow the skipped ones), so it isn't one bad shader either. The reports cover Navi 2x (RX 6800, RX 6600 XT) and the RDNA3 APUs (Steam Deck OLED, Rog Xbox Ally X), which is why this keys on the vendor instead of a device list.
Tested on an RX 6600 (RADV NAVI23, driver 0x6802006, kernel 7.3.3-cachyos), v2.1.0:
main with the same patch compiles clean.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
Thanks for the careful write-up, and the devcoredump reading from DuxMuxxy in #2245 makes the case well that task-only fallback (the #1747 Windows default) isn't enough on RADV. The code itself is small and correct:
mesh_modestays the row's value, so the log still says "Automatic (the compute path)", Native still opts back in, andtask_mesh_fallbackis moot oncedev.mesh_shaderis off. No test pins the touched lines.Before this goes in as the default, though, I think it should be checked against #2311. That PR finds that on RADV the hang comes from building mesh programs without the driver's optimizer (the AMD workaround from #461/#484 in
build_graphics), and turns the optimizer back on forVK_DRIVER_ID_MESA_RADV. It was tested on a Steam Deck LCD with the same symptom (ring gfx timeout ~30 s into Kokiri, then a reset). That fits what's described here: the culprit program moves between runs, and both task+mesh and mesh-only draws hang, which is what you'd expect if many mesh programs are built the bad way rather than one shader being wrong. #2312 (index map sizing) is a rendering fix and doesn't look related to the hang.If #2311 fixes #2245 on the RX 6600 / RX 6800, Compute-by-default on every Linux AMD card would cost performance for nothing: the compute path runs task/mesh as compute dispatches writing vertices to buffers plus an ordinary draw, which the menu itself calls "usually a little slower", and DuxMuxxy saw a cost too. That matters most on the Steam Deck and the Ally, the RDNA2/3 APUs this would also switch, which are the ones with the least headroom. Could you (or DuxMuxxy) run #2311 on top of main with Mesh shaders on Automatic through the post-intro cutscene? If it holds, I'd drop this PR or keep it only for whatever still hangs; if it doesn't, this is a fine stopgap, ideally with an fps number for Native vs Compute on one RDNA2 card so the cost is known.
One thing on the check itself, inline. CI: only the title check ran; the build and source-regression workflows are waiting for maintainer approval.
@ -251,0 +256,4 @@int mesh_mode_used = mesh_mode;#ifndef _WIN32if (mesh_mode_used == 0 && dev.props.vendorID == 0x1002) mesh_mode_used = 2; // (Linux AMD is RADV)#endifvendorID == 0x1002under#ifndef _WIN32is a stand-in for "the driver is RADV", but it isn't quite that: AMDVLK / AMD's own Vulkan driver can still be installed on Linux (and gets the optimizer-off workaround that worked for it on Windows), and the Windows build run under Proton on a Deck is RADV with_WIN32defined, so it misses this. Keying onVkPhysicalDeviceDriverProperties::driverID == VK_DRIVER_ID_MESA_RADV(as #2311 does) covers both.dev.driver_idis only filled further down (the subgroup block), so it'd need avkGetPhysicalDeviceProperties2with the driver properties here, or that query moved up.RDNA3 desktop data in support (RX 7900 XT, RADV NAVI31, Mesa 26.2.3, Linux 7.2.7; rows in docs/tested-configurations.md from #2202):
117eae7)RX_VK_FORCE_MESH_FALLBACK=1)RX_VK_TASK_MESH_FALLBACK=1)On an older build, native hung on the load into Kokiri Forest (gfx ring timeout → MODE1 reset) in 3 of 4 tries. Since then we've played on full compute, with no hang. So on this card, full compute is also the fastest mode, and making it the AMD default costs nothing here.
The inline point still applies:
gpu/vk/vk_main.cpp:258checksvendorID == 0x1002under#ifndef _WIN32. That catches AMDVLK on Linux and misses the Windows build under Proton, where the driver is RADV.driverID == VK_DRIVER_ID_MESA_RADVcovers both.#2311 (re-enable the optimizer for mesh programs on RADV) may be the real fix for #2245. If it is, this PR would move every Linux AMD card, Deck and Ally included, onto the slower compute fallback for nothing. #2382's depth hold also applies on that path, and the two haven't been tested together. Could someone with an RX 6600/6800 try #2311 first?
Quick follow-up, since there's new data on the thread (the head hasn't changed since my last review).
On the cost question: simonwjackson's RX 7900 XT numbers above show full Compute as the fastest of the three modes on that card (46 fps vs 45 native), and Fortich's RX 6800 XT run in #2245 holds 60 fps through the point where it used to lose the device. So on desktop RDNA2/3 the default looks free and it does stop the hang. What's still unmeasured is the Deck and the Ally, the APUs this also switches.
On #2311: it was closed as a duplicate of #1965, which is still open. Its author now says it fixes the reset while the save loads and that other RADV hangs remain, so it likely won't cover the post-intro cutscene hang here on its own. That makes this a reasonable stopgap to me, and the two don't conflict (#1965 only matters once Native is picked).
Still open, as Joey-Magnus also noted: the check on
gpu/vk/vk_main.cpp:258keys onvendorID == 0x1002under#ifndef _WIN32, so it catches AMDVLK on Linux and misses the Windows build under Proton on a Deck (RADV with_WIN32defined).driver_id == VK_DRIVER_ID_MESA_RADV(#1965 now readsdev.driver_idfor the same reason) would cover both; it needs that query to happen before this point. The menu hint's "on Linux AMD" would then read "on RADV".CI: only the title check has run; the build and source-regression workflows still wait for maintainer approval.
This is the run asked for in the review: RX 6800 XT, main with #1965 merged (landed 23:34Z today), Mesh shaders on Automatic.
Result: on this card the optimizer change is not enough on its own for native mesh, the run still ends in a full GPU reset.
99 s into the session, at frame 1398. The kernel took a full reset:
To be clear about what this says and what it does not: #1965 may well fix what it set out to fix — the reset while a save loads and nothing here contradicts that. The finding is narrower: on desktop RDNA2 with Automatic, the mesh path still takes the GPU down.
It is not the import bug either: the same run logged
0pool ... not importedlines, with the sparse-queue patch active (sparse buffers are bound on a queue of family 4).An earlier attempt on the same build hung sooner, on the Kokiri Forest load, with
ring gfx_0.0.0followed byring comp_1.0.1timeouts — the mutual wait this PR describes. This one got further, then took the full reset.Same build with the compute fallback restored: loads and runs, no resets.
What I could not measure: fps Native vs Compute. The native run died before there was a stable window to read it.
Hardware: RX 6800 XT (RADV NAVI21), Mesa 25.0.7, kernel 7.0.0-42, Vulkan 1.4.
github-sync referenced this pull request2026-11-12 06:22:54 +00:00