Skip to content

video_thread: the headset calls reach the driver under threaded video - #19736

Open
Davey-Hughes wants to merge 1 commit into
libretro:masterfrom
Davey-Hughes:threaded-video-vr-calls
Open

Davey-Hughes wants to merge 1 commit into
libretro:masterfrom
Davey-Hughes:threaded-video-vr-calls

Conversation

@Davey-Hughes

Copy link
Copy Markdown
Contributor

Description

With Threaded Video on, the frontend talks to the thread wrapper, whose tables left the newer VR hooks empty:

  • the headset refresh query (get_headset_refresh, poke)
  • the eye poses (get_vr_frame_state)
  • the stereo request a view map makes (set_vr_content_info)
  • the headset status (get_video_views_status)

So under threaded video the menu offered the fallback headset rates, and the runloop never learned the headset's rate (desktop, seen on a Steam Frame). On the Quest a VR core saw no headset, had its stereo map refused and got no poses, so it fell back to flat.

These calls come from the main thread while the driver runs on the video thread, so each forward has to be safe there:

  • Refresh and status are answered on the caller's thread, since cores and the runloop ask every frame. The drivers read only what the desktop headset thread publishes atomically and what driver init and free change, and the main thread waits through both.
  • The stereo request and the poses run on the video thread through video_thread_run_blocking(): the request sets the driver's stereo state, and taking the poses marks them for the frame that submits them.
  • The Quest context calls in video_driver.c (the per-frame pose sample, frame flags, reference-space change, eye size, the GL stereo flag) also run on the video thread, after the frames already queued. The reference space used to be replaced from the main thread while the video thread located views and submitted layers in it. Waiting for the queue also means each frame is submitted with the poses it was drawn with. The cost is that head-tracked content runs in step with the video thread.
  • Headset pacing stays off under threaded video, as before. The pacing relied on the missing refresh hook to keep threaded video unpaced. Its tick wait sits in the driver's frame, which under the wrapper does not hold the core, so this is now an explicit check in driver_adjust_system_rates().

Threaded video off: unchanged.

A new lane in samples/gfx/threaded_video (lane_headset_calls) checks the forwards: the menu's rate list, the runloop's rate, the status, the stereo request and the poses, and that the request and poses run on the video thread. It also checks that a fitting headset rate does not pace threaded video. It fails six ways on master.

Tested locally on Linux:

  • the harness on the null driver under ASan and TSan, with and without --enable-openxr
  • the release build with the menu harness's configure line
  • check-vulkan with --enable-openxr on RADV under the validation layer
  • C89: C89_BUILD=1 on the touched objects, plus a strict -std=c89 build with HAVE_OPENXR defined
  • an NDK build of the Quest flavour (HAVE_OPENXR=1, arm64)

The Quest path is compile-checked only; it still needs a device test.

Related Issues

None filed.

Related Pull Requests

#19726 (Quest OpenXR) and #19729 (desktop headset output) added the hooks this forwards.

The wrapper's tables left the headset refresh query and the three VR
calls empty. With Threaded Video on, the menu offered fallback rates,
the headset was never asked for its rate, and on the Quest a VR core
saw no headset, had its stereo map refused and got no poses.

The refresh and the views status are answered on the caller's thread:
the drivers read only what the headset thread publishes and what init
and free change. The stereo request and the poses run on the video
thread, as do the Quest context's sample, reference-space change and
stereo flag, after the frames already queued: the frame locates its
views in that space and is submitted with the poses it was drawn
with, so tracked content runs in step with the video thread.

Headset pacing stays off under threaded video, as before: the tick
wait is in the driver's frame, which does not hold the core there.
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.

1 participant