You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bring Linux to the same CTS standing Windows reached on 2026-09-23: 0 runtime-attributable failures across the three interactive categories (composition, actions, scenario), on a real GPU and a real X session, on top of the non-interactive arms that already gate CI. Windows got there across #1523 (d3d11), #1689/#1694/#1695 (d3d12) and #1704/#1705/#1706 (opengl); this is the Linux/Vulkan equivalent, and it is a smaller job than either Windows lane, because Linux is Vulkan-only.
Everything below can be done from the Linux box. The Windows box is only needed for a second opinion on a Vulkan runtime change (it can run -G vulkan too).
The harness exists: scripts/fetch_build_cts.sh, scripts/run_cts.sh (-g vulkan|vulkan2, --scope smoke|full, --xvfb, --software, --conformance-layer, --quarantine-list). Its header documents exactly what is and is not ported from the .ps1.
Never run: the whole suite on a real GPU + real X session, the installed .deb/tarball runtime rather than the dev tree, direct scanout (DXR_LINUX_DIRECT_SCANOUT=1), Wayland (the lane is X11/XCB only), and every interactive category — run_cts.sh deliberately has no interactive mode.
The work, in dependency order
1. vk_native must draw the layer types the interactive tests use (blocking)
Today comp_vk_native_compositor.c accepts quads into the accumulator and never draws them, exactly as D3D12 and GL did before #1689/#1704. Every CTS composition test puts its prompt, its labels and its reference image in quad layers, so the category is not failing on Vulkan — it is unjudgeable: no prompt, no labels, no content.
First step: rebase #1623 onto current main, land it, then port equirect2 to vk_native.
2. A Linux interactive harness (the actual new work)
The Windows driver is PowerShell + Win32: interactive_cts.ps1 (registry ActiveRuntime swap — not needed on Linux, XR_RUNTIME_JSON is honoured), cts_step.ps1 / cts_next.ps1 / cts_drive.ps1 (focus the CTS window, inject a key or click, capture, log a verdict), capture_dpi_aware.ps1, bar_profile.ps1 (gradient oracle), sab_measure.py / eq_diff.py (pixel oracles). The judging logic and oracles port as-is; only three platform primitives do not:
primitive
Windows
Linux equivalent
focus the CTS window
SetForegroundWindow
xdotool windowactivate / wmctrl -a (needs a WM — --xvfb starts a bare X server, so use a real session or add one)
inject key / button
keybd_event with scancodes
xdotool key / keydown / keyup / click, or skip X entirely (below)
capture the screen
PrintWindow, DPI-aware
import -window, xwd, or the runtime's own atlas capture (u_capture_intent_poll is already wired in comp_vk_native_compositor.c:6997; on Linux the trigger dir is $TMPDIR)
Two candidate routes for input — pick by measuring:
(a) X11 injection into the runtime's self-created window.comp_vk_native_window_xcb.c already selects XCB_EVENT_MASK_KEY_PRESS (:213, :223), but its event loop (:562) handles only CONFIGURE_NOTIFY / CLIENT_MESSAGE / DESTROY_NOTIFY — key presses are dropped on the floor. So (a) needs a small runtime change: pump XCB key events into qwerty the way comp_d3d11_window.cpp:852 pumps WM_KEY* into qwerty_process_win32. There is no qwerty_process_xcb yet; qwerty_win32.c and qwerty_sdl.c (qwerty_process_event) are the two models, and u_debug_gui.c:183 is the only existing caller of the SDL one.
(b) SDL front end.qwerty_sdl.c is already built when XRT_HAVE_SDL2, but nothing on the CTS path creates an SDL window, so it needs a pump too — probably more moving parts than (a).
Budget for the traps the Windows lane hit, all recorded in docs/reference/cts-interactive-procedure.md:
scenario cases treat Menu as FAIL (SpaceOffsets) or hand-swap (GripAndAimPose), never as Help;
QuadHands needs the qwerty hands raised into the frustum first (CTRL+ALT then E ~500 ms, §10.6);
the gradient pairs need the 100° camera profile (DXR_LEGACY_CAMERA_RIG) or the prompt quad falls outside the frustum.
3. Drive the three categories on the bench box
./scripts/build_linux.sh
./scripts/fetch_build_cts.sh --apt
./scripts/run_cts.sh -g vulkan --scope full --conformance-layer # non-interactive, real GPU, no --software# then the new interactive mode, category by category, judging each prompt
scenario — GripAndAimPose passes; SpaceOffsets auto-passes only since feat(qwerty): report analytic controller velocity and make all six SpaceOffsets axes driveable (#1692) #1696 gave qwerty analytic velocities (keyboard recipe in that PR body: CTRL+ALT held; D/E/S for the linear axes; R, then SHIFT+Up/Left/Z for the angular ones); InteractiveThrow is rig-limited — targets 3–5 m out under 9.8 m/s² versus a 1.83 m/s qwerty hand, so it cannot be completed on a keyboard rig on any platform. Record it as such; do not chase it.
4. The rest of the Linux-specific surface
Once the three categories are green on the dev tree:
the same run against the installed .deb / tarball rather than the dev build tree;
docs/reference/cts-interactive-procedure.md § 6 gate updated to name the Linux lane, and docs/roadmap/linux-support.md § Conformance updated with what the hardware arm now covers.
Goal
Bring Linux to the same CTS standing Windows reached on 2026-09-23: 0 runtime-attributable failures across the three interactive categories (
composition,actions,scenario), on a real GPU and a real X session, on top of the non-interactive arms that already gate CI. Windows got there across #1523 (d3d11), #1689/#1694/#1695 (d3d12) and #1704/#1705/#1706 (opengl); this is the Linux/Vulkan equivalent, and it is a smaller job than either Windows lane, because Linux is Vulkan-only.Everything below can be done from the Linux box. The Windows box is only needed for a second opinion on a Vulkan runtime change (it can run
-G vulkantoo).Where Linux already is
cts.yml'sbuild-linux-cts→run-linuxrunsvulkanandvulkan2on lavapipe under Xvfb at the pinnedopenxr-cts-1.1.63.0: 40062 / 0 / 0 and 40046 / 0 / 0 assertions (Linux CTS arm: vulkan + vulkan2 on a real-GPU Linux runner (currently zero conformance coverage) #1527, fix(vk): make the desktop-Linux external-memory/modifier/fd device extensions optional-if-present for enable1 (#1576) #1577). Those result files already drop into the same submission package as the Windows ones.scripts/fetch_build_cts.sh,scripts/run_cts.sh(-g vulkan|vulkan2,--scope smoke|full,--xvfb,--software,--conformance-layer,--quarantine-list). Its header documents exactly what is and is not ported from the.ps1..deb/tarball runtime rather than the dev tree, direct scanout (DXR_LINUX_DIRECT_SCANOUT=1), Wayland (the lane is X11/XCB only), and every interactive category —run_cts.shdeliberately has no interactive mode.The work, in dependency order
1.
vk_nativemust draw the layer types the interactive tests use (blocking)Today
comp_vk_native_compositor.caccepts quads into the accumulator and never draws them, exactly as D3D12 and GL did before #1689/#1704. Every CTS composition test puts its prompt, its labels and its reference image in quad layers, so the category is not failing on Vulkan — it is unjudgeable: no prompt, no labels, no content.feat/vk-compose-layers) is the fix: quad layers + back-face cull + the painter's rule, plus the CTS composition: UNORM (linear) swapchains are passed through un-encoded on every backend — GradientFormatsLinearVsNonLinear FAIL; ADR-021 Model A vs OpenXR format semantics #1589/compositor blends layers in sRGB-encoded space; OpenXR expects linear-space blending (CTS SourceAlphaBlending) #1610 colour model onvk_native. Drafted pending the app-side_SRGBmigration its author flagged.-G vulkanhardware leg on 2026-09-23 (comment on feat(vk_native): compose-path migration, part 2 — quad layers, painter's-order blend, back-face cull, and linear-light colour (#1581 #1590 #1598 #1589 #1610) #1623):QuadOcclusionx2 PASS,GradientFormatsLinearVsNonLinear13/13,SourceAlphaBlendingPASS,SourceAlphaBlendingWithEnvironment254/155 both blend modes. The branch is good; it needs landing, not re-inventing.vk_nativeafter feat(vk_native): compose-path migration, part 2 — quad layers, painter's-order blend, back-face cull, and linear-light colour (#1581 #1590 #1598 #1589 #1610) #1623:equirect2(vk_compositor_layer_equirect2()atcomp_vk_native_compositor.c:2323accumulates, nothing draws it), andSubimage/MinLayerswere not exercised on that leg. Equirect2 is a mechanical port — D3D12 got it in feat(d3d12): draw equirect2 layers off the shared HLSL — the last blank composition class on D3D12 (#1602) #1695, GL in feat(gl): draw equirect2 layers — a GLSL twin of the shared shader closes the last blank composition class on OpenGL (#1602) #1706, both off the sharedd3d_shared/comp_equirect2_shaders.h; the GL one is a GLSL twin, which is most of the way to a SPIR-V one.First step: rebase #1623 onto current main, land it, then port equirect2 to
vk_native.2. A Linux interactive harness (the actual new work)
The Windows driver is PowerShell + Win32:
interactive_cts.ps1(registry ActiveRuntime swap — not needed on Linux,XR_RUNTIME_JSONis honoured),cts_step.ps1/cts_next.ps1/cts_drive.ps1(focus the CTS window, inject a key or click, capture, log a verdict),capture_dpi_aware.ps1,bar_profile.ps1(gradient oracle),sab_measure.py/eq_diff.py(pixel oracles). The judging logic and oracles port as-is; only three platform primitives do not:SetForegroundWindowxdotool windowactivate/wmctrl -a(needs a WM —--xvfbstarts a bare X server, so use a real session or add one)keybd_eventwith scancodesxdotool key/keydown/keyup/click, or skip X entirely (below)PrintWindow, DPI-awareimport -window,xwd, or the runtime's own atlas capture (u_capture_intent_pollis already wired incomp_vk_native_compositor.c:6997; on Linux the trigger dir is$TMPDIR)Two candidate routes for input — pick by measuring:
comp_vk_native_window_xcb.calready selectsXCB_EVENT_MASK_KEY_PRESS(:213,:223), but its event loop (:562) handles onlyCONFIGURE_NOTIFY/CLIENT_MESSAGE/DESTROY_NOTIFY— key presses are dropped on the floor. So (a) needs a small runtime change: pump XCB key events into qwerty the waycomp_d3d11_window.cpp:852pumpsWM_KEY*intoqwerty_process_win32. There is noqwerty_process_xcbyet;qwerty_win32.candqwerty_sdl.c(qwerty_process_event) are the two models, andu_debug_gui.c:183is the only existing caller of the SDL one.qwerty_sdl.cis already built whenXRT_HAVE_SDL2, but nothing on the CTS path creates an SDL window, so it needs a pump too — probably more moving parts than (a).Budget for the traps the Windows lane hit, all recorded in
docs/reference/cts-interactive-procedure.md:SpaceOffsets) or hand-swap (GripAndAimPose), never as Help;QuadHandsneeds the qwerty hands raised into the frustum first (CTRL+ALT then E ~500 ms, §10.6);DXR_LEGACY_CAMERA_RIG) or the prompt quad falls outside the frustum.3. Drive the three categories on the bench box
Expect, from the Windows experience:
cts_actions_responder.ps1) is Windows-only and needs an equivalent or manual driving.GripAndAimPosepasses;SpaceOffsetsauto-passes only since feat(qwerty): report analytic controller velocity and make all six SpaceOffsets axes driveable (#1692) #1696 gave qwerty analytic velocities (keyboard recipe in that PR body: CTRL+ALT held; D/E/S for the linear axes; R, then SHIFT+Up/Left/Z for the angular ones);InteractiveThrowis rig-limited — targets 3–5 m out under 9.8 m/s² versus a 1.83 m/s qwerty hand, so it cannot be completed on a keyboard rig on any platform. Record it as such; do not chase it.4. The rest of the Linux-specific surface
Once the three categories are green on the dev tree:
.deb/ tarball rather than the dev build tree;DXR_LINUX_DIRECT_SCANOUT=1);vk_linux_update_surface_not_1to1()degrades a scaled Wayland surface to flat 2D on GNOME 42, Enforce refuse-rather-than-resample: we weave in sessions our own code has declared non-1:1 (desktop Linux / Wayland) #1595);docs/roadmap/linux-support.md§ Supported releases).Definition of done
vk_native.composition,actions,scenariodriven on a real-GPU X session at the pinned CTS, with a per-case tally posted on Epic: OpenXR CTS coverage for the full supported matrix — 5 graphics plugins on Windows, 2 on Linux, 2 on Android (today: 1, non-interactive) #1523 in the same shape as the Windows ones, and 0 runtime-attributable failures (skips enumerated;InteractiveThrowrecorded as rig-limited).docs/reference/cts-interactive-procedure.md§ 6 gate updated to name the Linux lane, anddocs/roadmap/linux-support.md§ Conformance updated with what the hardware arm now covers.Pointers
docs/reference/cts-interactive-procedure.md.docs/roadmap/linux-support.md; per-arm CTS detail:docs/roadmap/cts-windows-handoff.md§ Linux arms._SRGBviews encode on write), but worth knowing if a gradient pair ever looks odd.