mirror of
https://github.com/daniel-lynch/ovrplugin-openxr-shim.git
synced 2026-10-06 05:00:07 +02:00
Repo hygiene round following a full review. No shim behaviour changes. Leak risk: - .gitignore: ignore CLAUDE.md (personal assistant-lane config, was one `git add -A` away from a public commit) and scratch_obj/. Docs vs. reality: - shim/README.md: rewritten. It described a pre-implementation skeleton with "core fns are TODO stubs returning -1005", three mutually inconsistent stub counts, and four completed milestones listed as open. Now carries the verified breakdown: 438/438 exports = 371 generated stubs + 46 core + 7 layers + 2 Vulkan queries + 12 passthru trampolines. - TESTING.md: dropped the self-contradicting "NOT yet" block (5 of 6 items were done or misstated, and contradicted the same file 45 lines above). Path B now points at tools/desktop-harness, which exists, instead of the orphaned shim/tests/harness.c. Path A prereqs marked as the record they are. - HOST.md: corrected the runtime assumption. The OpenXR runtime inside Lepton is SteamVR (vendor/etc/openxr/1/active_runtime.json -> vrclient.so), not Monado. Favourable: SteamVR emulates Oculus Touch by default and advertises the XR_FB_foveation family, so the existing input and foveation paths should carry over. The old "remaining unknowns" are resolved by Lepton's published source and replaced with the items to check before a first Frame boot. - README.md: same runtime correction. - docs/research/RECON.md: the four passages prescribing an entitlement NOP/stub/bypass are corrected in place rather than merely disclaimed by the top banner, which they contradicted. Build correctness: - shim/build_android.sh: missing patchelf is now fatal. It warned and exited 0, producing a .so that cannot resolve the OpenXR loader at runtime. - scripts/fetch_deps.sh + packaging/build_openxr_loader.sh: pin the OpenXR and Vulkan header versions (were tracking `main`), overridable via OPENXR_TAG / VULKAN_HEADERS_TAG; require cmake for the loader build. - packaging/steamframe_patches.sh: use the apktool.jar that fetch_deps.sh downloads. Its prereq check demanded an `apktool` binary on PATH that the documented setup never provides, so it could not run after a clean setup. - shim/gen_stubs.sh: it reads all_exports.txt, not shim_surface.txt; comment and emitted banner corrected. stubs.c regenerated (banner line only). - shim/src/core.c: split seven `if (out) ...; return ...;` one-liners. Host build now compiles with zero warnings, down from seven. Verified: host build 0 warnings; gen_stubs.sh output identical on regeneration; bash -n clean on all edited scripts; pinned header/tarball URLs return 200 and the tag tarball extracts to the expected directory name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
83 lines
4.0 KiB
Markdown
83 lines
4.0 KiB
Markdown
# libOVRPlugin.so shim (OVRPlugin v1.51 ABI -> OpenXR)
|
|
|
|
Drop-in replacement for RE4 VR's `libOVRPlugin.so`. It re-exports the `ovrp_*` C ABI the
|
|
game calls and implements it on **OpenXR + Vulkan** instead of Meta's `libvrapi.so`.
|
|
|
|
**Status: working.** RE4 VR boots and is playable on a Quest 2 through this shim on Meta's
|
|
OpenXR runtime — stereo rendering, head and controller tracking, buttons, grips, haptics,
|
|
and save loading. Steam Frame is the next target; see `../HOST.md`.
|
|
|
|
## Export surface
|
|
|
|
The artifact exports **438/438** `ovrp_*` symbols, matching `../analysis/all_exports.txt`
|
|
exactly (0 missing, 0 extra), so any `dlsym` of any `ovrp_` resolves even for the ~199
|
|
entry points RE4 never references.
|
|
|
|
| Source | Exports | What |
|
|
|---|---|---|
|
|
| `src/stubs.c` (generated) | 371 | 103 Unsupported (-1004), 67 no-op Success (0), 201 NotYetImplemented (-1005) |
|
|
| `src/core.c` | 46 | lifecycle, frame loop, poses, controller, system info |
|
|
| `src/layers.c` | 7 | `SetupLayer` / `GetLayerTexture2` / stage count / eye layer desc |
|
|
| `src/vk_session.c` | 2 | the Vulkan instance/device extension queries |
|
|
| `src/passthru.c` | 12 | trampolines for calls the game makes that need no real impl |
|
|
|
|
`gen_stubs.sh` regenerates `src/stubs.c` from `../analysis/all_exports.txt`; functions
|
|
prototyped in the header are skipped there (67 of them) and implemented in `core.c`.
|
|
Regeneration is deterministic — re-running it on a clean tree produces no diff.
|
|
|
|
## Layout
|
|
|
|
- `include/ovrplugin_shim.h` — the `ovrp_*` C ABI: types, structs, core prototypes.
|
|
Independently written against the observed ABI, with `_Static_assert`s pinning the
|
|
binary-verified struct sizes so a layout mistake fails the build rather than the device.
|
|
- `src/xr_runtime.{c,h}` — the OpenXR engine: instance/session lifecycle, the frame loop,
|
|
swapchains, layer composition, foveation, perf levels.
|
|
- `src/vk_session.c` — Vulkan graphics binding, image enumeration, the tile-memory flush.
|
|
- `src/layers.c` — layer setup and eye layer geometry.
|
|
- `src/xr_input.c` — action sets and controller/haptics mapping.
|
|
- `src/android_init.c` — JavaVM/activity capture, `xrInitializeLoaderKHR`, Android instance
|
|
create-info chaining.
|
|
- `src/passthru.c` — the author-only A/B diagnostic (see below).
|
|
- `src/stubs.c` — generated.
|
|
|
|
Roughly 48 distinct OpenXR entry points are used.
|
|
|
|
## Build
|
|
|
|
**The deployable artifact** is Android arm64 — the game runs inside Horizon OS or Lepton:
|
|
|
|
```sh
|
|
../scripts/fetch_deps.sh # OpenXR + Vulkan headers, NDK, JDK, build-tools
|
|
./build_android.sh # -> build/arm64/libOVRPlugin.so
|
|
```
|
|
Needs the NDK (r27c) and `patchelf` (to add `NEEDED libopenxr_loader.so`). Then
|
|
`../packaging/repack.sh` swaps it into your own dumped APK.
|
|
|
|
**Host build** is compile-validation plus the desktop OpenXR harness, not a shipping
|
|
artifact:
|
|
|
|
```sh
|
|
./build_host.sh # -> ../build/host/{libOVRPlugin.so,harness}
|
|
../tools/desktop-harness/run.sh
|
|
```
|
|
Needs libvulkan and an OpenXR loader; without the loader it builds the objects and stops.
|
|
|
|
## Debug: passthru forwarding (author-only diagnostic)
|
|
|
|
`debug.re4vr.passthru=1` hands the whole OVRPlugin session to a real, SONAME-patched
|
|
`libOVRPlugin_real.so` if one is present in the APK — an A/B harness for diffing native
|
|
runtime behaviour against the shim. **No such binary is included or distributed by this
|
|
repo**; you would have to place one from your own device dump, and without it the flag is
|
|
inert. All other `debug.re4vr.*` props are likewise diagnostics.
|
|
|
|
## Known gaps
|
|
|
|
- Depth layer submission is gated behind `debug.re4vr.depth` and off by default; Meta's
|
|
runtime accepts but does not use plain KHR depth for reprojection.
|
|
- Input binds `/interaction_profiles/oculus/touch_controller` only.
|
|
- Several `debug.re4vr.*` paths are documented dead ends kept for reference (copy-ring,
|
|
render-ahead, submithook); see `../docs/research/` for what each one ruled out.
|
|
|
|
See `../docs/research/SHIM-SCOPE.md` for how the surface was scoped, `../TESTING.md` for the
|
|
test plan, and `../docs/README.md` for the research trail.
|