render: derive the auto frame cap from a refresh-scaled margin (SDK bump)

This commit is contained in:
mchughalex 2026-07-24 13:33:52 +01:00
parent 49690b290b
commit a37e74fb4d
2 changed files with 17 additions and 11 deletions

View file

@ -47,13 +47,18 @@ REXCVAR_DEFINE_DOUBLE(skate3_guest_fps_cap, 0.0, "Skate 3",
.lifecycle(rex::cvar::Lifecycle::kHotReload); .lifecycle(rex::cvar::Lifecycle::kHotReload);
REXCVAR_DEFINE_BOOL(skate3_guest_fps_cap_auto, true, "Skate 3", REXCVAR_DEFINE_BOOL(skate3_guest_fps_cap_auto, true, "Skate 3",
"Derive the guest frame cap from the display the window is on: " "Derive the guest frame cap from the display the window is on: "
"cap at (refresh rate - 4) fps, the VRR recipe above, without " "cap a safety margin below the refresh rate (4 fps or 5%, "
"hand-tuning per monitor. Above the display refresh the extra " "whichever is larger; see rex::ui::Window::AutoFrameCapHz), "
"frames cannot be shown anyway; refreshes beat-sample the " "the VRR recipe above, without hand-tuning per monitor. Above "
"frame stream and steady motion judders (measured: a " "the display refresh the extra frames cannot be shown anyway; "
"mathematically perfect synthetic pan judders at 330 fps on a " "refreshes beat-sample the frame stream and steady motion "
"144 Hz panel and is smooth capped below it). Overrides " "judders (measured: a mathematically perfect synthetic pan "
"skate3_guest_fps_cap while the display refresh is known.") "judders at 330 fps on a 144 Hz panel and is smooth capped "
"below it). The margin must also absorb swap-to-present "
"jitter: presents run with tearing allowed, so a present "
"landing inside the panel's minimum refresh period tears even "
"under VRR. Overrides skate3_guest_fps_cap while the display "
"refresh is known.")
.lifecycle(rex::cvar::Lifecycle::kHotReload); .lifecycle(rex::cvar::Lifecycle::kHotReload);
namespace skate3::native_render { namespace skate3::native_render {
@ -228,9 +233,10 @@ void PaceGuestFrame() {
if (REXCVAR_GET(skate3_guest_fps_cap_auto)) { if (REXCVAR_GET(skate3_guest_fps_cap_auto)) {
// Refresh-derived cap (see the cvar). Falls through to the explicit cap // Refresh-derived cap (see the cvar). Falls through to the explicit cap
// while the platform hasn't reported a refresh rate. // while the platform hasn't reported a refresh rate.
const double hz = double(rex::ui::Window::CachedDisplayRefreshHz()); const double auto_cap = double(rex::ui::Window::AutoFrameCapHz(
if (hz >= 30.0) { rex::ui::Window::CachedDisplayRefreshHz()));
cap = hz - 4.0; if (auto_cap > 0.0) {
cap = auto_cap;
} }
} }
static std::chrono::steady_clock::time_point s_next{}; static std::chrono::steady_clock::time_point s_next{};

@ -1 +1 @@
Subproject commit 79761cbdd5752e43422e93f0903ef604ef7e4650 Subproject commit 9100b278b70c4f0994a47639eb11107c570ee76d