Skip to content

About

Arm64 / Arm64EC / Aarch64 / x86_64 / I386 & WOW64 Wine With FEX For MacOS Silicon on MacOS 26.4+

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

47 stars

Watchers

0 watching

Forks

MetalSharp Wine

MetalSharp Wine

Release License: AGPL-3.0


Developer Notice: This project is in an early access state, especially concerning d3d12 pipelines such as Vkd3d-proton and Mullion. If you experience an issue in-game with either pipeline, please report them upstream to their respective repo's. VKD3D-Proton-MacOS is MetalSharp code and can be found under the MetalSharp Github Organization. Other issues may occur. If you believe it to be a wine issue, please report your issue to this repo instead. MetalSharp Wine 5.0 is focused on the respective elements as a whole;

  • D3D12 with VKD3D-Proton / Mullion in a stable state with playable frame-rates.
  • Games with Auth succeeding updates (Such as Assassin's Creed Odyssey)]
  • Fullscreen bug when playing with DXVK
  • Faster x86 FEX Emulation
  • More Wine Arm64EC bug fixes (Emulation overhead, process management, lifecycle management, and general bug fixes)

MetalSharp Wine is Wine 11.20 built as a native arm64 macOS application for Apple Silicon. A FEX-Emu fork translates x86 Windows code to ARM64. In its current state it doesn't run as a plain double-click .app: you run it from Terminal, like Sikarugir.

  • No Rosetta: none of it is x86 code run through Rosetta.
  • No hardware TSO: FEX emulates the x86 memory model with ordinary ARM64 instructions.

It runs ARM64, x86_64 and 32-bit x86 Windows programs, with Direct3D 9 through 12 and OpenGL 4.6 on Metal. It needs macOS 15 or later; i386 needs macOS 26.4 or later.

Windows code How it runs
ARM64 (aarch64) natively
x86_64 FEX through ARM64EC (libarm64ecfex.dll); Wine's own DLLs are native ARM64X hybrids
i386 FEX through WoW64 (libwow64fex.dll), in the signed app (cross-architecture entitlement: low 4GB, 4K pages)

Download

Releases has:

  • MetalSharp-Wine-<version>-arm64.zip: the signed and notarized MetalSharp-Wine.app. Use this one; i386 and 4K pages need it.
  • metalsharp-wine-<version>-arm64.tar.xz: the same Wine as a relocatable folder (bin/wine). It is ad-hoc signed, so x86_64 and ARM64 only, with 16K pages.

Use It:

It's a lot like Sikarugir in its current state until it is included with MetalSharp where it's just a 'Play' option inside the launcher.

  1. Download the .zip and move the .app from inside into /applications.

Terminal Commands:

  1. First point a shell variable at the Wine Inside the app:

export WINE=/Applications/MetalSharp-Wine.app/Contents/MacOS/wine

  1. Create a prefix:

WINEPREFIX=~/Games/my-prefix $WINE wineboot -i

(It takes a minute the first time. The prefix comes with Wine Mono (.NET), Gecko and the core fonts already set up, and x86 programs run through FEX automatically).

  1. Run an installer or game by passing the .exe path:

WINEPREFIX=~/Games/my-prefix $WINE ~/Downloads/setup.exe

WINEPREFIX=~/Games/my-prefix $WINE "C:\\Program Files\\MyGame\\Game.exe"

4.1) Running from inside the game’s folder also works and helps some games find their files:

cd ~/Games/my-prefix/drive_c/Program\ Files/MyGame && WINEPREFIX=~/Games/my-prefix $WINE Game.exe

  1. For Steam: run SteamSetup.exe (from Valve, or share/metalsharp/steam inside the app) the same way, then start Steam with:

