mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 08:00:25 +02:00
[vr] refresh_rate (Hz, 0 = the headset's own) is requested through XR_FB_display_refresh_rate each time the session starts running and whenever the setting changes, matched against the runtime's own list within half a hertz. Setting it back to 0 restores the rate the session started at. A rate that is not offered, or one the runtime declines, is logged and changes nothing. The game renders 60 frames a second, so at 120 Hz every frame shows for exactly two refreshes, where 72 or 90 Hz hold some frames longer than others. The Steam Frame build defaults to 120; every other build keeps the headset's own rate unless the player picks one. The F10/headset panel and the Android launcher's Headset section offer the choice; the interpolation tooltip points at it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HBRGKTE1GnN2ah8gcZKr3
61 lines
3.1 KiB
C++
61 lines
3.1 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
#include "vr/frame_interpolation_pacing.h"
|
|
#include "runtime_config.h"
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
|
|
using mkw::vr::FrameInterpolationPacing;
|
|
|
|
static void Require(bool condition) {
|
|
if (!condition) std::abort();
|
|
}
|
|
|
|
int main() {
|
|
// [vr] refresh_rate picks the runtime's own value for the rate asked.
|
|
const float frame_rates[] = {72.0f, 90.0f, 119.98f, 144.0f};
|
|
Require(mkw::vr::MatchDisplayRefreshRate(frame_rates, 4, 120.0f) == 119.98f);
|
|
Require(mkw::vr::MatchDisplayRefreshRate(frame_rates, 4, 90.0f) == 90.0f);
|
|
Require(mkw::vr::MatchDisplayRefreshRate(frame_rates, 4, 60.0f) == 0.0f);
|
|
Require(mkw::vr::MatchDisplayRefreshRate(frame_rates, 4, 100.0f) == 0.0f);
|
|
Require(mkw::vr::MatchDisplayRefreshRate(frame_rates, 0, 120.0f) == 0.0f);
|
|
for (uint32_t target : {0u, 1u, 72u, 90u, 120u}) {
|
|
std::istringstream input("[vr]\nframe_interpolation_fps = " + std::to_string(target) + "\n");
|
|
const auto config = RuntimeConfigFile::ParseConfig(input);
|
|
Require(config.vrFrameInterpolationFps == target);
|
|
}
|
|
std::istringstream legacy("[vr]\nframe_interpolation = true\neager_frame_heartbeat = true\n");
|
|
Require(RuntimeConfigFile::ParseConfig(legacy).vrFrameInterpolationFps == 1);
|
|
std::istringstream explicitOff("[vr]\nframe_interpolation_fps = 0\nframe_interpolation = true\n");
|
|
Require(RuntimeConfigFile::ParseConfig(explicitOff).vrFrameInterpolationFps == 0);
|
|
std::istringstream missing("[vr]\n");
|
|
Require(!RuntimeConfigFile::ParseConfig(missing).vrFrameInterpolationFps.has_value());
|
|
for (uint32_t headset : {72u, 90u, 120u}) {
|
|
for (uint32_t target : {1u, 72u, 90u, 120u}) {
|
|
FrameInterpolationPacing pacing;
|
|
uint32_t rendered = 0;
|
|
// Ten seconds on the actual display grid, including noninteger ratios.
|
|
for (uint32_t frame = 0; frame < headset * 10; ++frame) {
|
|
const auto time = 1'000'000'000ll + static_cast<int64_t>(frame) * 1'000'000'000ll / headset;
|
|
if (pacing.ShouldRender(time, target)) ++rendered;
|
|
}
|
|
const auto expected = std::min(headset, target == 1 ? headset : target) * 10;
|
|
Require(std::abs(static_cast<int>(rendered) - static_cast<int>(expected)) <= 1);
|
|
}
|
|
}
|
|
FrameInterpolationPacing pacing;
|
|
Require(pacing.ShouldRender(1'000'000'000, 72));
|
|
Require(!pacing.ShouldRender(1'008'333'333, 72));
|
|
Require(pacing.ShouldRender(1'008'333'334, 120)); // Live target change.
|
|
Require(pacing.ShouldRender(5'000'000'000, 120)); // Stall: no catch-up burst.
|
|
Require(!pacing.ShouldRender(5'000'000'001, 120));
|
|
Require(pacing.ShouldRender(1'000'000, 120)); // New session clock.
|
|
pacing.Reset();
|
|
Require(pacing.ShouldRender(1'000'001, 120));
|
|
Require(mkw::vr::NormalizeFrameInterpolationFps(90) == 90);
|
|
Require(mkw::vr::NormalizeFrameInterpolationFps(1) == 1);
|
|
Require(mkw::vr::NormalizeFrameInterpolationFps(60) == 0);
|
|
Require(mkw::vr::NormalizeFrameInterpolationFps(UINT32_MAX) == 0);
|
|
std::cout << "VR interpolation pacing tests passed\n";
|
|
}
|