Skip to content

[TeleViz] Opt-in native OpenXR quad layers for QuadLayer#819

Open
farbod-nv wants to merge 1 commit into
mainfrom
fm/openxr_quad_1
Open

[TeleViz] Opt-in native OpenXR quad layers for QuadLayer#819
farbod-nv wants to merge 1 commit into
mainfrom
fm/openxr_quad_1

Conversation

@farbod-nv

@farbod-nv farbod-nv commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Description

Adds an opt-in native OpenXR quad path to Televiz: QuadLayer::Config::use_openxr_quad_layer.

When set on a layer in a kXr session, the quad is submitted to the runtime as a native
XrCompositionLayerQuad — the backend copies the CUDA-fed image into a per-layer, lazily-created
color swapchain and lets the runtime place and sample the quad directly — instead of compositing it
into the shared render target. Stereo layers emit one quad per eye via eyeVisibility, with the
per-eye baseline offset matching the compositor path's convention. Frames whose visible layers are
all native quads drop the shared projection layer entirely, so the runtime sees a quad-only
submission and can engage its quad fast path / client-reconstructed streaming. Window/offscreen
modes ignore the flag and keep the compositor draw path.

Trade-off (documented on the config field): a native quad carries no depth — OpenXR quad layers
have none — so it composites in submission order rather than z-testing against ProjectionLayer
content, and generate_mipmaps is unused in native mode. In non-opaque (passthrough) blend modes
the source-alpha layer flag keeps quads compositing correctly but excludes them from the runtime's
client-reconstructed optimization; opaque VR sessions get the fast path.

Implementation notes:

  • layer_base/display_backend: NativeQuadView descriptor plus is_native_quad() /
    acquire_native_quad() and supports_native_quad() / record_native_quads() extension points
  • quad_layer: extracted promote_slot() shared by the render-pass and native-quad consumers;
    cuda_done_writing waits at TRANSFER stage in native mode (the backend copy is the first GPU read)
  • xr_backend: per-quad swapchain cache keyed by layer identity (exception-safe partial-creation
    cleanup), projection_active_ gating in end_frame, abort/release/destroy coverage
  • viz_compositor: partitions native vs composited layers; skips the shared render pass on
    quad-only frames
  • Python: exposes the flag on QuadLayerConfig (stub regenerated); camera_viz gains --native-quad

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Testing

Linux x86_64, 2× RTX 6000 Ada, CUDA 13.x.

  • Unit/GPU (Release): full viz suites pass — viz_core_tests (186 assertions),
    viz_layers_tests (351), viz_session_tests (386). New [native] tests cover the config
    default, the native gate (is_native_quad() false without a kXr session), acquire preconditions
    (pre-publish leniency, placement required once content is published, out-of-range in-flight
    slot), and the offscreen fallback (flag set → still composites through record(), pixel-verified
    via readback).
  • ASAN+UBSAN: same suites pass with zero reports (ASAN_OPTIONS=protect_shadow_gap=0 for CUDA).
  • Python: all 4 viz binding test files pass; flag round-trips through QuadLayerConfig.
  • Live XR against a local CloudXR runtime 6.2.0 (no client attached): mono native, stereo
    native, mixed native+composited (projection + quad in one xrEndFrame), and per-frame visibility
    toggling (projection layer drops and re-engages mid-session) — 300+ frames total, no XR errors,
    ~33 fps runtime pacing. Visual placement/disparity and streaming-fast-path engagement with a
    headset client remain to be verified manually.
  • SKIP=check-copyright-year pre-commit run passes on all changed files; clang-format clean.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the linter and formatter with SKIP=check-copyright-year pre-commit run --all-files
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix/feature works (or explained why not)
  • I have signed off all my commits (git commit -s) per the DCO

Summary by CodeRabbit

  • New Features

    • Added optional native OpenXR quad-layer rendering for XR sessions.
    • Added --native-quad to the camera visualization example.
    • Native quad layers now support stereo placement, sizing, and per-eye imagery.
    • Quad-only XR frames can be presented without an intermediate projection layer.
    • Non-XR sessions continue using the existing compositor path.
  • Bug Fixes

    • Improved frame synchronization for native quad rendering.
  • Tests

    • Added coverage for configuration, prerequisites, fallback behavior, and quad-only presentation.

Add QuadLayer::Config::use_openxr_quad_layer: in kXr mode the quad is
submitted as a native XrCompositionLayerQuad (per-layer lazily-created
color swapchains, one quad per eye for stereo via eyeVisibility) instead
of compositing into the shared render target. Frames whose visible
layers are all native quads drop the shared projection layer entirely,
letting the runtime engage its quad fast path / client-reconstructed
streaming. Window/offscreen ignore the flag and keep the compositor
draw path.

- layer_base/display_backend: NativeQuadView + is_native_quad()/
  acquire_native_quad() and supports_native_quad()/record_native_quads()
  extension points
- quad_layer: extract promote_slot() shared by both consumer paths;
  TRANSFER-stage cuda_done_writing wait in native mode
- xr_backend: per-quad swapchain cache keyed by layer identity,
  projection_active_ gating in end_frame, abort/release/destroy coverage
- viz_compositor: partition native vs composited layers; skip the render
  pass on quad-only frames
- python: expose the flag; camera_viz gains --native-quad

Validated against a local CloudXR runtime (mono, stereo, mixed
native+composited, and per-frame visibility toggling).
@farbod-nv
farbod-nv requested review from nv-jakob and tengw-nv July 24, 2026 04:12
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 61d57728-5139-41fe-9f03-5a4a8849121f

📥 Commits

Reviewing files that changed from the base of the PR and between 6258095 and 32dddda.

📒 Files selected for processing (11)
  • examples/camera_viz/camera_viz.py
  • src/viz/layers/cpp/inc/viz/layers/quad_layer.hpp
  • src/viz/layers/cpp/quad_layer.cpp
  • src/viz/layers_tests/cpp/test_quad_layer.cpp
  • src/viz/python/layers_bindings.cpp
  • src/viz/session/cpp/inc/viz/session/display_backend.hpp
  • src/viz/session/cpp/inc/viz/session/layer_base.hpp
  • src/viz/session/cpp/inc/viz/session/xr_backend.hpp
  • src/viz/session/cpp/viz_compositor.cpp
  • src/viz/session/cpp/xr_backend.cpp
  • src/viz/session_tests/cpp/test_quad_milestone.cpp

📝 Walkthrough

Walkthrough

The change adds an OpenXR native-quad configuration path for QuadLayer. Native views are acquired separately from composited layers, copied into cached per-eye XR swapchains, and submitted as XrCompositionLayerQuad entries. Quad-only frames omit the projection layer, while non-XR sessions continue using the compositor path. Tests cover configuration, acquisition preconditions, fallback behavior, and image output. The camera example exposes the feature through --native-quad.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CameraViz
  participant VizCompositor
  participant QuadLayer
  participant XrBackend
  participant OpenXRRuntime
  CameraViz->>QuadLayer: enable use_openxr_quad_layer
  VizCompositor->>QuadLayer: acquire_native_quad(slot)
  QuadLayer-->>VizCompositor: NativeQuadView
  VizCompositor->>XrBackend: record_native_quads(frame, views)
  XrBackend->>OpenXRRuntime: submit quad composition layers
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: an opt-in native OpenXR quad-layer path for QuadLayer.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fm/openxr_quad_1

Comment @coderabbitai help to get the list of available commands.

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