WINEPREFIX=~/Games/my-prefix $WINE "C:\\Program Files (x86)\\Steam\\steam.exe"

  1. Useful switches, set before the $WINE command like WINEPREFIX:
  • Direct3D: Mullion on Metal is the default. For x86_64 games, GRAPHICS_BACKEND=dxvk uses DXVK-macOS (D3D9/10/11 on MoltenVK) and GRAPHICS_BACKEND=vkd3d uses VKD3D-Proton (D3D12 on MoltenVK). GRAPHICS_BACKEND=wine uses Wine’s own wined3d.
  • VKD3D-Proton: run it with WINEDEBUG=-all. With Wine's default debug channels, device creation can fail ("Lacking support for single texel alignment").
  • OpenGL: WineMetalGL 4.6 is the default. OPENGL_BACKEND=wine switches back to Wine’s own.
  • Sync: msync is on by default and is much faster than going through the wineserver. WINEMSYNC=0 turns it off.
  • Memory ordering: FEX runs x86 code with its TSO emulation on by default, which games that hand data between threads with plain stores need (Red Dead Redemption 2 hangs without it). FEX_TSOENABLED=0 turns it off, which is faster for programs that don't need it.
  • x87: 32-bit programs run x87 floating point in double precision by default, as under Rosetta; full 80-bit emulation is much slower (it made Ori's FMOD audio stutter). FEX_X87REDUCEDPRECISION=0 restores full precision for a program that needs it.
  • Mouse: setting UseGCMouse to N (in HKCU\Software\Wine\Mac Driver) goes back to the old mouse input path if GCMouse raw input misbehaves in a game.
  • Settings: WINEPREFIX=~/Games/my-prefix $WINE winecfg opens Wine’s settings.

What's included

Area Details
Direct3D 10/11/12 Mullion (DXMT fork) on Metal, the default. ARM64X, so native ARM64 and x86_64 programs use one build; there's also an i386 build (D3D10/11). GRAPHICS_BACKEND=wine selects wined3d
Direct3D 9/10/11 (opt-in) DXVK-MacOS 3.1 (metalsharp/DXVK-MacOS, DXVK 3.1.1 ported to MoltenVK), built as ARM64X and run by x86_64 programs as ARM64EC under FEX: GRAPHICS_BACKEND=dxvk
Direct3D 12 (opt-in) VKD3D-Proton for macOS (metalsharp/VKD3D-Proton-MacOS), ARM64X, with DXVK 2.7.1's DXGI and D3D10/11 for swap chains and D3D11On12, on MetalSharp's MoltenVK: GRAPHICS_BACKEND=vkd3d (x86_64 programs; D3D9 there comes from DXVK-macOS). Apple's Metal Shader Converter turns its compute shaders, and pipelines of a vertex and a pixel shader, into Metal libraries directly; shaders a game's quirks change and pixel shaders with wave operations stay on SPIR-V (METALSHARP_MSC=0 turns the converter off, METALSHARP_MSC=compute keeps it to compute)
Tracing MULLION_TRACE_<CATEGORY>=1 or heavy (Mullion: gpu, sync, resource, memory, shader, present, pass, api, cpu) and METALSHARP_TRACE=<category>[+heavy] (VKD3D-Proton and MoltenVK) write a log per game: ~/Library/Logs/Mullion/<exe>/mullion.log, and vkd3d.log and moltenvk.log in ~/.metalsharp/logs/trace/<exe>/
Shader compilers Microsoft's DXC 1.9 (dxcompiler.dll, dxil.dll; ARM64 and x86) and the ARM64 d3dcompiler_47.dll are installed into every prefix, for programs that compile HLSL at run time
OpenGL WineMetalGL 3.7.0 (OpenGL 4.6 on Metal), the default. OPENGL_BACKEND=wine selects Wine's own
Vulkan MoltenVK 1.4.3 (MetalSharp build from VKD3D-Proton-MacOS: the pipeline cache is saved during long compiles and keyed on the shader sources, and compiled Metal libraries and binary archives are cached)
Media FFmpeg 8.0 (LGPL, VideoToolbox/AudioToolbox) and GStreamer 1.26
.NET / HTML Wine Mono 11.3.0 (arm64, x86, x86_64) and Wine Gecko 2.47.4 (x86, x86_64)
Sync msync (shared-memory synchronization; on by default, WINEMSYNC=0 turns it off)
Fonts Metric-compatible Arial, Times New Roman and Courier New files (renamed Liberation) in every prefix's C:\windows\Fonts. CJK Windows families are mapped to the macOS system fonts
Controllers winebus with SDL2 and IOHID (XInput and DirectInput)
Tools innoextract 1.9 (Inno Setup / GOG installers) and cabextract 1.11
Compatibility WineForge's launcher fixes (Steam, Epic, EA, Ubisoft, Battle.net, Rockstar), PE patches and the native Steam bridge. Rockstar's launcher runs on Mullion with WFDXCompat's launcher companion. HideWineExports hides Wine from programs that refuse to run under it (the PlayStation PC SDK in Sony's ports)
Fullscreen and mouse WineForge's native macOS fullscreen (macOS 27: fullscreen games get their own Space, and cursor confinement survives switching apps) and GCMouse raw input (Elvin Hayatov's WineHQ MR !11799), with MetalSharp's fix-up: raw GCMouse moves the game hasn't read yet are summed, like ordinary mouse moves, instead of costing a wineserver round trip at every report of a high-polling-rate mouse (Wine patches 0038, 0039, 0065)
App bundle Developer ID signed, hardened and notarized, with the cross-architecture entitlement. Windows programs run in an inner loader bundle (lib/wine/aarch64-unix/wine.app) that carries the provisioning profile, so they get 4K pages and the low 4GB
MetalSharp app payloads share/metalsharp/: Goldberg, the Steam installer and wrapper, FNA/XNA, fnalibs, the FNA kickstart, Unity Mono runtimes, SDL3, shims, Terraria launchers, CEF hooks, dxmt.conf, compat rules, the host runtime, and Microsoft's unmodified VC++ 2015-2022 and core-fonts installers

