system: answer DirectX adapter queries - #386
Open
napanto wants to merge 1 commit into
Open
Conversation
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
force-pushed
the
directx-adapter-queries
branch
from
July 6, 2026 02:23
c1a3c08 to
b5bfad5
Compare
Supreeeme
reviewed
Jul 22, 2026
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. |
Owner
There was a problem hiding this comment.
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.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
D3D11/D3D12 OpenVR games ask the runtime which GPU the HMD is on before creating their device, and xrizer currently can't answer:
GetOutputDeviceonly handlesTextureType_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.GetDXGIOutputInfoandGetD3D9AdapterIndexaretodo!(), which aborts the game.IVRSystem_016version ofGetOutputDevice(noVkInstanceparameter) is alsotodo!(). 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 fromVkPhysicalDeviceIDPropertiesplus the device's position invkEnumeratePhysicalDevicesorder, which is how DXVK orders its DXGI adapters. Most Linux drivers reportdeviceLUIDValid = 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 onSystemso repeated queries don't recreate the instance.The Vulkan path of
GetOutputDeviceis untouched, except that a null instance (only possible throughIVRSystem_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 fakexrGetVulkanGraphicsDeviceKHRalso now writes its output, which it previously left uninitialized.