Skip to content

Shared-texture mode (standalone) — Phase 1 of 2D surround (#131)#132

Closed
dfattal wants to merge 1 commit into
mainfrom
feat/shared-texture-mode-standalone-131
Closed

Shared-texture mode (standalone) — Phase 1 of 2D surround (#131)#132
dfattal wants to merge 1 commit into
mainfrom
feat/shared-texture-mode-standalone-131

Conversation

@dfattal
Copy link
Copy Markdown
Collaborator

@dfattal dfattal commented May 29, 2026

What

Phase 1 of #131 (2D surround support): adds an opt-in shared-texture mode to the plugin-owned standalone session (Editor Preview / Play Mode). Default OFF → current handle mode is preserved bit-for-bit.

This is the prerequisite for canvas sub-rect (#34) and the 2D surround feature (xrSetSharedTextureSurround2DEXT), which the runtime only supports in shared-texture mode.

Why standalone first

The standalone D3D12 backend already implements the full shared-texture output pipeline as dormant scaffolding with no call sites — create_shared_texture(), fw_create_swapchain()/fw_present(), get_shared_handle(). This PR just wires it up behind a flag. The built-player/hooked path (Unity owns presentation) is a tracked follow-on; see the plan in the issue discussion.

How

When the flag is on, the standalone session:

  1. allocates a panel-size shared output texture,
  2. binds its NT handle as XrWin32WindowBindingCreateInfoEXT.sharedTextureHandle so the runtime weaves into it (instead of presenting to the HWND),
  3. presents it each frame via fw_present after xrEndFrame (DXGI stretches the panel-size swapchain to the window → no WM_SIZE reallocation).

The request flag lives in a static (survives the start-time memset of s_sa). s_sa.shared_texture_active is set only if the mode was requested and the backend yields a handle — non-D3D12 backends return null → handle-mode fallback, so the flag is a safe no-op there.

Status

  • ✅ Builds clean (MSVC x64); DLL committed.
  • Hardware validation pending in the Preview Window: with the flag ON, output should be identical to OFF, no device removal. The runtime-side assumption (given sharedTextureHandle, the runtime weaves into it and does not also present to the HWND) needs confirming on device.

🤖 Generated with Claude Code

Phase 1 of 2D-surround support: wire up the dormant shared-texture-mode
scaffolding in the plugin-owned standalone session (Editor Preview / Play
Mode), behind an opt-in flag. Default OFF preserves handle mode bit-for-bit.

When enabled, the standalone session allocates a panel-size shared output
texture (StandaloneD3D12Backend::create_shared_texture, already implemented),
binds its NT handle as XrWin32WindowBindingCreateInfoEXT.sharedTextureHandle
so the runtime weaves into it instead of presenting to the HWND, and the
plugin presents it each frame via fw_create_swapchain/fw_present (also already
implemented) — DXGI stretches the panel-size swapchain to the window, so no
WM_SIZE reallocation is needed.

The request flag lives in a static (survives the start-time memset of s_sa);
the resolved s_sa.shared_texture_active is 1 only if the mode was requested AND
the backend produced a handle, so non-D3D12 backends (which return null) fall
back to handle mode and the flag is a safe no-op there.

- native: displayxr_standalone_set_shared_texture_mode() setter; allocate+bind
  at session create; present after xrEndFrame; teardown in stop.
- C#: DisplayXRNative P/Invoke; Preview Window "Shared Tex (#131)" toggle
  (EditorPrefs, applies at next Start); pushed before start in PreviewSession.

This is the prerequisite for canvas sub-rect (#34) and 2D surround. Built
clean (MSVC x64). Hardware validation in the Preview Window pending; the
runtime-side behavior (weave-into-shared-texture, no HWND present) needs
confirming on device.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dfattal dfattal marked this pull request as draft May 30, 2026 04:44
@dfattal
Copy link
Copy Markdown
Collaborator Author

dfattal commented May 30, 2026

Parking as draft. Reading the runtime source (openxr-3d-display) showed the surround blit is applied on the HWND path too (comp_d3d12_compositor.cpp:1670), so the built app gets 2D surround in its current handle mode — no shared-texture-mode/present-ownership rework needed. This PR (standalone shared-texture mode) is a valid capability but not a prerequisite for the surround deliverable, so we're pivoting to implement surround directly on the hooked path. Leaving this open as draft for later.

@dfattal
Copy link
Copy Markdown
Collaborator Author

dfattal commented Jun 1, 2026

Closing as superseded — not a missing fix.

The 2D surround feature this PR was framed as a prerequisite for shipped via a different mechanism and is fully released in v1.12.0 / v1.13.0, including the standalone (Editor Preview / Play Mode) path that this PR specifically targeted.

This PR's premise was that surround requires a shared-texture output mode (binding the runtime's NT handle as the window render target instead of presenting to the HWND). That assumption was abandoned. Instead, main keeps the standalone session in handle/HWND-present mode and adds surround as a separate cross-device shared texture + D3D12 fence bridge — same pattern as the wsui/atlas bridges. See:

On main, displayxr_standalone.cpp deliberately sets win_binding.sharedTextureHandle = NULL, i.e. it does not bind a shared handle as this PR proposed. The shared-texture-output scaffolding (create_shared_texture / fw_present) remains dormant in the backend files, unused.

The shared-texture-output mode in this branch would only matter as future infra for canvas sub-rect (#34) or a zero-copy preview path — not for surround. It also still has unfinished hardware validation. If we want that capability later, we'll reopen a fresh issue scoped to #34 rather than carry this stale branch (~20 commits behind main, with real rebase conflicts in the since-restructured standalone.cpp).

@dfattal dfattal closed this Jun 1, 2026
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