Results and design notes are in docs/STATUS.md; measured performance is in docs/PERFORMANCE.md.

Source

The modified sources are kept in this repository as branches, and main links them as submodules in src/, pinned to the commits each release is built from:

Submodule Branch Contents
src/wine source/wine Wine 11.20 + WineForge + MetalSharp (wine-11.20 tag plus 77 commits)
src/FEX source/fex FEX-2610 + MetalSharp (22 commits). It is not upstreamed
src/winemetalgl source/winemetalgl WineMetalGL's arm64 Wine module
src/wfdxcompat source/wfdxcompat WineForge DXCompat, built ARM64EC for Mullion: the Rockstar launcher companion
src/mullion aaf2tbz/mullion metalsharp-2.1 Mullion (DXMT fork). Developed there and sent upstream to dttdrv/mullion as pull requests
src/dxvk-macos metalsharp/DXVK-MacOS main DXVK-MacOS 3.1, DXVK 3.1.1 ported to MoltenVK: the GRAPHICS_BACKEND=dxvk lane, built as ARM64X
src/vkd3d-proton metalsharp/VKD3D-Proton-MacOS main VKD3D-Proton macOS: the GRAPHICS_BACKEND=vkd3d lane (D3D12 on Vulkan, with DXVK's DXGI and D3D10/11) and MetalSharp's MoltenVK, as patches on the upstream projects

The branches are full source trees with their upstream history (Wine's is large), which is why they are linked rather than merged into main. legacy-1.x holds the previous MetalSharp Wine (VKMT) history.

The same changes are in patches/ as git patches against the upstream tags. patches/wine/0042 is a pointer to WineForge's Steam bridge commit, because that commit vendors about 66 MB.

Path Contents
scripts/ Build, staging, test, audit, benchmark, packaging and signing scripts
patches/ wine/, fex/, mullion/, winemetalgl/
resources/ The app icon (MetalSharp-Wine.icon, an Icon Composer document)
tests/src/ Smoke tests and benchmarks (native ARM64, x86_64 and i386)
docs/ Status, testing, performance, the WineForge port plan, and provenance and licenses (PROVENANCE.md)

Building

You need Xcode, the Metal Toolchain, and these Homebrew tools: cmake, ninja, meson, pkgconf, autoconf, automake, libtool, bison, flex, nasm, gettext and gperf.

git clone --recurse-submodules https://github.com/metalsharp/MetalSharp-Wine.git

Or, in an existing clone:

zsh scripts/fetch-sources.sh
zsh scripts/build-all.sh

That builds:

  1. The dependencies.
  2. The ARM64X runtimes.
  3. Wine.
  4. FEX.
  5. The tests.

It then audits the Mach-O files and packages dist/metalsharp-wine-<version>-arm64.

The add-ons have their own scripts:

  • build-llvm15.sh and build-mullion.sh
  • build-winemetalgl.sh
  • build-wfdxcompat.sh (after build-mullion.sh)
  • stage-moltenvk.sh and stage-vkd3d-proton.sh (built in src/vkd3d-proton with its own scripts)
  • build-dxvk-macos.sh then stage-dxvk.sh
  • stage-shader-compilers.sh
  • fetch-addons.sh (Mono and Gecko) and fetch-fonts.sh
  • build-innoextract.sh and build-cabextract.sh
  • stage-metalsharp-assets.sh and stage-metalsharp-redist.sh

sign-app.sh builds MetalSharp-Wine.app with the hardened runtime and compiles the icon (actool, from Xcode). It needs a Developer ID certificate and a provisioning profile with the cross-architecture entitlement.

How the Mac-specific problems are solved

These are patches to Wine and FEX; see docs/STATUS.md for details.

  • x18 / TEB. Windows ARM64 keeps the thread pointer (TEB) in x18, and macOS clears it on every syscall. Measured result: the kernel preserves x18 only when the main executable's build-version SDK is 12.0 or older. The loader is therefore linked with -platform_version macos 15.0 12.0.
  • 4GB PAGEZERO. Without an entitlement, nothing below 4GB can be mapped. KUSER_SHARED_DATA moves from 0x7ffe0000 to 0x17ffe0000.
    • Wine publishes the new address (__wine_user_shared_data).
    • ARM64 loads from the old address are emulated in the fault handler.
    • FEX rebases constant-address loads at JIT time: 0.3 ns per read instead of 1.7 µs.
  • 16K pages and W^X.
    • Wine's ARM64 modules are linked with 64K sections. This fixes a winegcc bug that silently dropped the alignment for ARM64EC.
    • x86 images never get host execute permission.
    • Pages that really need write and execute switch between RX and RW on demand.
    • Stores from code into its own page are emulated, as are LSE atomics and exclusive stores.
    • Wine's NtFlushInstructionCache and FEX's code-write notifications keep JIT overhead to one fault per compiled block.
  • CPU features. macOS doesn't let EL0 read the ID registers, so Wine builds them from the hw.optional.arm.FEAT_* sysctls. FEX uses them to pick LSE, LRCPC, AFP and other fast paths.
  • Startup. dnsapi used to look up the host's own .local name through multicast DNS at every process start (5 seconds). A cold start went from 10.5s to about 0.6s.

Limitations

i386 (32-bit x86) programs need the low 4GB of address space. On macOS 26.4 and later Apple's com.apple.developer.cross-architecture-support entitlement provides it. scripts/sign-app.sh builds dist/MetalSharp-Wine.app with that entitlement, using your Developer ID certificate and a provisioning profile for the bundle's App ID. In that bundle:

  • i386 works.
  • KUSER_SHARED_DATA is at its real address.
  • Every process runs with 4K pages, so none of the 16K workarounds are active.

macOS only grants that entitlement to an executable whose own bundle embeds the provisioning profile; on release builds of macOS 27.2 a standalone executable that claims it is killed at launch. Every Windows process runs in Wine's inner loader, so sign-app.sh gives the inner loader a bundle of its own (lib/wine/aarch64-unix/wine.app, with the profile), and Wine runs it from there.

The bundle is signed with the hardened runtime, as notarization requires. Wine maps Windows DLLs from disk as executable code, which the hardened runtime only allows through the disable-executable-page-protection entitlement. Without the entitlement, i386 would need a full guest address-translation layer.

Unsigned builds, or macOS 15 through 26.3:

  • x86_64 and ARM64 programs work.
  • The page size is 16K, so 4K-granular memory tests in Wine's test suite fail, as they do on Linux with 16K pages.
  • Native ARM64 programs with 4K sections take the slower W^X emulation path.

Licenses

  • MetalSharp Wine's own material (scripts, docs, tests and build glue): AGPL-3.0, like MetalSharp.
  • Wine and the Wine changes: LGPL-2.1-or-later.
  • FEX and its fork: MIT.
  • Mullion/DXMT: LGPL-2.1-or-later.
  • VKD3D-Proton: LGPL-2.1. DXVK and DXVK-MacOS: zlib; DXVK-MacOS's dxbc-spirv: MIT. MoltenVK: Apache-2.0.
  • WineMetalGL: LGPL-3.0.
  • Everything else: each redistributed component keeps its own license, and the app carries them all in share/licenses/.
  • Microsoft's VC++ and core-fonts installers and shader compilers (DXC, d3dcompiler_47) are included unmodified under Microsoft's redistribution terms.

About

Arm64 / Arm64EC / Aarch64 / x86_64 / I386 & WOW64 Wine With FEX For MacOS Silicon on MacOS 26.4+

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

47 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages