protonscr

The Witcher 3 (next-gen): GPU hang (Xid 109 / VK_ERROR_DEVICE_LOST) when enabling ray tracing

vkd3dopen
HansKristian-Work/vkd3d-proton#3226 · opened 2026-08-20 by Stanni97 · updated 2026-08-28 · 5 comments · github
SStanni97 2026-08-20 github

Enabling the master ray tracing toggle in The Witcher 3 next-gen reliably hangs the GPU about 40 seconds later. The game freezes permanently and has to be killed. dmesg reports Xid 109 CTX SWITCH TIMEOUT for witcher3.exe, and vkd3d-proton logs a cascade of vr -4 (VK_ERROR_DEVICE_LOST). Same channel and Info value every run.

No individual RT effect is needed to trigger it — the master toggle alone, with GI, reflections, AO and shadows all off, is enough.

Notes that may help narrow it down:

  • Cyberpunk 2077 runs ray tracing on this exact stack without issues, so DXR itself works here.
  • The same hardware runs Witcher 3 with RT fine under Windows.
  • The game is detected correctly (Detected game witcher3.exe, adding 2 configs + shader quirks).
  • Tested with no effect: single_queue, no_upload_hvv, descriptor_heap (confirmed active in the log), cleared shader cache, stock clocks (no LACT/overclocking).
  • DX11 and DX12-without-RT are both stable.

Possibly related to #3085, where downgrading to vkd3d-proton 3.0.0 fixed a similar DEVICE_LOST hang. I could not test that — every Proton build available to me ships 3.1.0.

Software information

The Witcher 3: Wild Hunt — Complete Edition (GOG), next-gen, DX12, 2560x1440. Ray tracing master toggle enabled in the main menu, all individual RT effects off.

System information

  • GPU: NVIDIA GeForce RTX 4070
  • Driver: 610.57.04, open kernel modules
  • Wine version: proton-cachyos 11.0-20260703 (also reproduced on GE-Proton11-5)
  • VKD3D-Proton version: 3.1.0, build 3dfc6f07d0953b1 (GE-Proton11-5: 731c4aae5991b33)

Log files

Attached: full log captured via Lutris/umu-launcher with VKD3D_DEBUG=info (not a Steam install, so no steam-xxxxx.log).

Relevant excerpt:

NVRM: Xid (PCI:0000:01:00): 109, pid=60621, name=witcher3.exe, channel 0x0000001d, errorString CTX SWITCH TIMEOUT, Info 0x25c01a
10688.746: d3d12_device_determine_ray_tracing_tier: DXR 1.1 support enabled.
10694.231: dxgi_vk_swap_chain_init: Creating swapchain (2560 x 1440), BufferCount = 3.
10734.780: err: vkd3d_wait_for_gpu_timeline_semaphore: Failed to wait for Vulkan timeline semaphore, vr -4.
10734.783: err: d3d12_command_queue_execute: Failed to submit queue(s), vr -4.

witcher3-rt-hang-proton-cachyos.log

Ddoitsujin maintainer 2026-08-24 github

wasn't this already fixed? Please try a more up to date vkd3d-proton build (e.g. from Proton Experimental).

SStanni97 2026-08-24 github

Tested with Proton Experimental — vkd3d-proton 3.1.0, build 238f157e1d64f90, a different build than the two in the original report (3dfc6f07d0953b1 and 731c4aae5991b33). The hang still reproduces, same vr -4 cascade, same Xid 109 CTX SWITCH TIMEOUT.

One caveat: the prefix was originally created by proton-cachyos, and Experimental logs Proton: Upgrading prefix from CachyOS-11.0-100 to 11.0-100 / Prefix has an invalid version?! on startup. I doubt that explains a GPU hang, but I'm happy to redo the test with a fresh prefix if you'd like to rule it out.

Driver here is 610.57.04 with the open kernel modules. Attaching the new log.

witcher3.log

Aaustin-wojo 2026-08-26 github

