Initial public release: OVRPlugin→OpenXR interoperability shim

An independent reimplementation of Meta's libOVRPlugin ABI on top of OpenXR, so
VrApi-era Meta Quest VR titles can run on non-Meta OpenXR runtimes (Monado,
Steam Frame) instead of being locked to Meta hardware. Original code only — no
Meta/Epic/Capcom binaries, headers, or assets. Includes a desktop harness that
drives the shim against Monado headless.

Scope/legal: interoperability; entitlement handling is out of scope. See README
for the legal/scope section and docs/ for the research trail and design notes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D6sFYGXZPsq3v7xtcDES6g
This commit is contained in:
Daniel LynchandClaude Opus 4.8 committed 2026-06-29 00:48:48 -04:00
commit a72a79ad29
57 files changed
+9304

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
# RE4 VR shim — docs
Research trail and session handoffs for the OVRPlugin→OpenXR shim that runs RE4 VR
on non-Meta OpenXR runtimes (Quest 2 today; Steam Frame the goal).
- **`handoffs/`** — chronological session handoffs (the day-by-day journey).
- **`research/`** — reverse-engineering notes, design docs, the ghost-fix writeup, and
`related-work.md` (how Overport/others run Quest games elsewhere; why this shim is novel).
- `../analysis/` — raw RE dumps (`*.txt`, mostly gitignored; `all_exports.txt` +
`shim_surface.txt` feed `shim/gen_stubs.sh`).
- Operational docs live at repo root: `README.md`, `TESTING.md`, `HOST.md`.
## The "ghost" — how it was actually solved (the short version)
For weeks the headline bug was a **VR "ghost"**: doubled/tripled hands and watches,
seated-mode deform, standing-mode black flashes. It survived every theory it *looked*
like — stereo geometry, FOV/IPD, depth reprojection, render-submit ordering, GPU load.
The break came from building **P4 passthru** (`research/ghost-fix-2026-06-27.md`):
running the real Meta `libOVRPlugin` *inside* our app proved native is flawless, so the
bug was in **our path**. Then always-on anomaly logging caught the real signature —
**dropped frames** — and a recording + frame-blending showed it was **whole-frame
temporal judder**, not a stereo/geometry artifact. Localizing the stall showed UE's
render thread blocking ~85–150ms during motion at only ~14ms of GPU work.
Root cause: the shim left `ovrp_WaitToBeginFrame` a **no-op** and ran `xrWaitFrame` on
the **render** thread, so the game thread was unpaced and UE's pipelined renderer
desynced → render-thread stalls → dropped frames → the compositor's timewarp filled the
gaps → judder. **Fix: pace the game thread like vrapi** (`xrWaitFrame` in
`xrr_wait_frame`, frameState handed to the render thread via a 1:1 FIFO ring). Result:
render stall 150→3ms, drops 0.79% (~native 0.34%), steady 72Hz — ghost gone.
Commits `79476c3` (fix) + `c0ecff3` (XR_FRAME_DISCARDED guard).
Secondary wins kept as defaults: game-driven FFR (apply the game's foveation), and the
per-frame luma readback off.
## Reading order if you're new
1. `research/ghost-fix-2026-06-27.md` — the full diagnosis chain (start here).
2. `handoffs/` newest → oldest — the journey, including the dead ends (reproject,
submit-ordering, depth) that were ruled out.
3. `research/RECON.md`, `RE-NOTES.md`, `SHIM-SCOPE.md` — how the shim was reverse-engineered.
4. `research/render-submit-sync-design.md` — the render/submit sync design.