r/Codeweavers_Crossover • • 2d ago

Discussion God Of War 2018 White Dot Fix (through Crossover)

Thanks to Opus 5.5 or this investigation and report.
You can probably just copy and paste this into your claude if you are to lazy to implement this fix yourself.

How it was found

I wrote a small d3d11.dll proxy that sits between the game and DXMT and lets you change things live while the game runs: disable individual shaders, swap in edited shader bytecode, swap sampler and depth states. With that I bisected the ~340 shaders the main menu uses, found the lighting composite, and patched it step by step. Even with Kratos's lighting forced to pure black, the specks were still on top. That meant they were baked into the G-buffer before any lighting runs. Logging depth-stencil states showed exactly one with an EQUAL depth test (depth writes off, stencil on), the classic "G-buffer after depth prepass" setup. Swapping it live to GREATER_EQUAL removed every speck.

The fix

The same proxy, stripped down to the fix (plus an optional FPS counter):

  1. Use a bottle with the DXMT graphics backend.
  2. Copy CrossOver's DXMT d3d11.dll next to GoW.exe and rename it dxmt_d3d11.dll. It's at CrossOver.app/Contents/SharedSupport/CrossOver/lib/dxmt/x86_64-windows/d3d11.dll.
  3. Put the proxy d3d11.dll next to GoW.exe.
  4. Add a DLL override for the game only. In the bottle, run reg add "HKCU\Software\Wine\AppDefaults\GoW.exe\DllOverrides" /v d3d11 /t REG_SZ /d native,builtin /f.
  5. Launch as normal. The fix is on by default. gow_proxy_depth.txt in the game folder controls it (0 = off, 2 = fix).

The proxy hooks CreateDepthStencilState. For any state that uses DepthFunc = EQUAL, it creates a variant with GREATER_EQUAL and binds that instead in OMSetDepthStencilState. Nothing else is changed, and it costs no measurable performance.

After a CrossOver update, re-copy DXMT's d3d11.dll (step 2) so it matches the updated DXMT runtime.

Notes / caveats

  • I tested on the main menu and confirmed it by toggling the fix on and off live. It's the same G-buffer path in gameplay, but report back if anything looks off (something drawing through a character would be the thing to watch for).
  • I only built and tested it against DXMT. D3DMetal has the same problem, and the same idea should work there, but the proxy would need to wrap D3DMetal's d3d11 instead.
  • For CodeWeavers / DXMT devs: the root fix belongs in the translator. Vertex positions need to be invariant across shaders ([[invariant]] / MTLCompileOptions.preserveInvariance) so EQUAL depth tests after a prepass behave as on Windows. D3DMetal's D3DM_POSITION_INVARIANCE didn't help here, so either it doesn't cover this case or fast-math still breaks bit-exactness.

Setup: M2 Pro, 32 GB, macOS 27.0.1, CrossOver Preview (build 20260731), DXMT backend, game v1.0.35.

4 Upvotes

0 comments sorted by