protonscr

Crash while playing dx12 games with DLSS + ReShade Addon

vkd3dopen
HansKristian-Work/vkd3d-proton#2797 · opened 2026-01-18 by ilyeser · updated 2026-09-06 · 6 comments · github
Iilyeser 2026-01-18 github

The game just crashes (sometimes at start, sometimes randomly while playing) when both DLSS and Reshade Addon are enabled. Even after the recent patch of Reshade Addon (v6.7).

Software information

Cyberpunk 2077 (crashes randomly while playing, sometime at start)
The Witcher 3

System information

  • GPU: RTX 3090
  • Driver: nvidia-open 590.48.01-7
  • Wine version: Proton-GE 10-28
  • VKD3D-Proton version: Proton-GE 10-28
  • Addition info : Reshade 6.7 + Renodx (reshade installed with https://github.com/kevinlekiller/reshade-steam-proton)
  • Envars : PROTON_LOG=1 ENABLE_HDR_WSI=1 PROTON_ENABLE_HDR=1 PROTON_ENABLE_WAYLAND=1 DXVK_HDR=1 DXVK_NVAPI_DRS_NGX_DLSS_SR_OVERRIDE_RENDER_PRESET_SELECTION=RENDER_PRESET_K WINEDLLOVERRIDES="d3dcompiler_47=n;dxgi=n,b" %command% --launcher-skip

Log files

proton-logs.tar.gz

Jjettoblack 2026-03-23 github

@ilyeser I'm in a similar boat. Here's my current status with Reshade + Cyberpunk + Proton + Nvidia. My launch command is very similar to yours. I tried it both via gamescope and without, the results are the same either way.

Nvidia driver 595.45.04
proton-cachyos-slr 1:10.0.20260320-1 (based on proton experimental-10.0-20260312)
Reshade 6.7.3.2148

Reshade uninstalled: Game runs 100% stable in HDR with either PROTON_VKD3D_HEAP=0 or 1 (I don't know if it makes any difference currently, performance seems about the same)

Reshade installed:

With PROTON_VKD3D_HEAP=1 main menu loads, game loads and runs, but graphics are scrambled. Interestingly, the inventory screen renders the 3d character model just fine:

Image

Image

(Both screenshots with Reshade enabled.)

With PROTON_VKD3D_HEAP=0 it hangs every time at the "Welcome to Night City" loading screen just before the main menu. Logs from both modes above attached:

cyberpunk_reshade_logs.zip

There was one combination of Nvidia 590 drivers and an older proton / Reshade build where I could get it playable and looking correct with Reshade for anywhere between 30 seconds and a couple minutes before it would crash or hang, which wasn't particularly useful. It sounds like that's where you were at back when you posted this. But anything more recent consistently hangs or crashes at the loading screen.

I'm hopeful that when the Nvidia VKD3D heap support gets fully implemented this will get fixed.

Fflshy1337 2026-09-03 github

Another instance of this, resolved down to the exact entry point. It is the same defect
as #2785 one interface level up: ID3D12DeviceExt2 slot 15,
GetCudaIndependentDescriptorObject, which ReShade's add-on build does not hook and
therefore does not convert its rewritten descriptor handle back on.

Environment

Arch, kernel 7.1.11, RTX 5070, driver 610.57.04. ReShade 6.8.0 add-on build proxying
dxgi.dll. Reproduced on Proton Experimental, Proton 11.0 and GE-Proton10-34, and in
a headless test harness with no game at all.

Where it faults

.pdata lookup in the exact d3d12core.dll the prefix loads (Proton Experimental,
md5 1fcaba68…): the faulting address +0x3AEF9C falls inside the function at RVA
0x3AEEC0, at +0xDC:

1cb13ef99:  4c 01 c8        add    %r9,%rax
1cb13ef9c:  f6 00 01        testb  $0x1,(%rax)     <== faulting instruction

The strings that function addresses name it:

'pNext not supported.'
'd3d12_device_vkd3d_ext_GetCudaIndependentDescriptorObject'
'Unsupported object type %d'

That instruction is libs/vkd3d/device_vkd3d_ext.c:631:

desc = d3d12_desc_decode_va(params->desc);
if (!(desc.view->info.flags & VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW))
    return E_INVALIDARG;

VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW is bit 0 at offset 0 of the metadata struct, and
params->desc is the incoming D3D12_CPU_DESCRIPTOR_HANDLE.ptr at offset 0x10 of the
params struct — the mov 0x10(%rsi),%rdx two instructions earlier. d3d12_desc_decode_va
is pure bit arithmetic on that value with no loads in between, so a handle vkd3d did not
mint decodes to an arbitrary pointer and the deref faults. Exactly the shape Saancreed
described in #2785 for slots 7/8, where the observed view pointers were non-NULL and
unreadable.

On Proton 11.0's build the same function is at +0x394D59; I resolved that one the same
way and it is the same function.

Confirming the path rather than inferring it

VKD3D_CONFIG=no_nvx clears VK_NVX_binary_import and VK_NVX_image_view_handle, so
supports_cubin_64bit is false and the function returns E_NOTIMPL at its first check.
With that set there is no fault at all — NGX simply reports 0xBAD00007 NotInitialized.
VKD3D_CONFIG=descriptor_heap did not take effect on this driver, so the validated heap
branch was never exercised.

It is not any one add-on

Same game, same model, three unrelated DLSS suppliers driving the neural-rendering pass:

supplier author result
dlss5-bridge 1.4.3 NIGos 21600 frames, then faults when the NR pass is switched on
renodx-dlssfix clshortfuse faults on create
DLSS5-Feeder 0.12.0 jlrouzies-fr 3600 frames, then faults when the NR pass is switched on

Different architectures, same 0xC0000005 at the same trigger. The control: with no
ReShade in the prefix at all
(OptiScaler in a D3D12 game with its own DLSS), the same
NR model on the same driver runs the pass indefinitely with no fault.

The ReShade side

crosire's fix for this interface is 50319382 ("Add support for ID3D12DeviceExt2 from
vkd3d"), which hooks slots 14 and 15 and applies convert_to_original_cpu_descriptor_handle.
It is not in any build I can obtain:

  • ReShade 6.8.0, the current release: strings shows only
    ID3D12DeviceExt::GetCudaSurfaceObject/GetCudaTextureObject and the ID3D12DeviceExt2
    variants of those two — no GetCudaIndependentDescriptorObject, no
    GetCudaMergedTextureSamplerObject.
  • The nightly built from main on 2026-09-02 (nightly.link, crosire/reshade, workflow
    build): same four strings, same omission. I ran it in the harness and it faults
    identically.
  • The RenoDX ReShade build linked from their Discord: artifact expired, 404.

crosire/reshade has issues disabled, so this is the closest place to record it.

Offer

The reproduction here is headless and scripted — a full cycle is about 40 seconds in
ngxGym, with no game needed, and I have Proton
Experimental, 11.0, 10.0 and GE-Proton10-34 installed. If a vkd3d patch that validates
the legacy branch the way the heap branch does at lines 612-619 is worth measuring, or a
ReShade build with those hooks turns up, I can run either the same day and post logs.

Full write-up, disassembly and the logs behind the table:
happy to attach them here if useful.

Fflshy1337 2026-09-04 github

Follow-up: not a vkd3d bug. Retracting the analysis in my previous comment.

I reported the fault inside d3d12_device_vkd3d_ext_GetCudaIndependentDescriptorObject and suggested vkd3d might validate the handle before decoding it. That check would still be cheap insurance, but the defect is upstream in ReShade, and I have the experiment to show it.

ReShade's add-on build replaces D3D12 CPU descriptor handles with synthetic ones and converts them back inside its hooks. Since 50319382 — which is in the 6.8.0 release, not just master — it also hooks ID3D12DeviceExt2 slots 14/15, by patching the shared vtable of the vkd3d device object. Every caller of slot 15 therefore runs through:

const size_t heap_index = (handle.ptr >> heap_index_start) & 0xFFFFFFF;
assert(heap_index < _descriptor_heaps.size() && _descriptor_heaps[heap_index] != nullptr);
return { _descriptor_heaps[heap_index]->_orig_base_cpu_handle.ptr + (handle.ptr & ...) };

with no runtime check; the assert is compiled out. When NGX passes a genuine VA-encoded handle, this decodes garbage, reads _descriptor_heaps out of bounds and hands vkd3d a bad handle. d3d12_desc_decode_va then does exactly what it should with the value it was given, and the deref faults.

Evidence — I blinded ReShade's IID_ID3D12DeviceExt2 constant by one byte so its QueryInterface no longer matches and slots 14/15 stay unhooked. Same bench, same scenario, only dxgi.dll differing:

DLSS 5 add-on in use stock ReShade 6.8.0 IID Ext2 blinded
renodx-dlssfix fault at feature create features created at three resolutions, 12000+ frames, no fault
renodx-dlss5 create ok, fault at evaluate fault at create
renodx-dlss5 fed by DLSS5-Feeder instead of the bridge 3600 frames, fault at evaluate the add-on unhooks and unregisters itself during create

Note on the first row: renodx-dlssfix carries no neural rendering at all (its binary has no NR code — only DLSS/DLSS_G/DLSS_RR presets), so that row shows plain DLSS surviving slot 15, not a working neural pass. No combination we have tried puts DLSS 5 neural rendering on screen through ReShade.

Same fault address throughout. The second row shows slot 15 receives handles of both kinds in one session — some rewritten by ReShade, some not — which is why blinding the hook is not a general fix either; the converter simply has to check whether the handle is its own.

DLSS 5 neural rendering does reach vkd3d correctly; an interposer was corrupting the handle on the way in. Feel free to close this unless you want the defensive check on the vkd3d side anyway.

dlss5-linux-reshade-hook.zip

Jjp7677 2026-09-04 github
Fflshy1337 2026-09-04 github

Thanks — I tested it. It does not change this crash, and I think the reason is that the corruption happens before dxvk-nvapi is reached.

I took the CI build of that branch (dxvk-nvapi-llvm from run 33677251803, d3d12-private-data-storage) and dropped nvapi64.dll into both the Proton runtime and the prefix, then ran four configurations. renodx-dlss5 is the neural consumer in all of them; the fault address is identical throughout (d3d12core.dll +0x3AEF9C on Proton Experimental, +0x394D62 on Proton 11.0):

nvapi ReShade bridge unwrap result
PR 391 stock 6.8.0 1 feature created, 0xC0000005 at evaluate
PR 391 stock 6.8.0 0 feature created, 0xC0000005 at evaluate
PR 391 IID_ID3D12DeviceExt2 blinded 0 0xC0000005 at create
stock stock 6.8.0 1 identical to row one

The path is: NGX → NvAPI_D3D12_GetCudaIndependentDescriptorObject → ID3D12DeviceExt2 slot 15 → vkd3d. The handle is already wrong when dxvk-nvapi receives it, because ReShade patches the shared vtable of the vkd3d device object as soon as anything queries IID_ID3D12DeviceExt2 through its proxy device, and its hook runs every handle through

const size_t heap_index = (handle.ptr >> heap_index_start) & 0xFFFFFFF;
assert(heap_index < _descriptor_heaps.size() && _descriptor_heaps[heap_index] != nullptr);   // compiled out in release
return { _descriptor_heaps[heap_index]->_orig_base_cpu_handle.ptr + (handle.ptr & ...) };

with no runtime check. Handles that ReShade itself rewrote convert correctly; genuine VA-encoded ones decode to a garbage heap index, read _descriptor_heaps out of bounds, and vkd3d faults on the first dereference of what comes back. Both kinds reach that hook in one session, which is why blinding the hook only moves the fault from evaluate to create, and why the caching change in PR 391 cannot help: whoever created the wrapper, the call still lands on the patched vtable entry.

So this is a ReShade bug — convert_to_original_cpu_descriptor_handle has to verify the handle is its own and pass it through otherwise. Sorry for the noise on your side; I only mention it here because your suggestion sent me to test it, and the negative result seemed worth recording.

dlss5-linux-reshade-hook.zip

Jjettoblack 2026-09-06 github

Using https://github.com/jp7677/dxvk-nvapi/pull/391 + https://github.com/crosire/reshade/pull/435 + a recent master build of vkd3d-proton with VKD3D_CONFIG=descriptor_heap, I finally have Cyberpunk running stable with Reshade + DLSS 4.5 + FG. It took all of those together to make a difference. I can't say it's 100% stable (the game has never been 100% stable, often mod-related issues), but I was able to go from 1-2 minutes before a crash, to well over 1hr+ of gameplay with no Reshade-related crashes. I haven't tried it with DLSS 5.

NVIDIA driver 610.57.04
proton-cachyos-11.0-20260703 + vkd3d-proton @ 35bdee14 + https://github.com/jp7677/dxvk-nvapi/pull/391
cachyos with kernel 7.2.3-1