mirror of
https://github.com/thejerf/baijiSteamVR.git
synced 2026-10-20 00:01:57 +02:00
86 lines
4.0 KiB
C++
86 lines
4.0 KiB
C++
// Copyright 2026 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
// VR display frame region + viewport classifier (Hydra's g_final_screen_region /
|
|
// SetViewportType, adapted to the OpenXR architecture).
|
|
//
|
|
// The authoritative "displayed frame" is the EFB->XFB copy source rectangle — the region
|
|
// of the EFB that is actually scanned out to the TV. A full-width EFB *clear* is NOT a
|
|
// reliable source: many games clear more lines than they display (Mario Galaxy), while
|
|
// Metroid Prime Trilogy really does display 480 lines but renders the scene into 448.
|
|
//
|
|
// Everything here runs on the video thread only (FIFO order), so plain statics are safe.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
|
|
struct Viewport;
|
|
|
|
namespace VR
|
|
{
|
|
struct VRFrameRegion
|
|
{
|
|
int left = 0;
|
|
int top = 0;
|
|
int width = 0;
|
|
int height = 0;
|
|
bool valid = false;
|
|
};
|
|
|
|
// Hydra-style viewport classification, measured against the latched frame region.
|
|
enum class VRViewportClass
|
|
{
|
|
MainScene, // viewport == frame region (or region unknown — preserve behavior)
|
|
Letterboxed, // full-width but not full-height (cinematic bars, Trilogy 448-in-480)
|
|
SplitScreen, // multiplayer half/quadrant viewport
|
|
HudElement, // small / off-center sub-viewport (e.g. MKDD character select panes)
|
|
RenderToTexture, // square edge-anchored render target (shadow/env maps)
|
|
Offscreen, // outside the displayed frame region
|
|
};
|
|
|
|
// Called from BPStructs for every EFB->XFB copy (srcRect in native EFB coordinates,
|
|
// already clamped to the EFB). Multi-strip copies within one frame are unioned; the
|
|
// completed union is committed when the next frame's first copy arrives, so consumers
|
|
// see the PREVIOUS completed frame's display region (same latency as Hydra's
|
|
// g_final_screen_region, updated at Swap).
|
|
void NotifyVRXFBCopyRegion(int left, int top, int right, int bottom);
|
|
|
|
// Previous completed frame's display region. Not valid until two XFB copies were seen.
|
|
VRFrameRegion GetVRFrameRegion();
|
|
|
|
// Forget everything (new game boot).
|
|
void ResetVRFrameRegion();
|
|
|
|
// Classify a draw's viewport against the latched frame region. x_off/y_off are the
|
|
// doubled scissor offsets (scissorOffset << 1), matching BPFunctions conventions.
|
|
// Returns MainScene when the frame region is unknown so all callers fall back to
|
|
// current behavior.
|
|
VRViewportClass ClassifyVRViewport(const Viewport& viewport, int x_off, int y_off);
|
|
|
|
// Record a real perspective draw which can describe the composed scene's EFB extent.
|
|
// At the XFB-copy boundary the most frequently drawn full-width region is used as the
|
|
// presentation source. This deliberately records the game's unmodified viewport: EFB
|
|
// effects continue to see the exact layout the game rendered.
|
|
void ObserveVRPerspectiveViewport(const Viewport& viewport, int x_off, int y_off);
|
|
|
|
// Select and consume the scene extent accumulated since the previous XFB copy. Returns
|
|
// true only when the VR presentation copy should sample a different vertical EFB region
|
|
// from the game's XFB copy. The caller must still use xfb_source for the emulated RAM copy.
|
|
bool ConsumeVRPresentationSourceRegion(const VRFrameRegion& xfb_source,
|
|
VRFrameRegion* presentation_source);
|
|
|
|
// Convert a pane-local NDC position to the pane's position in the full displayed frame.
|
|
// Used by both automatic small-pane routing and the explicit Screen Pane override.
|
|
std::array<float, 4> CalculateVRPaneRemap(const Viewport& viewport, int x_off, int y_off,
|
|
const VRFrameRegion& frame);
|
|
|
|
// Reference clip W for the perspective Screen Pane 3D transform. Most draws expose their model
|
|
// origin through the current position matrix. Skinned/per-vertex-matrix draws do not, so use the
|
|
// geometric centre of the projection's near/far range as a stable positive fallback.
|
|
float CalculateVRPaneReferenceW(float model_origin_view_z, float projection_z,
|
|
float projection_w);
|
|
|
|
const char* GetVRViewportClassName(VRViewportClass vclass);
|
|
} // namespace VR
|