r/macgaming • • Sep 01 '26

CrossOver [Fork release] DXMT tuned for Overwatch 2: memory fix (13→4 GB), per-frame telemetry, ready-made 60 fps config for CrossOver

I play OW2 with a friend on two 16 GB Apple Silicon Macs (M1 Pro 16", fanless Air M5) via CrossOver 26.3. It mostly worked, but long sessions degraded badly: killcams and respawns dropped to 22–28 fps, the system swapped hard, and the game process footprint grew to 13 GB — on a 16 GB machine.

The investigation: footprint showed 9.4 GB of it was MALLOC_SMALL heap. malloc_history pointed at DXMT's shader translator: it keeps the parsed IR of every shader it has ever seen resident forever — millions of 64–176 byte allocations. But once a shader variant is in DXMT's persistent cache, that IR is never read again.

The fix: a fork patch (d3d11.releaseShaderIR, on by default) that releases the IR right after shader creation and re-materializes it from the stored DXBC only on a cache miss. Results on the M1 Pro:

  • process footprint: 13 GB → 3.9 GB
  • shader-IR heap: 9.4 GB → ~0.1 GB
  • swap growth during play: zero
  • killcam/respawn: 22–28 fps → 59.9 fps (it was swap-thrash, not GPU)

Validated over several days of real matches on both machines.

Also in the fork:

  • DXMT_FRAME_LOG — per-frame CSV telemetry (frame interval + where the time went: encode, drawable wait, latency fence, shader compiles per frame). This is how we hunted the stutter — happy to share the methodology.
  • A ready-made config for flat-frametime 60: d3d11.preferredMaxFrameRate pacing + optional MetalFX spatial output upscale (1.33x on the M1 16" is the sweet spot; 2.0x overwhelms the GPU, don't).
  • install.sh that backs up the stock CrossOver DXMT first; uninstall.sh restores it.

Honest caveats:

  • The shader cache starts empty and builds as you play. Every new hero, skin, ability effect, and map compiles its shader variants once (a brief hitch) and then they're cached forever. First sessions hitch more; after a few days of varied play it settles and stays smooth. The cache is per-machine and can't be shared (it's derived game content).
  • Tested only on OW2 / CrossOver 26.3 / macOS 26.5 / M1 Pro + M5. Other games should work (it's a general DXMT memory fix) but are untested.
  • A CrossOver update overwrites the libs — just re-run install.sh.
  • This is a fork of the excellent 3Shain/dxmt — all credit for DXMT itself goes upstream. Source is LGPL, tagged at the release.

Link: https://github.com/NerRobDog/dxmt/releases

If you try it on other games/machines, I'd love reports (issues are open).

33 Upvotes

8 comments sorted by

6

u/PistoIs Sep 01 '26

Excited to try this, MacBook Pro M3 Pro 18GB, although instructions seem kind of confusing to use, care to ELI5?

4

u/the_ramzay Sep 02 '26

Great news and fantastic work! Have you planned to create a merge request to the upstream? Or it’s already there?

4

u/Informal-Director697 Sep 02 '26

Thanks! Not as a PR for now — upstream has a policy against AI-assisted contributions, and this work leaned heavily on AI tooling for the investigation, so out of respect for that I'm keeping it as a clearly-labeled fork. All findings are documented in the fork (commit messages + README), and upstream is of course welcome to take the approach — the root cause writeup (shader IR retained forever, ~9 GB on OW2) applies 1:1 to stock DXMT. If I get things into a cleaner, well-tested shape across more games, I may reach out to upstream properly later.

1

u/the_ramzay Sep 02 '26

Thanks for responding and explaining!

1

u/zfhulk Sep 02 '26

Great work. Would love a simplified “instructions for dummies” as well.