Skip to content

fix(dxvk): remove stale native dxgi.dll left by a DXMT launch - #253

Merged
frankea merged 1 commit into
mainfrom
fix/dxvk-stale-dxmt-dxgi
Sep 1, 2026
Merged

fix(dxvk): remove stale native dxgi.dll left by a DXMT launch#253
frankea merged 1 commit into
mainfrom
fix/dxvk-stale-dxmt-dxgi

Conversation

@frankea

@frankea frankea commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Problem

enableDXMT deploys a native dxgi.dll into the bottle's system directories. DXVK ships no dxgi.dll, so enableDXVK never replaces it, and after a switch from DXMT to DXVK the bottle pairs DXVK's d3d11 with DXMT's dxgi under the n,b override. That mix cannot create window swapchains: Chromium clients log SwapChain11.cpp:636 ... HRESULT: 0x887A0004 and eglCreateWindowSurface: EGL_BAD_ALLOC, and the Steam client runs with no window at all. Combined with the resolver gap fixed in #252 (first launch of a launcher auto-picks DXMT on payload-less runtimes), this is why a default-install Steam bottle on the new engine line looked completely dead.

Verified bidirectionally on real bottle clones against v4.6.4-beta.1: a clean clone works, planting DXMT's dxgi.dll into system32 reproduces the failure on the very next launch, and restoring the builtin-marked file brings the main window back. Reproduced twice on independent clones; full investigation on #163.

Fix

enableDXVK now ends by removing a markerless (native) dxgi.dll from system32 and syswow64, letting the ,b half of the override load wine's builtin, which is the pairing DXVK is written against. Two deliberate stand-downs: builtin-marked files are never touched (wine's own fake DLL), and the removal is skipped entirely when the GPTK importer's originals/ backup exists, because the builtin is then Apple's forwarder and the prefix needs a clean native copy instead; #251 owns that case and the two changes compose.

Tests

WineDXVKResidueTests: residue removed from both arches with bystanders untouched, builtin-marked file kept, native file kept when GPTK originals exist, missing file no-op, truncated stray left alone (isNativePE fails closed). Full kit suite passes.

Part of #163.

DXVK-macOS ships no dxgi.dll, so enableDXVK never overwrote the native
copy a DXMT deploy leaves in system32 and syswow64. A DXVK launch then
paired DXVK's d3d11 with DXMT's dxgi under the n,b override, and that
mix cannot create window swapchains (DXGI_ERROR_UNSUPPORTED,
EGL_BAD_ALLOC in Chromium clients): Steam ran with no window at all
after a bottle switched from DXMT to DXVK.

Verified bidirectionally on a real bottle against v4.6.4-beta.1:
planting DXMT's dxgi reproduces the failure on the next launch and
removing it brings the window back. Details on #163.

The removal stands down when the GPTK importer's originals backup
exists, since the builtin behind the override is then Apple's forwarder
and the prefix needs a clean native copy instead (#251
owns that case). Builtin-marked files are never touched.
@frankea

frankea commented Sep 1, 2026

Copy link
Copy Markdown
Owner Author

Review notes (self-merge per the usual flow, so on the record here): the removal is scoped tight: dxgi.dll only, native-marker only, both arch directories, and it stands down whenever the GPTK originals backup exists so it cannot fight #251's originals-aware deploy; builtin-marked fakes and truncated strays survive (isNativePE fails closed, and the truncation case has its own test). The failure it clears was verified bidirectionally on real bottle clones before the patch existed: plant the DXMT dxgi, next launch hard-fails with 0x887A0004; remove it, the window returns. Full kit suite green locally and on CI.

@frankea
frankea merged commit cb67192 into main Sep 1, 2026
9 checks passed
@frankea
frankea deleted the fix/dxvk-stale-dxmt-dxgi branch September 1, 2026 05:37
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.47059% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
WhiskyKit/Sources/WhiskyKit/Wine/Wine.swift 76.47% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

dappermint added a commit to dappermint/Whisky that referenced this pull request Sep 1, 2026
enableDXVK now runs one reconciliation step instead of stacking a removal
and a deploy. Which dxgi.dll the prefix needs depends on what the builtin
is: with the D3DMetal payload deployed it is Apple's forwarder, which
DXVK's d3d11 cannot pair with, so wine's backed-up original is installed
and marker-stripped; without the payload the builtin is wine's own, so a
native copy in the prefix is DXMT residue and is removed.

The removal side is frankea#253's isNativePE-guarded both-arch helper, called
rather than reimplemented. The old else branch did a blind removeItem on
system32 only, which deleted wine's builtin-marked placeholder on every
DXVK launch (a per-launch prefix mutation wineboot just undoes) and left
syswow64 untouched, so a 32-bit title kept the bad DXVK-d3d11 plus
DXMT-dxgi pairing.

The payload predicate moves out of the removal helper and into the
caller. Keying on originals/ alone misreads the stale-store state, where
a previous engine's backups survive but the payload does not: the store
says GPTK is active while the builtin is already wine's own.

removeCleanDXGIForDXVK is dropped rather than wired into undeploy. It had
no caller, and the reconciliation step already restores the prefix on the
next DXVK launch without a second owner of that path.

deployCleanDXGI and the reconciliation step take injectable originals and
payload-state seams, mirroring removeStaleNativeDXGI, with tests covering
the deployed, not-deployed and syswow64 cases.
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.

1 participant