Replay each VR eye in one render pass

- Added eye_pass_plan.hpp: an eye keeps drawing in the render pass it has open across the frame's
  GX copies (only the mono render performs them), skips passes a later clear of the whole color and
  depth erases, and splits only for a clear of color alone or depth alone.
- render_stereo_eye follows that plan; the cockpit fallback is drawn inside the last pass instead of
  a render pass of its own that loaded the eye back.
- The stencil is now cleared where the eye actually starts, so a cockpit mask drawn in an erased pass
  can no longer punch holes in the HUD.
- [vr] single_pass_eyes (default on, live from F10) and debug.wiicompiled.eye_passes 0/1 on the Quest
  switch back to one render pass per recorded pass for A/B timing.
- Each new plan shape is logged once ("Eye replay plan: ...").
- Tests: EyePassPlan cases in gx_fifo_tests; stereo_multiplayer_smoke and stereo_frame_worker_smoke
  pass on D3D12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
iChris4andClaude Opus 5.5 committed 2026-09-24 18:18:08 +02:00
1 parent 13311ea626
commit ceeeba0332
12 files changed
+527 -18

No files matched your search

+14
View File
@@ -140,6 +140,7 @@ bool g_showFps = RuntimeConfigFile::ShowFps();
bool g_vrEnabled = RuntimeConfigFile::VrEnabled(true);
bool g_vrStopAtDisplayCopy = RuntimeConfigFile::VrStopAtDisplayCopy(true);
bool g_vrSkipCopyClears = RuntimeConfigFile::VrSkipCopyClears(true);
bool g_vrSinglePassEyes = RuntimeConfigFile::VrSinglePassEyes(true);
bool g_vrHudVirtualScreen = RuntimeConfigFile::VrHudVirtualScreen(true);
bool g_vrFlatScreen = RuntimeConfigFile::VrFlatScreen();
#if defined(__ANDROID__)
@@ -1424,6 +1425,18 @@ void DrawVrSettings() {
"Both apply on the next frame. Turning either off restores the raw replay and is "
"expected to black out the eyes.");
ImGui::PopTextWrapPos();
// Shows the live state, which the Quest's debug.wiicompiled.eye_passes can override.
g_vrSinglePassEyes = aurora_get_stereo_single_pass_eyes();
if (ImGui::Checkbox("One render pass per eye", &g_vrSinglePassEyes)) {
aurora_set_stereo_single_pass_eyes(g_vrSinglePassEyes);
RuntimeConfigFile::SetVrSinglePassEyes(g_vrSinglePassEyes);
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(
"Keeps drawing each eye in the render pass it has open across the frame's GX "
"copies, which only the desktop image performs, and skips what a later clear "
"erases. Same picture, less GPU memory traffic; turn off to compare.");
}
ImGui::Separator();
ImGui::Text("VR 2D layer");
ImGui::BeginDisabled(g_vrFlatScreen);
@@ -2317,6 +2330,7 @@ void InitializeRuntimeSettings() noexcept {
aurora_set_disable_copy_filter(g_disableCopyFilter);
aurora_set_stereo_stop_at_display_copy(g_vrStopAtDisplayCopy);
aurora_set_stereo_skip_copy_clears(g_vrSkipCopyClears);
aurora_set_stereo_single_pass_eyes(g_vrSinglePassEyes);
aurora_set_stereo_mirror_view(static_cast<AuroraStereoMirrorView>(g_vrMirrorView));
mkw::vr::OpenXRSetControllerMode(static_cast<mkw::vr::OpenXRControllerMode>(g_vrControllerMode));
ApplyVrHudVirtualScreen();