Same here, could workaround that with launch options:
SteamDeck=1 %command%
Same here, could workaround that with launch options:
SteamDeck=1 %command%
works, however, the game does not properly capture the mouse cursor, so the cursor moves outside the window during gameplay
Try -noprefetch -nointro
Another thing to consider: for me "New Game" or loading a saved game worked very unstable on Proton Experimental but it's pretty stable on Proton 7.0-6 (tested w/ same SteamDeck=1 %command% launch options). I don't see more similar reports anywhere so may be something with my hardware/setup.
I have error D3D12_0 on my system. I have RTX 4070 Super. Is there any way to fix the issue?
@dmknght Hi there.
Please attach a Proton log from a time the game is having issues. You can make one by running the game with PROTON_LOG=1 %command% in the games launch options. A log named steam-2427430.log should appear in your users home folder.
Tried installing to see log and it worked today. Idk why but few weeks ago I installed newer Lutris version to play D2R (Diablo 2 remastered version) which has the same D3D12 issue. That installation upgraded a lot of wine runtimes. IDK if It changed Steam's proton too.
correction: the explanation below is wrong, see my follow up. the engine never queries NV12 and the missing format is not the trigger. leaving the text for the record.
the borked videos have a root cause. i chased it on a different wine stack (macos, d3dmetal for d3d12) that shows pixel-identical corruption to the screenshots above, and the mechanism is shared.
what it is not: wine's media stack. the EE plays its intro mp4s with a decoder built into xrEngine.exe, console-port heritage. with every plausible media channel traced (mfplat, quartz, msvideo, avifile, wmvcore), the intro plays corrupted while all of them stay silent; the only media foundation call the game ever makes is MFStartup, and the only video format guid in the whole binary is NV12. audio from the same mp4 plays perfectly through the same in-engine path. the decode is fine.
what it is: the engine checks d3d12 NV12 texture support before choosing its video upload path. on windows every driver says yes. on my stack, CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT) returns support1=0 for NV12, P010, YUY2, AYUV and 420_OPAQUE, and unless vkd3d-proton answers differently (i could not test that half, but multi-plane video formats have been a known gap there) proton lands in the same place. with NV12 refused, the engine falls into a fallback upload path that no windows machine ever executes, and the fallback has a stride bug: it writes tightly packed rows into a destination with twice the pitch. that is exactly what the screenshots show. each output row holds two consecutive source rows, so the frame appears as two side-by-side copies squeezed into the top half, and chroma gets sampled from luma bytes, which tints dark scenes olive and bright highlights purple.
so: a game bug in dead-on-windows fallback code, surfaced by a real capability gap. the -nointro workaround stands. the actual fixes are gsc repairing the fallback stride math, or vkd3d-proton growing NV12 sampling support so the fallback never runs at all.
verification for the proton half, if someone with a linux box cares to close the loop: create a d3d12 device and call CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT) for DXGI_FORMAT_NV12. on windows hardware support1 comes back with TEXTURE2D and SHADER_SAMPLE set; my prediction for proton is 0.
correcting myself: my NV12 explanation above is wrong. please disregard it.
i built a d3d12 interposer to act on that theory, and instrumenting the engine's real calls killed it. across full intro playbacks, xrEngine never queries CheckFeatureSupport(FORMAT_SUPPORT) for NV12 at all, and never creates an NV12 resource. so nothing is gated on that capability and the missing format is not what triggers the corruption. i also had the interposer claim NV12 as supported, which changed nothing on screen, exactly as it should not have.
what the instrumentation does show about the video path, on my macos/d3dmetal stack:
DXGI_FORMAT_B8G8R8A8_UNORM textures at 3840x2160, double buffered. the engine decodes to bgra itself, no yuv surface is involved anywhere.CopyTextureRegion from a staged upload buffer, PLACED_FOOTPRINT, format bgra8, 3840x2160, RowPitch=15360. that is exactly 3840*4 and correctly 256 aligned, so the engine declares a valid tightly packed layout.so the remaining question is narrower than what i posted: whether the bytes the engine staged in that buffer actually match the 15360 pitch it declared. if they do, the upload is right and the fault is downstream of it. if they do not, the engine staged a half stride frame. i am chasing that next and will report what the dump says rather than another theory.
what still holds from before: the decoder is built into xrEngine, not media foundation. i traced mfplat, quartz, msvideo, avifile and wmvcore through a corrupted playback and the only call the game makes is MFStartup, while audio from the same mp4 is perfect. and -nointro remains the workaround.
sorry for the noise. i should have instrumented before posting a mechanism.
superseded, see https://github.com/ValveSoftware/Proton/issues/8717#issuecomment-5291342666. the missing interface is right but the reason is wrong: the engine never asks for decode, only for
D3D12_FEATURE_VIDEO_PROCESS_SUPPORT. what is needed is the video processor, not a decoder.
found it, and this time it is measured end to end rather than inferred.
the engine asks for ID3D12VideoDevice and does not get it. interposing the d3d12 device and logging QueryInterface through an intro playback:
device QI {1f052807-0b46-4acc} -> 0x80004002 REFUSED
that iid is IID_ID3D12VideoDevice (1f052807-0b46-4acc-8a89-364f793718a4). xrEngine EE wants gpu video decode, the implementation does not expose it, and the engine drops to a software path whose output is wrong. vkd3d-proton does not implement ID3D12VideoDevice either, which is why this reproduces identically on both stacks and never on windows, where the interface exists.
what the broken fallback actually produces, dumped straight out of the staging buffer before any gpu work touches it:
R8G8B8A8_UNORM texture, one CopyTextureRegion per frame, and only the top left 1920x1080 is populated, for a video whose real size is 3840x2160. so the fallback decodes at half resolution.V, U, Y, A, that is packed AYUV, not rgb. sampled across the populated area: R is 128 and G is 128 everywhere, B carries the picture, A is 255. the chroma is pinned neutral, so the fallback also loses colour entirely.displayed raw, (128, 128, luma) is exactly the olive cast everyone sees, and bright areas become (128, 128, high) which is the purple. the two side by side copies come from the same mismatch, the engine sizing its sampling for a 3840x2160 video while the surface holds a 1920x1080 one.
so the corruption is entirely upstream of the graphics stack. i verified the parts people would reasonably suspect and they are all clean on my end: the staged bytes for the menu background render perfectly, and a buffer to BGRA CopyTextureRegion at 3840x2160 with RowPitch=15360 reads back with 2160 of 2160 rows exact.
for whoever picks this up: implementing ID3D12VideoDevice in vkd3d-proton would fix it properly, since the engine only takes the broken path when the interface is missing. failing that it is a gsc bug in a fallback that no windows machine ever executes. -nointro remains the workaround.
this supersedes both of my earlier comments. the first blamed NV12 texture support, which was wrong; the engine never queries any format support at all, i logged every CheckFeatureSupport call to be sure. the missing capability is the video device interface, not a texture format.
correcting myself once more, and this time with a working fix behind it rather than a theory. my last comment said the engine wants ID3D12VideoDevice for gpu decode. that is the wrong target, and anyone acting on it would build the wrong thing.
the engine does not want the decoder. it wants the video processor.
i implemented ID3D12VideoDevice on my macos/d3dmetal stack to find out what xrEngine actually does with it. the answer is that it makes exactly one call:
device QI {1f052807-0b46-4acc} -> our video device
video CheckFeatureSupport feature=5 size=608
feature 5 is D3D12_FEATURE_VIDEO_PROCESS_SUPPORT. no decoder, no decoder heap, no DecodeFrame, no bitstream buffer, ever. the engine decodes h264 itself, in engine, and only wants d3d12 to convert the result.
an important detail for whoever implements this: my first build implemented the decode side properly and returned E_INVALIDARG for the one feature it did not recognise. the engine asked that single question, got a failure, and went straight back to the broken fallback without another call. a video device that answers feature 5 with a failure is indistinguishable from no video device at all.
the full negotiation, once feature 5 is answered as supported:
CreateVideoProcessor 1 input stream, out fmt=28 cs=0
in 0 fmt=103 cs=9 src 64x64..3840x2160 dst 64x64..3840x2160
field=0 deint=0 past=0 future=0 alpha=0 auto=0
ProcessFrames processor=... streams=1
out tex=... sub=0 target=0,0..3840,2160
in 0 tex=... sub=0 src=0,0..3840,2160 dst=0,0..3840,2160 orient=0 flags=0x0
so the whole requirement is: NV12 (fmt=103) in, R8G8B8A8_UNORM (fmt=28) out, 1:1 at the source resolution, one input stream, no scaling, no filters, no deinterlace, no past or future reference frames, alpha fill opaque. the engine uploads both planes itself, sub=0 as R8 and sub=1 as R8G8 at half size, so it is a plain two-plane colour conversion. i implemented it as a fullscreen pass sampling both planes with the matrix from the declared colour space, and the intro then plays correctly at the full 3840x2160.
that also fixes the resolution, not just the colour: the broken fallback decodes at 1920x1080 into a 2048x2048 texture, which is where the two side by side copies come from. the gpu path runs the real 4k.
one caveat worth knowing: the engine declares cs=9, YCBCR_FULL_G22_LEFT_P709, but the files are yuv420p(tv, bt709), studio range. obeying the declaration the way a driver should leaves black at 16 and the video visibly washed out. i default to treating it as studio and keep the literal behaviour behind an option.
for vkd3d-proton this is a much smaller job than the decoder i pointed at before: ID3D12VideoDevice answering VIDEO_PROCESS_SUPPORT, CreateVideoProcessor, a VIDEO_PROCESS command list, and ProcessFrames doing a YUV to RGB blit. no bitstream parsing, no DPB, no DXVA structures. that would fix this game on linux properly, and -nointro stops being needed.
proton 7.0-6x1 2025-05proton experimentalx1 2025-05PROTON_LOG=1x1 2025-10SteamDeck=1 %command%x3 2025-050x80004002x1 2026-08
Compatibility Report
System Information
I confirm:
Symptoms
The game starts on a black screen, then shows an error report dialogue
Reproduction
Start the game, wait until the error pops up
steam-2427430.log