Porting RADV to Win32
- title
- Porting RADV to Win32
- type
- summary
- summary
- Collabora got Mesa's open source AMD Vulkan driver running Counter-Strike 2 on Windows
- tags
- graphics, vulkan, windows, drivers, reverse-engineering
- sources
- radv-win32-port
- created
- 2026-07-29
- updated
- 2026-07-29
Louis-Francis Rattรฉ-Boulianne's July 2026 write-up of Collabora's work, sponsored by Valve, on making RADV run on Windows. RADV is Mesa's open source Vulkan driver for AMD GPUs and has become the de facto Vulkan driver for AMD hardware on Linux โ AMD discontinued their own PAL-based alternative in its favour and consolidated on Mesa. On Windows, AMD users still have only the proprietary driver, and the pitch for changing that is a shared codebase across platforms, easier debugging, faster fixes, and a path for game developers to report or contribute against a driver they can read.
What WDDM2 gives you, and what it withholds
The groundwork is Faith Ekstrand's, presented at XDC 2024. Her finding was that since Windows 10, WDDM2 is a workable foundation for a third-party driver: it defines a clear model for how a user-mode driver talks to the OS and to the kernel-mode driver, which is the split a Vulkan implementation needs.
The catch is that many D3DKMT calls carry private driver data โ opaque vendor-specific blobs whose contents are entirely the driver's business. The UMD and KMD stay tightly coupled through that channel, and it is completely undocumented. Ekstrand's route around it was wddm2-pdd-re, a tool that logs WDDM2 calls and the private data they carry for D3D12 applications. From those logs she reverse-engineered enough of the private interface โ adapter info queries, buffer allocation, queue creation, command submission โ to get RADV submitting work to the proprietary kernel driver, ending with a rotating 3D model on screen.
From triangle to game
Collabora picked that up with three goals: more flexible (fewer hard-coded values, so different hardware works), more portable (native Windows instead of running through WSL), and far more stable (not crashing after two minutes of deqp-vk). They reworked command stream handling and synchronization and added sparse bindings, tessellation, task shaders, and dynamic querying of GPU properties. The driver is still not conformant, though the deqp-vk pass rate has gone up substantially. The visible result is Counter-Strike 2 running on RADV under Windows โ anyone can try it by launching with -vulkan.
Three specific obstacles
Hardware generations diverge more than expected. Collabora worked on Gen 11 hardware (RX 7900 XT) while Ekstrand had used a 10th-gen part (RX 7800 XT), and architecture changes between them meant her results couldn't be reproduced for a long time โ anything more complex than clearing a surface to a hard-coded colour hung the GPU. Windows offers no tooling to debug that class of hang, so the fix was more tooling: the reverse-engineering utility was upgraded into a full WDDM2 logging layer that can analyze any application running on the official Vulkan driver, dumping command streams, registers and shader code, so the two drivers' behaviour can be diffed.
MSVC disagrees with the compilers Mesa was written for. Mesa is developed against GCC and Clang and its codebase leans on assumptions those two share. The example given is enum handling: MSVC can treat an enum value as signed and cap it at 32 bits, which produces surprising behaviour in code that never considered the possibility.
Opaque data inside an opaque call. D3DKMTEscape is WDDM2's vendor-specific hook, with no defined structure at all โ the only rule is that it shouldn't duplicate something a standardized call already does. Collabora's read is that the escapes they see target advanced features like multi-GPU rendering, so they can be safely ignored for now.
What blocks production use
The kernel interface is the open question. Writing their own KMD is not an option, so RADV has to talk to AMD's, and right now that conversation runs entirely on reverse-engineered knowledge of private data structures. Worse, the UMD and KMD ship as a matched pair with no backward-compatibility guarantee, so those structures can change between driver releases with no notice and nothing to warn you. Making this maintainable needs either a stable documented interface to the proprietary KMD, or a shim library mediating the private data channel to give a stable surface as the blobs underneath evolve.
Presentation is the other gap. Jesse Natalie did WSI work for Windows in the context of the Dozen driver, but RADV currently only supports the slow CPU path. Using DXGI swapchains requires importing an image from D3D12 โ more opaque metadata โ and zero-copy swaps on top of that would need direct involvement from AMD and probably Microsoft, given the limitations around image sharing. The prize named for that last step is up to a 3x gain for applications that aren't GPU-bound.
The whole project is a bet that open drivers are worth the reverse-engineering tax on a platform whose vendor never intended them, which is the same territory win32-stable-abi covers from the opposite direction โ there, Win32 through Wine turned out to be the most durable ABI on Linux precisely because Microsoft's interfaces don't move. Here the undocumented half of a Microsoft interface moves whenever AMD ships a driver, and that is exactly what makes the port fragile.
The work lives on the wddm2 branch of lfrb's Mesa fork.