Skip to content

fix(vk): task + mesh draws through the compute fallback on Navi 21 too (#996) - #1992

Merged
hckrman101 merged 1 commit into
NotRexed:mainfrom
getzabelz:fix/navi21-task-mesh-fallback
Nov 11, 2026
Merged

hckrman101 merged 1 commit into
NotRexed:mainfrom
getzabelz:fix/navi21-task-mesh-fallback

Conversation

@getzabelz

Copy link
Copy Markdown
Contributor

Related to #996 (AMD on Windows: driver timeouts and device lost). A follow-up to #1747.

#1747 turned the compute fallback on by default for task + mesh draws on Navi 22 (RX 6700 XT, 0x73df), because AMD's Windows driver timed out on the native path there. Navi 21 (0x73bf: RX 6800, RX 6800 XT, RX 6900 XT) hangs the same way. This adds it to the same default, so those cards get the fallback without setting anything.

The change

gpu/vk/vk_main.cpp:

task_mesh_fallback = dev.props.vendorID == 0x1002 && (dev.props.deviceID == 0x73bf || dev.props.deviceID == 0x73df);
  • AMD and Windows only, as before. RADV on Linux is untouched.
  • RX_VK_TASK_MESH_FALLBACK still decides over it either way: =0 gives a Navi 21 the native path back.
  • The RX 6950 XT (0x73a5) is left out: I have not been able to test it.

Evidence

RX 6800 XT (1002:73BF), driver 0x800161 (32.0.21045.16010), Windows 11, 3440x1440, at the entrance to Hyrule Castle:

Build Path Result
Current main Native task + mesh Device lost (VK_ERROR_DEVICE_LOST, Windows LiveKernelEvent 141/117) within a couple of minutes of starting, a few seconds into play. The usual sign came first: a 5.3 s GPU wait (sync waits (5282 ms)) and a capture's write-back timing out.
Current main RX_VK_TASK_MESH_FALLBACK=1 25 minutes there, no device loss, no long GPU wait, and no fallback pipeline failing. The crates at the entrance draw correctly.
v2.0.13 Native Device lost twice in about 15 minutes in the same area (LiveKernelEvent 141/117, present failed (VkResult -4)).
v2.0.13 RX_VK_FORCE_MESH_FALLBACK=1 (the whole older fallback) 32 minutes, no device loss. The crates drew as flickering lights; that is fixed in main's fallback.

So on this card the native task + mesh path is what loses the device, and main's fallback both avoids it and draws correctly. Several reports in #996 are from RX 6800 / 6800 XT owners with the same symptoms (driver timeouts while playing, Hyrule Field, Kokiri).

To be transparent: the main builds tested also had #1823 applied (the driver-fault quarantine). That one is about the pause-menu freeze with no TDR; it does not touch the task + mesh path or the device loss here.

What it also brings on Navi 21

Turning task_mesh_fallback on is not only the draw path. Everything main gates on it applies too:

  • Fallback compute pipelines are built without the driver's optimizer (vk_draw.cpp, as on Navi 22).
  • Work around AMD Vulkan task shader timeouts and restore cloth rendering #1747's retry without the optimizer, after a graphics pipeline fails with VK_ERROR_UNKNOWN, now applies on Navi 21 too. It was not needed in the 25 minutes tested: no "recovered with optimization disabled" in the log.
  • The program cache key includes the mode (vk_shader.cpp). The first start after this change prepares the shaders again on these cards: 1,299 fallback programs in about 4.5 minutes here. A new translator stamp does the same anyway.

Frame rate: a rough look at the logs, leaving out menu frames, gives 47.5 fps on average with the fallback (371 samples over 25 minutes) against 56.2 fps on the native path. The native figure comes from only 10 samples, in other moments of play, before it lost the device. That is too little to measure; the fallback may cost some frame rate, but a lost device costs the session.

Tests

  • New tests/test_task_mesh_fallback_devices.py checks:

    • that Navi 21 and Navi 22 are both in the default;
    • that it is AMD-only and inside #ifdef _WIN32;
    • that RX_VK_TASK_MESH_FALLBACK is read after the default, so it decides for any GPU.

    It fails on current main's code and passes with this change.

  • docs/development.md now lists RX_VK_TASK_MESH_FALLBACK, which was not documented.

  • Full run_all.py on Windows: 291 passed (current main: 290). The 6 failures fail the same way on a clean main on this PC (local environment); none is new.

NotRexed#996)

NotRexed#1747 turned the compute fallback on by default for task + mesh draws on
Navi 22 (RX 6700 XT, 0x73df), where AMD's Windows driver timed out on the
native path. Navi 21 (0x73bf: RX 6800, 6800 XT, 6900 XT) does the same.
On an RX 6800 XT (driver 0x800161), Windows 11, at Hyrule Castle's
entrance:
- current main, native path: the device was lost (VK_ERROR_DEVICE_LOST,
  LiveKernelEvent 141/117) within minutes of play. A 5.3 s GPU wait came
  first, as before every such hang;
- the same build with RX_VK_TASK_MESH_FALLBACK=1: 25 minutes there with
  no device loss and no long GPU wait. The crates at the entrance draw
  correctly;
- on v2.0.13 the native path hung twice in 15 minutes there, and the
  whole-mesh fallback (RX_VK_FORCE_MESH_FALLBACK=1) played 32 minutes with
  none.

The default stays AMD-only and Windows-only, and RX_VK_TASK_MESH_FALLBACK
still decides over it either way. RX 6950 XT (0x73a5) is left out:
untested.

tests/test_task_mesh_fallback_devices.py checks both chips are in the
default, that it is AMD and Windows only, and that the variable is read
after it. docs/development.md lists RX_VK_TASK_MESH_FALLBACK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@hckrman101 hckrman101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is a small, well-scoped change, and the evidence is good: the A/B on the same card and spot (native loses the device within minutes, RX_VK_TASK_MESH_FALLBACK=1 plays 25 min), the v2.0.13 cross-check, and the honest fps note. It also matches what #996 keeps getting from Windows RX 6800 / 6800 XT / 6900 XT owners (Hyrule Field, camera turns, Zora's Domain).

Detection. PCI id under #ifdef _WIN32 with vendor 0x1002, so it only reaches AMD's Windows driver. RADV, the Deck (VanGogh), RDNA1 (no mesh shaders, already on the full fallback) and RDNA3/4 are untouched. One gap worth a look: 0x73bf is not every Navi 21. The XTXH 6900 XT boards (LC, Toxic and the like) report 0x73af. One shows up in #1000 on RADV (PCI 1002:73af), so Windows owners of that board will keep the native path. The 6950 XT is 0x73a5. Same chip, same driver. I understand leaving out what you couldn't test, but I'd add 0x73af at least, or say in the comment that those ids are left out on purpose. Not blocking.

Fit with main. The PR is 44 commits behind, but it merges cleanly. Main has since added the Mesh shaders row (#1971), with if (mesh_mode == 1) task_mesh_fallback = false; between the #endif and the env read. So Automatic picks up the new default, Native turns it off, Compute already runs everything on the fallback, and the env var still wins. Your test's checks (inside #ifdef _WIN32, env read after the default) still hold with that line there. The mesh-query gating (dev.mesh_queries) is independent of this. Small nit for the docs row: mention that Native in the Mesh shaders row also turns it off, since that's what players will reach for before an env var.

Side effects. As you list: the non-mesh VK_ERROR_UNKNOWN retry and the no-optimizer build of the fallback compute pipelines now apply on Navi 21. Mesh-only programs stay native and keep the PR 430 no-optimizer rule. The one-time re-preparation of shaders on first start (1,299 programs, about 4.5 min) is a real cost, but a one-off.

Relation to #1965 (build task/mesh programs with the optimizer on RADV): no shared code. #1965 only changes the amd check in build_graphics (vk_draw.cpp) and excludes VK_DRIVER_ID_MESA_RADV. This PR is Windows-only in vk_main.cpp, so neither changes what the other does on any GPU, and they can land in either order. After both, a Windows Navi 21 takes the compute fallback for task + mesh draws, and a Linux Navi 21 on RADV stays native with the optimizer on.

CI: the only failure is test_log_batch.py on windows-2022 (GetTickCount64() - t0 < 200), a timing check on a runner. It has nothing to do with this change. Ubuntu passes, and so does the Windows renderer build.

Looks good to me.

Comment thread gpu/vk/vk_main.cpp
// Navi 22 can time out on task + mesh draws in the AMD Windows driver (issue 996), and so can Navi 21: on an RX 6800 XT
// (driver 0x800161) the native path lost the device within minutes at Hyrule Castle's entrance, while the fallback played
// 25 minutes there with none. Navi 21 is 0x73bf (RX 6800, 6800 XT, 6900 XT); Navi 22 is 0x73df (RX 6700 XT)
task_mesh_fallback = dev.props.vendorID == 0x1002 && (dev.props.deviceID == 0x73bf || dev.props.deviceID == 0x73df);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Navi 21 also ships as 0x73af (XTXH RX 6900 XT boards) and 0x73a5 (RX 6950 XT). Same chip and same driver, so they probably hang the same way. I'd consider adding 0x73af, or noting here that it's left out on purpose (the test's ids == set(DEVICES) would need the same change).

@hckrman101
hckrman101 merged commit 1396428 into NotRexed:main Nov 11, 2026
9 of 10 checks passed
hckrman101 pushed a commit that referenced this pull request Nov 11, 2026
…XTXH and RX 6950 XT (#996) (#2215)

Follow-up to #1992, as @hckrman101 suggested in [the
review](#1992 (comment)).

Navi 21 also ships as **0x73af** (RX 6900 XT, XTXH boards) and
**0x73a5** (RX 6950 XT). It's the same chip on the same AMD Windows
driver as 0x73bf, so I've added both to the default task + mesh compute
fallback.

- `gpu/vk/vk_main.cpp`: the two IDs are added to the default (AMD,
Windows only). The comment says they weren't tested on their own.
- `tests/test_task_mesh_fallback_devices.py`: `DEVICES` lists them, so
the `ids == set(DEVICES)` check covers them.
- `docs/development.md`: the `RX_VK_TASK_MESH_FALLBACK` row names the
6950 XT.

**Not tested on those cards**: I only have an RX 6800 XT (0x73bf). The
reasoning is the same chip and driver. If an owner reports a problem or
a big fps cost, `RX_VK_TASK_MESH_FALLBACK=0` turns it off. `python -I -B
tests/test_task_mesh_fallback_devices.py` passes locally.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants