9.4 KiB
LegendFrame plan (single-pass stereo, SPS-VI)
Read DESIGN.md first. Source is TRLVR 1.1.0 (e3657d0) at ~/Games/LegendFrame/src.
Build is ~/Games/LegendFrame/toolchain (podman legendframe-mingw). Outputs go to
~/Games/LegendFrame/build-*. Rules:
- Lanes never edit the same file at the same time.
- Each lane works on its own branch off
steam-frameand is merged by the overseer. - Nothing is installed into the game directory except by the M5 lane.
File ownership (exclusive while the lane is open)
| lane | files |
|---|---|
| M1-T toolchain | toolchain/*, build-m1/*, build patches only (no src/ edits except an agreed src/common/seh_compat.h) |
| M2-A DXVK shader | dxvk-trlvr/src/d3d9/d3d9_shader.cpp, d3d9_shader.h |
| M2-B DXVK device | dxvk-trlvr/src/d3d9/d3d9_vr.h, d3d9_vr.cpp, d3d9_device.h, d3d9_device.cpp, d3d9_state.h, d3d9_options.*, src/util/config/config.cpp |
| M2-C harness | src/test/stereotest.cpp (new), toolchain/stereotest.sh (new) |
| M3-P proxy | src/proxy/proxy_device.h, proxy_device.cpp, proxy_d3d9.cpp, src/vr/stereo.cpp/.h, src/vr/reflection_stereo.cpp/.h, src/common/config.h/.cpp |
| M3-K hotkey/panel | src/vr/tune.cpp/.h, src/proxy/overlay.cpp (settings panel entry) |
| M4-M maths | src/vr/vr_session.cpp/.h, src/vr/vr_math.*, src/test/mathtest.cpp |
| M5-I install/validate | ~/Games/LegendFrame/install/*, the game dir, trlvr.ini, logs |
Contract frozen at the start of M2-B, so the other lanes can code against it:
IDirect3DVRStereo9ind3d9_vr.h(DESIGN §4);D3D9StereoPushDataat VS push offset 20;- the bank is 8 vec4 appended to the VS static CBV, L c0..c3 then R c0..c3;
- shader key suffix
_sps1.
M1: reproducible baseline (in progress, toolchain lane)
Accept when:
- the container builds 1.1.0
d3d9_dxvk.dll,d3d9.dllandtrlvr_launcher.exefrom~/Games/LegendFrame/src, using the 1.1.0build.batsource list (overlay, xr/ovr/vr runtime, menu_*, tr7_menu_hook, finger_input, godmode/, physics/, third_party/openxr headers,openxr_loaderdelay-load or LoadLibrary-only); - the
__tryshim compiles all 11 files that use it, or the proxy is built with clang-cl + xwin; upstream-diff.txtlists the fork's diff against upstream DXVK v3.1.0 (settles DESIGN §2 UNVERIFIED);- a headset session with self-built 1.1.0 two-pass,
vr_runtime=openvr, stays within ±5 % of 1.0.0 shipped fps at the same spot. Log lines to expect:vr: using OpenVR / SteamVRandsubmit: first side-by-side frame accepted.
Lanes:
- M1-T (Sonnet, high; already running): finish the proxy build.
- M1-V (Sonnet):
vulkaninfotobuild-m1/vulkan-caps.txt. ConfirmmultiViewport,maxViewports,shaderOutputViewportIndex,VK_KHR_multiview(+multiviewGeometryShadernot needed),VK_QCOM_multiview_per_view_viewports, andVK_EXT_vertex_attribute_divisor.
M2: DXVK single-pass core (needs only the DXVK build, which already works)
Accept when:
- with
stereotest.exeunder Proton 11 ARM64 on the Frame (DISPLAY=:1, no headset):- a VS reading c0..c3 renders a quad into a 2W x H RT, once with
SetStereoDraw(L, R, W, H)and once as two-pass; - the readback images are identical (max abs diff 0) for: a static c0 shader, a
relative-addressed (a0) shader, a shader with
callsubroutines, MSAA 2x, and the scissor test on; - mono draws after
ClearStereoDraware unchanged; - an instanced draw while armed is rejected and logged;
- a VS reading c0..c3 renders a quad into a 2W x H RT, once with
spirv-valpasses on dumped stereo shaders;- DXVK log lines:
D3D9VR: single-pass stereo enabled (viewport index, bank 8 vec4, key _sps1)D3D9VR: stereo draw rejected (instanced) -- reported onceD3D9VR: stereo lowering failed for <key> -- compiled monoD3D9VR: single-pass disabled by d3d9.trlvrSinglePass
Lanes (parallel):
- M2-B device/interface (Opus): freeze the header first, then do arming, the bank
upload in
UpdateShaderConstants, the two viewports inBindViewportAndScissor, instanceCount, the push flag, Reset, stats, and the conf switch. - M2-A shader lowering (Opus):
stereoModeoption and key, bank members insetupStaticCbv, selects inlowerLegacyConstInput(static + dynamic), and the ViewportIndex prologue. - M2-C harness (Sonnet):
stereotest.cpploadsd3d9_dxvk.dlldirectly, getsIDirect3DVR9viaDirect3DCreateVR9, and QIs toIDirect3DVRStereo9. Add a run script using the SLR/Proton command from the MCC recipe.
M3: proxy integration (needs M1 proxy build + M2 header)
Accept when:
- in the headset,
stereo_mode=singlepassgives identical-looking images to two-pass across the DESIGN §8 checklist, with the Shift+F6 live toggle; - the stats line shows >= 90 % single-pass among stereo draws in gameplay;
- fps is >= 50 at the test spot (1440, 72 Hz, cool start).
Config keys, [vr] in trlvr.ini:
stereo_mode = twopass|singlepass(defaulttwopassuntil M5 sign-off);stereo_stats = 0|1;vr_runtime = openvr(Frame default).
Proxy log lines:
stereo: single-pass (viewport index) enabled, DXVK stereo interface v1stereo: DXVK has no single-pass interface (E_NOINTERFACE) -- two-passstereo: single-pass requested but EnableSinglePassStereo failed (0x%08X) -- two-pass- every 5 s with
stereo_stats=1:stereo stats: single %u, fallback %u (eye-textures %u, fixed-function %u, instanced %u, reflection %u), mono %u, arm calls %u, dxvk rejected %u stereo: live toggle -> single-pass|two-pass (Shift+F6)
Lanes:
- M3-P proxy (Opus):
stereo_issue_single, eligibility, sticky arm/clear,hands_in_front, thereflection_stereo_draw_needs_eye_texturespredicate,SetStreamSourceFreqtracking, config, CreateDevice enable, and the debug hand sample. - M3-K hotkey/panel (Sonnet): Shift+F6 toggle, plus an optional settings-panel item.
Calls only
stereo_set_single_pass(bool)exported by M3-P (agree the signature in the M3-P first commit).
M4: shared per-eye maths (can start as soon as the M1 proxy build works; independent of M2/M3)
Accept when:
mathtestshows the dual-eye function bit-identical to 2x single calls on >= 200 captured c0 sets, covering pure projection, WVP, sky, UI, marker, PDA, Mission Prep, first-person hands and board hands. Captures come from avr_capture_c0=1debug key writingc0_capture.bin;perf cpu"mod matrix math" is down >= 40 % in both two-pass and single-pass;- there is no visual change.
New log line: stereo: dual-eye substitution on (shared prefix, eye matrix cache, zoom EMA per frame).
Key: [vr] stereo_shared_math = 1 (0 = legacy per-eye calls, for A/B).
Lane:
- M4-M (Opus):
vr_substitute_c0_stereo, a per-framevr_eye_matrixcache, the binocular_zoom EMA once per frame, the sky call counter +2, and lazy upload-time centre-eye substitution.
M5: Frame validation, install, defaults
Accept when:
- three cool sessions in single-pass + M4 give a median fps >= 60 at the test spot and no regression in the checklist;
- the owner signs off on the look;
- defaults are flipped (
stereo_mode=singlepass) and the install script is idempotent; - the memory file is updated.
Lanes:
- M5-I (Sonnet): install/uninstall scripts and backups (rollback below), headset session log collection, A/B summary table.
- M5-X (Sonnet, optional, after sign-off): FEX knobs (
FEX_MAXINST=5000,FEX_PROFILESTATS=0) and a Proton Experimental ARM64 A/B. Also, behind[vr] submit_wait = 1|0, the no-wait TransferSurface experiment. Revert anything that shows artefacts. - M5-F (Opus, only if M3 stats show fixed-function fallback > 5 %): FF GLSL epilogue
(
d3d9_fixed_function_vert.vert+ push flag).
M6: optional research (not scheduled)
- Layered multiview (DESIGN §3.2/§6): dxbc-spirv
eViewIndex,vk11.multiview,viewMask, 2-layer stereo surfaces, OpenXRarraySize=2, and the OpenVR array submit through Proton vrclient. Only if GPU time becomes the limit. - OpenXR on Proton Experimental ARM64 (32-bit wineopenxr):
vr_runtime=openxr,openxr_loader.dll, SteamVR OpenXR runtime; compare pacing with OpenVR.
Rollback
- Before the first install, M5-I copies the game dir's
d3d9.dll,d3d9_dxvk.dll,openvr_api.dll,trlvr_launcher.exe,trl_vr.exeandtrlvr.inito~/Games/LegendFrame/build-m1/shipped/1.0.0/, withSHA256SUMS. These are the currently installed 1.0.0 files. The zip's sha256fd36ec16…a18is in~/Games/TRLVR/dl, so the zip is a second source. - Every install writes
~/Games/LegendFrame/install/last-install.txt(file, old sha, new sha) and keeps the previous set ininstall/prev/. - Three levels of fallback, fastest first:
- Shift+F6 in the headset;
[vr] stereo_mode=twopass;d3d9.trlvrSinglePass = Falseindxvk.conf(in launch options viaDXVK_CONFIG);install/rollback.sh, which restoresshipped/1.0.0and checks the sha256s.
- Proxy and DXVK are always swapped together (the IID pairing). Never mix a 1.0.0 proxy with a 1.1.0 DXVK.
- Delete DXVK's shader/state cache files for trl_vr in the game dir/prefix on every swap (key-suffix safety net).
Immediate start
- M2-B DXVK device/interface (Opus): the header freeze is its first commit.
- M2-A DXVK shader lowering (Opus): works against the frozen contract above.
Both need only the DXVK container build, which works today (build-m1/out/dist/d3d9_dxvk.dll).
M2-C (Sonnet) can follow as soon as the header is frozen. M4-M starts when M1-T has a
working proxy build.