fix(vk): build mesh programs with the optimizer on RADV (Steam Deck GPU hang) #2311

Closed
Kolkka wants to merge 1 commit from fix/radv-mesh-optimizer-hang into main
Kolkka commented 2026-11-11 14:24:52 +00:00 (Migrated from github.com)

On the Steam Deck the game freezes about 30 seconds into Kokiri Forest, every run: the kernel logs a ring gfx timeout and resets the GPU. Fixes #1000.

What changed: mesh programs on AMD are built without the driver's optimizer, a workaround for hangs on AMD's own drivers (RX 6600, #461, #484). On Mesa's RADV that is the case that hangs: the foliage culling mesh program 89ca750f9852b7ca, built without the optimizer, wedged the Deck's GPU (Van Gogh, RDNA2). The workaround now checks VkPhysicalDeviceDriverProperties::driverID and skips RADV, so RADV builds every mesh program with the optimizer, as on other vendors. AMD's proprietary drivers are unchanged. RX_VK_MESH_OPT=1 still forces the optimizer on.

Tested: Steam Deck LCD, SteamOS, Mesa RADV, handheld at 50% resolution. Before: ring gfx timeout and reset 25–40 s after the save loaded in Kokiri, in every run. After: no ring timeout or reset in any run since, each 1,200–6,000 frames past the first 3D frame. tests/run_all.py: no new failures against main.

🤖 Generated with Claude Code

On the Steam Deck the game freezes about 30 seconds into Kokiri Forest, every run: the kernel logs a ring gfx timeout and resets the GPU. Fixes #1000. **What changed:** mesh programs on AMD are built without the driver's optimizer, a workaround for hangs on AMD's own drivers (RX 6600, #461, #484). On Mesa's RADV that is the case that hangs: the foliage culling mesh program `89ca750f9852b7ca`, built without the optimizer, wedged the Deck's GPU (Van Gogh, RDNA2). The workaround now checks `VkPhysicalDeviceDriverProperties::driverID` and skips RADV, so RADV builds every mesh program with the optimizer, as on other vendors. AMD's proprietary drivers are unchanged. `RX_VK_MESH_OPT=1` still forces the optimizer on. **Tested:** Steam Deck LCD, SteamOS, Mesa RADV, handheld at 50% resolution. Before: ring gfx timeout and reset 25–40 s after the save loaded in Kokiri, in every run. After: no ring timeout or reset in any run since, each 1,200–6,000 frames past the first 3D frame. `tests/run_all.py`: no new failures against `main`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hckrman101 (Migrated from github.com) reviewed 2026-11-11 16:28:49 +00:00
hckrman101 (Migrated from github.com) left a comment

Thanks, and the Deck LCD runs plus the program id (89ca750f9852b7ca) are useful evidence.

This is the same change as #1965 (addisonbair, opened a day earlier): the amd lambda is identical line for line, vendorID == 0x1002 && driverID != VK_DRIVER_ID_MESA_RADV, only the code comment differs. I reviewed #1965 yesterday and the same points apply here, so I'll keep this short. Only one of the two should land; I'd suggest keeping one and moving your Deck LCD results (and the hang id) into it, so the comment and history carry both reports. That's for you two and @NotRexed to settle.

The code is right. Keying on driverID rather than the vendor is the correct axis, it matches the cloth guard a few lines below (which already uses VkPhysicalDeviceDriverProperties), and AMD's Windows driver and AMDVLK keep the PR 430 rule. The RX_VK_MESH_OPT=1 override still works. The #1000 thread backs it up: manianac (RX 6800 XT), addisonbair (Deck OLED) and NutterButterCake all report RX_VK_MESH_OPT=1 stops the hang.

What it doesn't cover: rere225 (RX 6900 XT, RADV) still hangs entering the Great Deku Tree with RX_VK_MESH_OPT=1, and KewinBR (Deck LCD) at Lon Lon Ranch, so the optimizer isn't the whole RADV story. Not a regression from this PR, but see the inline note on the comment wording.

Overlaps:

  • #2362 (deuxque) makes Automatic mean the compute path on Linux AMD. If it lands, this change only matters for people who pick Native by hand. Note #2362's RX 6600 runs were on stock main, i.e. with task/mesh built without the optimizer, the exact case this PR changes; it would be worth trying RX_VK_MESH_OPT=1 there before deciding RADV needs the compute path by default.
  • #2312 (yours) edits spirv_emit_context.cpp only: no conflict with this one.

Before merge: CI hasn't run (the Windows, Linux and source-regression workflows are waiting on maintainer approval, action_required). A small source check in tests/ (RADV excluded, RX_VK_MESH_OPT override kept) would keep this from being undone by accident; optional, in keeping with the repo.

Thanks, and the Deck LCD runs plus the program id (`89ca750f9852b7ca`) are useful evidence. **This is the same change as #1965** (addisonbair, opened a day earlier): the `amd` lambda is identical line for line, `vendorID == 0x1002 && driverID != VK_DRIVER_ID_MESA_RADV`, only the code comment differs. I reviewed #1965 yesterday and the same points apply here, so I'll keep this short. Only one of the two should land; I'd suggest keeping one and moving your Deck LCD results (and the hang id) into it, so the comment and history carry both reports. That's for you two and @NotRexed to settle. **The code is right.** Keying on `driverID` rather than the vendor is the correct axis, it matches the cloth guard a few lines below (which already uses `VkPhysicalDeviceDriverProperties`), and AMD's Windows driver and AMDVLK keep the PR 430 rule. The `RX_VK_MESH_OPT=1` override still works. The #1000 thread backs it up: manianac (RX 6800 XT), addisonbair (Deck OLED) and NutterButterCake all report `RX_VK_MESH_OPT=1` stops the hang. **What it doesn't cover:** rere225 (RX 6900 XT, RADV) still hangs entering the Great Deku Tree with `RX_VK_MESH_OPT=1`, and KewinBR (Deck LCD) at Lon Lon Ranch, so the optimizer isn't the whole RADV story. Not a regression from this PR, but see the inline note on the comment wording. **Overlaps:** - #2362 (deuxque) makes Automatic mean the compute path on Linux AMD. If it lands, this change only matters for people who pick Native by hand. Note #2362's RX 6600 runs were on stock main, i.e. with task/mesh built *without* the optimizer, the exact case this PR changes; it would be worth trying `RX_VK_MESH_OPT=1` there before deciding RADV needs the compute path by default. - #2312 (yours) edits `spirv_emit_context.cpp` only: no conflict with this one. **Before merge:** CI hasn't run (the Windows, Linux and source-regression workflows are waiting on maintainer approval, `action_required`). A small source check in `tests/` (RADV excluded, `RX_VK_MESH_OPT` override kept) would keep this from being undone by accident; optional, in keeping with the repo.
@ -2085,1 +2080,4 @@
// without it on AMD. RX_VK_MESH_OPT=1: with it, as the others)
// AMD's own drivers only. Mesa's RADV is the other way round: on the Steam Deck (Van Gogh, RDNA2) the foliage culling
// mesh program 89ca750f9852b7ca built without the optimizer wedged the GPU about 30 s after a save loaded in Kokiri, every
// run (ring gfx timeout, then a reset; issue 1000); built with it, the forest plays
hckrman101 (Migrated from github.com) commented 2026-11-11 16:28:49 +00:00

Nit: "built with it, the forest plays" reads as if RADV is fixed. Some RADV hangs remain with the optimizer on (rere225's 6900 XT at the Deku Tree, KewinBR's Deck at Lon Lon Ranch, both in #1000). Something like "built with it, this hang is gone" would be more accurate.

Nit: "built with it, the forest plays" reads as if RADV is fixed. Some RADV hangs remain with the optimizer on (rere225's 6900 XT at the Deku Tree, KewinBR's Deck at Lon Lon Ranch, both in #1000). Something like "built with it, this hang is gone" would be more accurate.
NotRexed commented 2026-11-11 21:22:03 +00:00 (Migrated from github.com)

Thanks, and for the Steam Deck measurement. #1965 makes the same change (the optimizer kept on for RADV, AMD's own driver unchanged), opened earlier, so the review continues there; your Van Gogh result is noted on it. Closing as a duplicate.

Thanks, and for the Steam Deck measurement. #1965 makes the same change (the optimizer kept on for RADV, AMD's own driver unchanged), opened earlier, so the review continues there; your Van Gogh result is noted on it. Closing as a duplicate.
Joey-Magnus (Migrated from github.com) reviewed 2026-11-11 21:24:40 +00:00
Joey-Magnus (Migrated from github.com) left a comment

The vk_draw.cpp lambda is identical to #1965's (still open) apart from the comment. The change is correct: the hangs that added the workaround (#461, #484) were on Windows/Adrenalin, so exempting RADV leaves it where it's needed. It doesn't cure every RADV hang, though; the RX 6900 XT Deku Tree and Lon Lon reports hang with the optimizer on. One of the two should merge with both sets of Deck results, and the other close. If this fixes #2245, #2362 may be unnecessary.

The `vk_draw.cpp` lambda is identical to #1965's (still open) apart from the comment. The change is correct: the hangs that added the workaround (#461, #484) were on Windows/Adrenalin, so exempting RADV leaves it where it's needed. It doesn't cure every RADV hang, though; the RX 6900 XT Deku Tree and Lon Lon reports hang with the optimizer on. One of the two should merge with both sets of Deck results, and the other close. If this fixes #2245, #2362 may be unnecessary.
Commenting is not possible because the repository is archived.
No description provided.