Reproduced on effectively identical hardware (RTX 4070, 610.57.04 open modules, GE-Proton11-5),
and I think I have the mechanism. The Xid 109 CTX SWITCH TIMEOUT is a downstream symptom,
not the fault.
Running with VKD3D_CONFIG=fault changes the reported error entirely:

NVRM: Xid (PCI:0000:0b:00): 31, name=witcher3.exe, MMU Fault: ENGINE GRAPHICS GPC1
  GPCCLIENT_T1_2 faulted @ 0xe1_4a8bc000. Fault is of type FAULT_PDE ACCESS_TYPE_VIRT_READ

d3d12_device_report_fault: Address [0]: 000000e14a8bc000 (granularity 1), type N/A
vkd3d_address_binding_tracker_check_va: Found no candidate VA entries. Page fault was likely
  caused by accessing never used memory or out of bounds access.

It is a page fault into unmapped memory. The context-switch timeout is just what the driver
reports once the faulted context can no longer be switched out.

The signature

Across runs, the shader PC is always the same region (~0xdf3e761xxx) while the faulting
data address is different every time
(0xe14a8bc000, 0xb36f1e7a000, 0xbe2f373e000,
0x741f4fd0000). One specific shader, reading a pointer that is garbage. A race would move the
PC as well; this doesn't. That points at the data being structurally corrupt rather than late.

What it isn't

  • Not a missing barrier. VKD3D_CONFIG=breadcrumbs_sync (full barrier + sync after every
    command) still faults. extra_rtas_sync and single_queue also make no difference.
  • Not an out-of-bounds descriptor read. I built vkd3d-proton with
    -Denable_descriptor_qa=true and ran VKD3D_CONFIG=instruction_qa_checks: zero
    violations, no RESOURCE_HEAP_OOB, no ROOT_CBV_OOB. (Worth noting neither QA mode is
    compiled into any shipped Proton, so descriptor_qa_checks is silently inert on stock builds.)
  • Not driver version or Proton version. proton-cachyos, Proton Experimental and GE-Proton11-5
    all fail identically, as does forcing every RT sub-feature on or off.

What it is

Every load logs ~1750 of these inside a ~175 ms window:

d3d12_command_list_register_rtas_scratch_range: Application bug detected.
  Attempting to use scratch which is currently in flight on GPU. Flushing batch.

The game reuses one scratch buffer across all its BLAS builds. #3191 handled the aliasing, but
the allocation also appears to be too small — the game already under-queries RTAS sizes,
which is why its profile carries RTAS_ALLOW_BLAS_REBUILD_SIZES. Builds overrun their scratch,
corrupt neighbouring memory, and traversal then walks a malformed BVH into unmapped addresses.

Over-reporting the sizes in d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo fixes
it completely:

info->ResultDataMaxSizeInBytes     *= rtas_size_scale;
info->ScratchDataSizeInBytes       *= rtas_size_scale;
info->UpdateScratchDataSizeInBytes *= rtas_size_scale;
  • scale 4 — stable for ~1.5 hours with the RT master toggle on, sub-features off.
  • scale 8 — stable with all RT features on (shadows, RTAO, RTXGI) at 3440x1440.
  • scale 1 (stock) — faults within ~40 s, every time.

Open question

I can't tell from outside whether the shortfall originates in the game's size queries or in
vkGetAccelerationStructureBuildSizesKHR under-reporting on NVIDIA. A blunt multiplier is
obviously not a fix worth upstreaming as-is, but the fact that scaling it works at all should
narrow down where the real gap is.

Debugging note

VKD3D_DEBUG=info does not include warnings in this build — 117 info lines, 155 err lines,
0 warn. The register_rtas_scratch_range warnings above are invisible unless you use
VKD3D_DEBUG=warn. That cost me several hours, and may be why this looked like a bare timeout.

HHansKristian-Work maintainer 2026-08-28 github

Do we really just have to ignore app scratch and allocate our own? sigh

Mmbriar 2026-08-28 github

Fwiw, any workaround for this game is probably going to be obsolete next month with the next next gen update anyways (or it will require some new ones :p)

Proton versions

Launch options