Conversation
OpenComposite reference. Also apparently these games read the HMD identity strings once at startup and never re-query. In my traces the game asked for TrackingSystemName ~14 seconds before the runtime bound any controller interaction profile, so at answer time there's no profile to pull from. OpenComposite probably had this too and hardcodes "oculus"/"Oculus". Games that identify controllers still get the profile-accurate strings from the controller devices, this fixed string only feeds the HMD-sniffing path. |
|
I don't think it's a good idea to hard-code the Quest 3 properties here. One idea I had is to spin up a headless session in IVRClientCore::Init and create a dummy action set with a single binding, suggest bindings for all interaction profiles, call xrSyncActions, then cache the bound interaction profiles and destroy the headless session before continuing initialisation. Then we'd have the information available early when games request such properties immediately. |
Some games sniff these to decide which motion controller scheme to enable, and they typically do it once at startup - before any controller has connected - so the HMD is the only device that can answer. Empty strings land such games in their fallback scheme: SUPERHOT VR picks its Vive scheme, where dropping items needs a trackpad, and Serious Sam 3 ignores controller input entirely. Games match against the handful of device families SteamVR shipped, so derive the family from the OpenXR system name instead of hardcoding one headset, and report the real system name as the model. An unrecognized system name falls back to Oculus-style strings, since touch-style controllers are the modern common case. Implements xrGetSystemProperties in fakexr so the property tests can exercise it.
Fallout 4 VR (and Skyrim VR, Serious Sam 3 VR) pick their control scheme from the HMD's Prop_TrackingSystemName_String, which they read exactly once right after init. We reported nothing useful for the HMD, so they fell back to a reduced scheme where A/X and stick clicks don't work (Supreeeme#365, Supreeeme#394). Two changes are needed to fix this: 1. Give the HMD an identity. Each interaction profile now carries HmdProperties for the headset it normally ships with; the HMD answers ModelNumber/SerialNumber/ControllerType from that and shares TrackingSystemName/ManufacturerName with the controllers. Values are taken from Valve's Steam Link driver config (Quest 2/3 report "Oculus"/"Oculus Quest2|3", HMD controller type "rift"; Index "indexhmd"; Vive "vive"). The last seen profile is remembered so the identity survives session restarts and controllers going to sleep. 2. Know the profile in time. Runtimes only resolve interaction profiles on xrSyncActions in a focused session, and a session isn't focused until frames are submitted - normally by the game, long after it asked. So during IVRClientCore::Init, before the regular session is created, spin up a throwaway session with a dummy action set bound to the grip pose of every supported profile, submit empty frames until it is focused, sync once, cache the bound profiles and tear the session down again. The HMD identity is seeded from that cache. fakexr now transitions to VISIBLE/FOCUSED after SYNCHRONIZED and can preset the profile new sessions will bind, so this path is exercised; hmd_identity_available_before_first_frame reproduces the game's access pattern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015X5yWegHAqamZYhDVW3WXv
Fallout 4 VR (and Skyrim VR, Serious Sam 3 VR) pick their control scheme from the HMD's Prop_TrackingSystemName_String, which they read exactly once right after init. We reported nothing useful for the HMD, so they fell back to a reduced scheme where A/X and stick clicks don't work (Supreeeme#365, Supreeeme#394). Two changes are needed to fix this: 1. Give the HMD an identity. Each interaction profile now carries HmdProperties for the headset it normally ships with; the HMD answers ModelNumber/SerialNumber/ControllerType from that and shares TrackingSystemName/ManufacturerName with the controllers. Values are taken from Valve's Steam Link driver config (Quest 2/3 report "Oculus"/"Oculus Quest2|3", HMD controller type "rift"; Index "indexhmd"; Vive "vive"). The last seen profile is remembered so the identity survives session restarts and controllers going to sleep. 2. Know the profile in time. Runtimes only resolve interaction profiles on xrSyncActions in a focused session, and a session isn't focused until frames are submitted - normally by the game, long after it asked. So during IVRClientCore::Init, before the regular session is created, spin up a throwaway session with a dummy action set bound to the grip pose of every supported profile, submit empty frames until it is focused, sync once, cache the bound profiles and tear the session down again. The HMD identity is seeded from that cache. fakexr now transitions to VISIBLE/FOCUSED after SYNCHRONIZED and can preset the profile new sessions will bind, so this path is exercised; hmd_identity_available_before_first_frame reproduces the game's access pattern.
Fallout 4 VR (and Skyrim VR, Serious Sam 3 VR) pick their control scheme from the HMD's Prop_TrackingSystemName_String, which they read exactly once right after init. We reported nothing useful for the HMD, so they fell back to a reduced scheme where A/X and stick clicks don't work (Supreeeme#365, Supreeeme#394). Two changes are needed to fix this: 1. Give the HMD an identity. Each interaction profile now carries HmdProperties for the headset it normally ships with; the HMD answers ModelNumber/SerialNumber/ControllerType from that and shares TrackingSystemName/ManufacturerName with the controllers. Values are taken from Valve's Steam Link driver config (Quest 2/3 report "Oculus"/"Oculus Quest2|3", HMD controller type "rift"; Index "indexhmd"; Vive "vive"). The last seen profile is remembered so the identity survives session restarts and controllers going to sleep. 2. Know the profile in time. Runtimes only resolve interaction profiles on xrSyncActions in a focused session, and a session isn't focused until frames are submitted - normally by the game, long after it asked. So during IVRClientCore::Init, before the regular session is created, spin up a throwaway session with a dummy action set bound to the grip pose of every supported profile, submit empty frames until it is focused, sync once, cache the bound profiles and tear the session down again. The HMD identity is seeded from that cache. fakexr now transitions to VISIBLE/FOCUSED after SYNCHRONIZED and can preset the profile new sessions will bind, so this path is exercised; hmd_identity_available_before_first_frame reproduces the game's access pattern. Vibe coded using Claude Opus 5.
c12ddea to
87d15d2
Compare
Game in question: Serious Sam 3 VR: BFE via Steam and Proton CachyOS from July
Hardware: Quest 3 on KDE Wayland via WiVRN and opensource AMD drivers
Prior status: shows some Vive looking controllers, asks to press right trigger, nothing happens with any button
Current status: fully playable, both controllers, shows Oculus models
Maybe odd: some in-gameplay interface objects have a strong glow - maybe that's just how it is
Note: game complains about display driver, but allows it to be ignored and works fine
Code by: Fable 5
Some games read the HMD's TrackingSystemName/ModelNumber/ManufacturerName strings to decide which motion controller scheme to enable. When these come back empty, such games conclude no supported controllers are present and ignore all controller input (menus still work via mouse) while rendering their fallback wand models.
Report Oculus-style identity strings for the HMD, consistent with the tracking system name already reported for the Touch controller profiles.