First of all, thank you so much for bringing hope to the Mac VR scene !
What you have built with OpenXR-OSX is incredible, and it inspired me to see if I could push the boundaries a bit further to support Windows PCVR games running on Apple Silicon for my Vision Pro
(Note: I am opening this as an issue since the Discussions tab isn't enabled on the repository, also this latter post is mostly AI inspired since I used Gemini for this R&D project - but this is not slop !)
Naively, I took the "AI route" (working heavily with Gemini CLI) to see if I could build a bridge between Windows VR games running in CrossOver (via D3DMetal) and your native macOS OpenXR-OSX runtime.
I wanted to share the architecture I came up with, the massive compilation walls I hit, and ask your thoughts on whether this path is actually viable.
The Architecture I Attempted
Since a Windows game in CrossOver can't load a macOS .dylib, I attempted to use Valve's wineopenxr (from the Proton repository) as a Universal Translator.
The idea was to build a "Triple-Bridge" leveraging Valve's PE/Unix Split architecture:
- The Client (Windows): Compile
wineopenxr.dll and inject it into the CrossOver bottle via the ActiveRuntime registry key.
- Graphics Marshalling: Intercept
xrEndFrame, use CrossOver's D3DMetal hooks to query the underlying Apple IOSurface ID backing the fake DirectX 12 texture.
- The IPC Thunk (macOS): Instead of piping OpenXR calls through Wine's network stack, the Unix-side thunk (
wineopenxr.so) would communicate directly with OpenXR-OSX using native macOS IPC:
- Telemetry: POSIX Shared Memory (
shm_open) for zero-latency head/hand tracking reads.
- Pacing: Mach Semaphores (
semaphore_wait) to block the game thread during xrWaitFrame.
- Frame Handoff: Unix Domain Sockets (
AF_UNIX) to pass the tiny IOSurface ID integer directly to OpenXR-OSX for presentation.
The Roadblocks (Why it's not finished)
While the C code, IPC headers, and Python thunk-generators were relatively straightforward, compiling a PE/Unix split DLL for macOS turned out to be an absolute nightmare:
- macOS Native Compilation is Impossible: CodeWeavers strips the developer toolchain (
winebuild, winegcc, and headers like <wine/unixlib.h>) from all consumer builds of CrossOver. Attempting to use a standalone llvm-mingw cross-compiler natively on the Mac results in fatal header collisions between standard MinGW Windows headers (windef.h) and Wine's internal headers.
- Valve's Container Wall: Valve's
wineopenxr relies heavily on their custom Proton build system, which uses a massive Podman container (sniper) with heavily patched compilers to bypass those exact header collisions.
- The Apple Silicon Trap: The
sniper SDK container is strictly compiled for AMD64/x86_64. It instantly crashes on an ARM64 Ubuntu VM (even with qemu-user-static, because tini uses unsupported kernel subreaper calls).
- Software Emulation: Booting a full x86_64 Ubuntu VM in UTM via software emulation works, but forcing it to unpack and compile the millions of lines of Wine source code just to link this one
.dll at the end takes days and dies to hyper-specific cross-compilation quirks (like nsiproxy.sys macro collisions).
My Questions for You
Since I am currently blocked purely by the Wine build system infrastructure, I wanted to ask:
- Is this architecture viable? If I successfully compile
wineopenxr.dll, is grabbing the IOSurface ID from D3DMetal and handing it to OpenXR-OSX over a Unix socket actually going to work with your presentation pipeline? Or will synchronization/ownership rules prevent a clean zero-copy render path?
- CrossOver Integration: Have you ever considered a native CrossOver integration on your roadmap? (Perhaps CodeWeavers themselves would be interested in supporting your host runtime natively?)
Thank you again for all the hard work you've put into OpenXR-OSX. I'd love to hear your thoughts on whether this D3DMetal bridge is worth continuing to pursue!
First of all, thank you so much for bringing hope to the Mac VR scene !
What you have built with OpenXR-OSX is incredible, and it inspired me to see if I could push the boundaries a bit further to support Windows PCVR games running on Apple Silicon for my Vision Pro
(Note: I am opening this as an issue since the Discussions tab isn't enabled on the repository, also this latter post is mostly AI inspired since I used Gemini for this R&D project - but this is not slop !)
Naively, I took the "AI route" (working heavily with Gemini CLI) to see if I could build a bridge between Windows VR games running in CrossOver (via D3DMetal) and your native macOS OpenXR-OSX runtime.
I wanted to share the architecture I came up with, the massive compilation walls I hit, and ask your thoughts on whether this path is actually viable.
The Architecture I Attempted
Since a Windows game in CrossOver can't load a macOS
.dylib, I attempted to use Valve'swineopenxr(from the Proton repository) as a Universal Translator.The idea was to build a "Triple-Bridge" leveraging Valve's PE/Unix Split architecture:
wineopenxr.dlland inject it into the CrossOver bottle via theActiveRuntimeregistry key.xrEndFrame, use CrossOver'sD3DMetalhooks to query the underlying AppleIOSurfaceID backing the fake DirectX 12 texture.wineopenxr.so) would communicate directly with OpenXR-OSX using native macOS IPC:shm_open) for zero-latency head/hand tracking reads.semaphore_wait) to block the game thread duringxrWaitFrame.AF_UNIX) to pass the tinyIOSurfaceID integer directly to OpenXR-OSX for presentation.The Roadblocks (Why it's not finished)
While the C code, IPC headers, and Python thunk-generators were relatively straightforward, compiling a PE/Unix split DLL for macOS turned out to be an absolute nightmare:
winebuild,winegcc, and headers like<wine/unixlib.h>) from all consumer builds of CrossOver. Attempting to use a standalonellvm-mingwcross-compiler natively on the Mac results in fatal header collisions between standard MinGW Windows headers (windef.h) and Wine's internal headers.wineopenxrrelies heavily on their custom Proton build system, which uses a massive Podman container (sniper) with heavily patched compilers to bypass those exact header collisions.sniperSDK container is strictly compiled for AMD64/x86_64. It instantly crashes on an ARM64 Ubuntu VM (even withqemu-user-static, becausetiniuses unsupported kernel subreaper calls)..dllat the end takes days and dies to hyper-specific cross-compilation quirks (likensiproxy.sysmacro collisions).My Questions for You
Since I am currently blocked purely by the Wine build system infrastructure, I wanted to ask:
wineopenxr.dll, is grabbing theIOSurfaceID from D3DMetal and handing it to OpenXR-OSX over a Unix socket actually going to work with your presentation pipeline? Or will synchronization/ownership rules prevent a clean zero-copy render path?Thank you again for all the hard work you've put into OpenXR-OSX. I'd love to hear your thoughts on whether this D3DMetal bridge is worth continuing to pursue!