To play Windows games on your Apple silicon Mac, download Mach9.app from mach9.app.
A relocatable, signed Wine for games on Apple silicon Macs, made to be
embedded in a launcher. Direct3D 9 runs on
mtld3d, its own Direct3D 9 implementation,
which draws straight on Metal. The launcher configures the engine
with rules that match processes, passed in the environment variable
WINE_COMPATDB, in a file WINE_COMPATDB_FILE names, or both, so each
game gets the Direct3D implementation
(backends) and the settings it
needs. The API that writes the rules is published, so a launcher
generates them in code.
The easy way to play games on Mach9 today, until other launchers embed it. It runs D3D9 games with mtld3d, and everything else in the engine is included, so D3D10, D3D11 and D3D12 games run as well.
- Runs the Windows version of Steam, so Steam games install and start from there.
- Wine is built in: nothing else to download, no Rosetta.
- Notarized, and updates itself.
- Pick and start games from its Dock menu.
Setup and use: docs/app.md.
The app's source, and what builds and releases it, is in
launcher/ (building); the
engine does not depend on it. Each release of the engine is a release of
the app too.
A launcher that wants one game's D3D9 on wined3d, for example, sets:
export WINE_COMPATDB='exe=game.exe;d3d9=wined3d'game.exe then gets the wined3d D3D9 tree while every other process keeps
mtld3d; the format and the recipes show the rest.
- Wine is built for arm64 and runs without Rosetta. FEX runs the x86 code of Windows programs.
- D3D9 runs on mtld3d, a D3D9 on Metal, and
x87 code runs fast because FEX's reduced x87 precision is on by default
(
builtin::fex_reduced_x87_precision). - D3D10 and D3D11 run on DXMT, D3D12 on vkd3d-proton. x64 programs run as ARM64EC: Wine and the graphics stack are ARM64X and run natively, and only the game's own code is emulated. Unlike upstream FEX, our FEX runs the x86_64 code of these programs without AFP: AFP needs a floating-point mode switch at every call between x86 and native code, and measurements showed that switch costs more than AFP saves (FEX).
Other defaults that differ from Wine, besides the built-in rules
(builtin::defaults):
- msync (runtime)
- the hardware x86 memory ordering (FEX)
- the bundled Vulkan driver with its features always on (Vulkan)
- D3D12 frame latency handles released when the GPU is done (vkd3d-proton)
- Get a bundle from a
v*release (releases) or a local build (building). Builds from before the app joined the releases are thearm64-*releases. - Copy the
wine/tree into the app (bundle layout). - Sign the app without touching
wine.app(loader app). - Minimum macOS: macOS floors.
- Prefixes after an upgrade: upgrade checklist.
The rules in WINE_COMPATDB are written with the compatdb-core crate,
used at the same release as the bundle:
[dependencies]
compatdb-core = { git = "https://github.com/athei/mach9", tag = "<the bundle's v* tag>" }- The crate documentation is the spec; it has only a Rust API.
- A complete example: Quick start.
- What a launcher must do: launcher responsibilities.
- Each process logs its configuration (logging).
Variables the bundle reads besides WINE_COMPATDB:
| Variable | Explained in |
|---|---|
WINE_COMPATDB_FILE |
format, launcher responsibilities |
WINE_PROF_SERVICE |
profiler check-in |
WINEMSYNC, WINENCPU |
runtime |
FEX_HARDWARE_TSO, FEX_HOSTFEATURES |
FEX |
VK_DRIVER_FILES, VK_ICD_FILENAMES, VK_ADD_DRIVER_FILES, MESA_KK_EXPERIMENTAL |
Vulkan |
GST_PLUGIN_SYSTEM_PATH_1_0, GST_REGISTRY_1_0, each also without _1_0 |
GStreamer |
VKD3D_CONFIG, VKD3D_DEBUG and vkd3d-proton's other variables |
upstream |
WINE_D3D_CONFIG |
Rule::wined3d |
- docs/building.md: building the bundle locally.
- docs/internals.md: how the build works.
- docs/compatdb.md: how
compatdb.soapplies the rules. - docs/maintenance.md: maintaining the build.
