Skip to content

system: answer DirectX adapter queries - #386

Open
napanto wants to merge 1 commit into
Supreeeme:mainfrom
napanto:directx-adapter-queries
Open

system: answer DirectX adapter queries#386
napanto wants to merge 1 commit into
Supreeeme:mainfrom
napanto:directx-adapter-queries

Conversation

@napanto

@napanto napanto commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

D3D11/D3D12 OpenVR games ask the runtime which GPU the HMD is on before creating their device, and xrizer currently can't answer:

  • GetOutputDevice only handles TextureType_Vulkan. For DirectX texture types it logs "Unsupported texture type" and returns without writing *pnDevice. Proton's vrclient forwards the value to the game even in that case, so the game reads uninitialized memory where it expects an adapter LUID.
  • GetDXGIOutputInfo and GetD3D9AdapterIndex are todo!(), which aborts the game.
  • The IVRSystem_016 version of GetOutputDevice (no VkInstance parameter) is also todo!(). Proton passes this one through untranslated, so games requesting old interface versions can hit the panic.

This implements all of them from one query: create a short-lived Vulkan instance, get the runtime's physical device through xrGetVulkanGraphicsDeviceKHR, and read the LUID from VkPhysicalDeviceIDProperties plus the device's position in vkEnumeratePhysicalDevices order, which is how DXVK orders its DXGI adapters. Most Linux drivers report deviceLUIDValid = false; in that case we write 0, which is what Proton's own vrclient reports when it can't provide a device, and the adapter index falls back to 0, always correct on single GPU machines. The result is cached on System so repeated queries don't recreate the instance.

The Vulkan path of GetOutputDevice is untouched, except that a null instance (only possible through IVRSystem_016) now logs an error and writes 0 instead of panicking.

Tested with Assetto Corsa (D3D11, requests IVRSystem_014) under GE-Proton9 with Monado: it previously failed with "D3D11CreateDevice failed" and now runs in VR. Half-Life: Alyx (Vulkan) is unaffected. fakexr gains just enough of the Vulkan API to unit test this; its fake xrGetVulkanGraphicsDeviceKHR also now writes its output, which it previously left uninitialized.

D3D11/D3D12 games ask which GPU the HMD is connected to before creating
their device. GetOutputDevice with a DirectX texture type expects the
adapter LUID, GetDXGIOutputInfo and GetD3D9AdapterIndex expect an
adapter index. All of these were todo!() or returned without writing
the output, so a game either aborted or read uninitialized memory
(Proton's vrclient forwards the value to the game even when we don't
write it).

Create a short-lived Vulkan instance, ask the runtime for its physical
device and answer with its LUID (VkPhysicalDeviceIDProperties) and its
position in vkEnumeratePhysicalDevices order, which is how DXVK orders
DXGI adapters. Most Linux drivers don't report a valid LUID; write 0 in
that case, matching what Proton's vrclient does when it can't provide a
device. The Vulkan path of GetOutputDevice is unchanged, except that a
null instance (possible through IVRSystem_016, which has no instance
parameter) no longer panics.

Tested with Assetto Corsa under GE-Proton9, which previously failed to
create its D3D11 device and now runs in VR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@napanto
napanto force-pushed the directx-adapter-queries branch from c1a3c08 to b5bfad5 Compare July 6, 2026 02:23
Comment thread src/system.rs
Comment on lines +904 to +908
// Direct3D games ask for the LUID of the adapter the HMD is
// connected to, then create their device on the DXGI adapter with
// the matching LUID. Proton usually rewrites this into a Vulkan
// query before it reaches us, but the IVRSystem_016 version comes
// through untranslated.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds more like something that needs to be raised with the Proton folks. I don't really want to add stuff that might change at any time within Proton. (if I have to, I will, but I'd rather not.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants