Skip to content

Investigate Single-Pass Instanced (SPI) support to halve stereo CPU cost #126

@dfattal

Description

@dfattal

Motivation

The plugin is MultiPass-only today. Single-Pass Instanced (SPI) roughly halves the CPU cost of the stereo render (one instanced draw set + one culling/scene-traversal pass instead of two). The GPU win is smaller. Payoff is scene-dependent — draw-call-heavy scenes benefit most; simple scenes (single avatar, a gaussian splat) and CPU-headroom-rich desktop setups may not notice. Worth it for the plugin's general applicability, not urgent.

Current state / the documented blocker

Runtime/DisplayXRFeature.cs:365 ships a build-blocking validation rule (error = true, with a fixIt that forces MultiPass):

"DisplayXR requires Multi-Pass render mode. Single-pass instanced is incompatible with Camera.SetStereoProjectionMatrix (MultiPass-only on every platform), which DisplayXR uses to push the Kooima asymmetric projection per eye."

The rig (DisplayXRCamera/DisplayXRDisplay.OnCameraPreRender) calls SetStereoViewMatrix/SetStereoProjectionMatrix per eye.

Why it may be less blocked than that implies (the key question to settle first)

We established separately that the GPU projection actually comes from the native xrLocateViews hook (xrLocateViews → scene transform + tunables + Kooima projection), and that Camera.SetStereoProjectionMatrix is C#-cache-only — it does not reach the GPU under an active OpenXR loader. If that holds, under SPI Unity populates its stereo view/proj constant buffer from the runtime's xrLocateViews output — which the plugin already controls — so the Kooima projection could flow to the GPU without SetStereoProjectionMatrix, making the MultiPass requirement avoidable.

Spike #1 (cheap, decides everything): force SPI, bypass/relax the validation rule, confirm whether per-eye Kooima projection still reaches the GPU via the xrLocateViews hook (correct asymmetric stereo on screen). If yes → SPI is feasible; if no → it needs a real GPU-instancing projection path and the cost-benefit likely sinks.

Work items / unknowns (if the spike is positive)

  1. Projection path — drop or guard the C# SetStereoProjectionMatrix path; relax the MultiPass validation rule to allow SPI.
  2. Swapchain layout (biggest unknown) — SPI submits one swapchain with arraySize=2 (texture array) vs today's two arraySize=1 swapchains. Audit and extend:
  3. Post-process AADisplayXRPostAA (Rig-level post-process FXAA for the XR eye RT (#121) #125) uses Graphics.Blit in OnRenderImage, which mishandles the SPI eye-texture array. Needs a per-slice blit or an array-aware AA pass.
  4. Standalone (SA) preview — the SA path renders its own per-tile eye cameras (DisplayXRPreviewSession); confirm it's unaffected (it doesn't use Unity's XR submission) or adjust.
  5. Validation — verify stereo correctness, eye tracking, transparent overlay, and wsui all still work under SPI.

Priority

Low / investigation. MultiPass works today and #125 (FXAA) closed the immediate anti-aliasing need. This is an efficiency improvement to scope via Spike #1 before committing.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions