Skip to content

Bring the host up to the current XR_DXR_weave spec (v6 N-view atlas, v3 batch, legacy fallback) - #5

Merged
dfattal merged 3 commits into
mainfrom
feat/weave-spec-v6-sync
Aug 10, 2026
Merged

dfattal merged 3 commits into
mainfrom
feat/weave-spec-v6-sync

Conversation

@dfattal

@dfattal dfattal commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Brings the host up to date with the current XR_DXR_weave spec, and verifies it
on real hardware rather than in theory.

What was wrong

  • Vendored XR_DXR_weave.h was SPEC_VERSION 1; the runtime's canonical copy is
    6. The host submitted through the pre-v3 single-rect call — still supported,
    so it worked, but as the standalone integration example it taught an API five
    versions stale.
  • displayxr-common pinned v2.5.0; latest is v2.6.1.
  • CI was lint-only, so "does it build against a current runtime" had been
    unverified since July.

What this does

1. Headers re-synced byte-for-byte from displayxr-runtime's
src/external/openxr_includes/openxr/ (the canonical copy), which also picks up
XR_DXR_wayland_surface_binding.h and the corrected 1004999xxx registry.
displayxr-common → v2.6.1.

2. Modern submit paths, negotiated down from the spec version the runtime
reports (never the vendored header's):

Runtime spec Path
≥ 6 (preferred) XrWeaveSubmitLayoutDXR N-view worst-case atlas
3 – 5 XrWeaveSubmitRectsDXR batch, firstChunk on ≥ 5
< 3 legacy per-element — documented fallback, logic unchanged

The batch shape follows displayxr-browser patch 0027 (SubmitBatchWin), including
the 32-rect chunking.

On v4/v5/v6 — what I included and why. v6 is the primary path: it makes the host
an ordinary N-view client (ADR-010 worst-case atlas + ADR-030 crop-before-DP), packing
the atlas itself at the active mode's viewScale, sized from the display so window
resize never reallocates. Crucially it owns the alpha between elements, so the woven
output draws back whole-window in one premultiplied "over" blit with no dependence on a
runtime-side clear. v5 firstChunk is used on the v3 rung, where that clear is what
makes the same whole-window draw-back safe.

v4 overlays are deliberately out: this demo paints no crisp 2D over the woven 3D —
the page's 2D surround sits around and under the elements, which the page base already
handles. Adopting v4 would mean inventing a second window-sized premultiplied-RGBA atlas
producer and a stacking-order rasteriser existing only to exercise the field. v6 beyond
viewCount == 2 is also out
: filling a 4-view mode needs the page to render 4 views,
which is a demo-page rewrite, not a host change.

3. A pre-existing geometry bug, fixed. Element rects were clamped to the page, so
an element scrolled off the top (negative y) collapsed into a full-height rect pinned at
y=0 — the host then fed page text to the weave and drew woven text back over the
page. That is the ragged-canvas-while-scrolling artifact, and it reproduces on main
(I rebuilt unmodified main to confirm before touching it). Rects are now intersected
with the page and dropped when empty: an off-screen element is not a weave region.

4. DXR_WEAVE_MAX_SPEC=<n> caps the negotiated version (never raises it), so one build
reproduces every submit shape the extension has shipped against a current runtime — the
knob for bisecting "is this bug batch-only?", which is half of why this repo exists.

5. CI: a cached windows-latest build that asserts the exe lands, plus a non-blocking
header-sync job diffing the vendored headers against displayxr-runtime@main — it would
have caught this five-version gap. Also neutralizes one vendor company name in the README
that predates this branch (never caught because lint.yml only runs on pull_request).

Verified on hardware

Real 3D display, vendor DP (not sim_display), non-elevated via explorer.exe against the
non-elevated service:

Runtime v2.5.0-3-g7262f3bc1, reports XR_DXR_weave spec v6
Display processor vendor plug-in v2.0.7, plug-in ABI v5
Active mode 2 views, 2×1 grid, viewScale 0.5 × 0.5 → worst-case atlas 3840×2160
CEF 149.0.4 (Chromium 149.0.7827.156)
  • v6 path: one submit/frame, 3 elements, ~1.4 ms round-trip, zero errors; correct at
    rest and under scroll, confirmed on the live display.
  • v3 batch + v5 firstChunk (via DXR_WEAVE_MAX_SPEC): ~1.26 ms/frame.
  • Legacy per-element: ~2.6 ms/frame, same 3 elements — the per-call fixed cost
    (IPC round-trip + shared-texture open + keyed-mutex + fence) is what batching amortizes.

The DP is genuinely weaving, not passing through: sampling a scanline across a cube edge in
the composited output alternates column-by-column between background 13,18,23 and cube
93,30,23 — the interlace comb. Flat regions inside the same element show zero
column-to-column delta.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LW3wiw5Ds4Tj8AaGUQAFqF

dfattal and others added 3 commits August 9, 2026 23:06
…on v2.6.1

The vendored XR_DXR_* headers had drifted: XR_DXR_weave.h was SPEC_VERSION 1
against the runtime's 6, so the host was compiled against an interface five
versions stale (no batched rects, overlay atlas, first-chunk clear, or N-view
atlas). Re-copied the whole openxr/ set byte-for-byte from the runtime's
canonical src/external/openxr_includes/openxr/, which also picks up
XR_DXR_wayland_surface_binding.h and the corrected 1004999xxx type-value
registry.

displayxr-common moves v2.5.0 -> v2.6.1 in the same pass.

No behavioural change on its own: the host still submits via the legacy
single-rect path until the next commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LW3wiw5Ds4Tj8AaGUQAFqF
…h, legacy

The host submitted one xrWeaveSubmitDXR per element per frame via the pre-v3
single-rect call. That still works, but as the standalone integration example
it taught an API five spec versions stale. Negotiate DOWN from the spec version
the RUNTIME reports (never the vendored header's) through three paths:

  >= 6  XrWeaveSubmitLayoutDXR N-view worst-case atlas (preferred)
  3-5   XrWeaveSubmitRectsDXR batch, + firstChunk on >= 5
  < 3   legacy per-element (documented fallback, unchanged)

v6 makes the host an ordinary N-view client (ADR-010 / ADR-030): it packs the
atlas itself at the active mode's viewScale, sized from the DISPLAY so window
resize never reallocates, and owns the alpha between elements — so the woven
output draws back whole-window in one premultiplied "over" blit with no
dependence on a runtime-side clear. It needs XR_DXR_display_info for the mode
geometry (xrEnumerateDisplayRenderingModesDXR) and viewCount == 2, since the
page renders a squeezed SBS pair per element; anything else falls back a rung.

Also fixes a pre-existing geometry bug that this made visible. Element rects
were CLAMPED to the page, so an element scrolled off the top (negative y)
collapsed to a full-height rect pinned at y=0 — the host then fed page TEXT to
the weave and drew woven text back over the page (ragged canvases while
scrolling, on main too). Rects are now INTERSECTED with the page and dropped
when empty: an off-screen element is not a weave region.

DXR_WEAVE_MAX_SPEC=<n> caps the negotiated version (never raises it) so one
build reproduces every submit shape against a current runtime — the knob for
bisecting "is this bug batch-only?", which is half of why this host exists.

Verified on a real 3D display against runtime v2.5.0-3-g7262f3bc1 (spec v6),
vendor DP v2.0.7 / ABI v5, CEF 149.0.4: v6 path, 3 elements, one submit per
frame, ~1.4 ms round-trip, correct at rest and under scroll. Measured against
~1.26 ms/frame for the v3 batch and ~2.6 ms/frame for legacy per-element.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LW3wiw5Ds4Tj8AaGUQAFqF
…coverage

CI was lint-only, so "does it still build against a current runtime" had been
unverified since July — for a repo whose whole job is being a reproducer that
runs, that is the bug worth fixing. Adds:

- a windows-latest build (cached CEF/OpenXR keyed on the pinned versions, so a
  hit makes setup-deps a no-op) that asserts the exe actually lands; and
- header-sync, which diffs the vendored openxr/ set against
  displayxr-runtime@main. Non-blocking (continue-on-error): drift means "go run
  the sync", not "this PR is wrong" — but it would have caught the five-version
  gap this branch just closed.

README gains a spec-coverage table (which weave version each path drives, and
why v4 overlays and >2-view v6 are deliberately out of scope for a minimal
example), the DXR_WEAVE_MAX_SPEC knob, a verified-against block naming the exact
runtime/DP/CEF versions of the last hardware run, and the header re-sync recipe.

Also neutralizes one vendor company name in the README. It predates this branch
and had never been caught because lint.yml only runs on pull_request, and the
line arrived via a direct-to-main doc commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LW3wiw5Ds4Tj8AaGUQAFqF
@dfattal
dfattal merged commit 5bac35a into main Aug 10, 2026
3 checks passed
@dfattal
dfattal deleted the feat/weave-spec-v6-sync branch August 10, 2026 08:51
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