Add adaptive resolution for the immersive eyes

[vr] adaptive_resolution (off by default, in the VR tab) lowers the
race's eye resolution by 10% steps, down to 70%, while new eye frames
fall below 85% of the game's 60 FPS, and raises it again after three
seconds on time. Adapted from heurazy/Wiicompiled_VR-PLUS.

The eyes render into the top-left corner of the full swapchain image
and the projection layer shows only that corner, so the compositor
upscales them and no swapchain is recreated, unlike render_scale. The
Linux same-device bridge now copies an eye smaller than its target;
the Quest's bridge and layer already did. The PC's D3D12 path copies
whole eyes, so the setting is not offered on Windows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sabhzu6VgoWcHtpSk4C9KZ
This commit is contained in:
Claude committed 2026-10-05 12:35:26 +00:00
1 parent 00034b17fc
commit 94bfc555c8
10 files changed
+207 -6

No files matched your search

+15
View File
@@ -101,6 +101,7 @@ struct RuntimeUserConfig {
std::optional<std::string> vrFoveation;
std::optional<bool> vrEyeTrackedFoveation;
std::optional<bool> vrRepeatFrames;
std::optional<bool> vrAdaptiveResolution;
std::optional<std::string> vrRecenterKey;
std::optional<float> vrLeanBackDegrees;
// F10 > Diagnostics: OpenXR pacing and presentation logging in console.log.
@@ -607,6 +608,10 @@ inline void EnsureConfigFile() {
"# Submit the last frame again for each refresh the game has no new\n"
"# frame for, so the runtime does not fill those refreshes itself. Live.\n"
"repeat_frames = " MKW_VR_REPEAT_FRAMES_DEFAULT_TOML "\n"
"# Lower the race's eye resolution, down to 70% of render_scale, while\n"
"# new frames fall behind the game's 60 FPS, and raise it again once\n"
"# they keep up. Experimental; the Steam Frame and the Quest. Live.\n"
"adaptive_resolution = false\n"
"render_scale = " MKW_VR_RENDER_SCALE_DEFAULT_TEXT "\n"
"world_units_per_meter = 500.0\n"
"hud_distance_meters = 2.0\n"
@@ -928,6 +933,7 @@ inline RuntimeUserConfig ParseConfigDocument(const toml::value& document) {
}
config.vrEyeTrackedFoveation = FindConfigValue<bool>(document, "vr", "eye_tracked_foveation");
config.vrRepeatFrames = FindConfigValue<bool>(document, "vr", "repeat_frames");
config.vrAdaptiveResolution = FindConfigValue<bool>(document, "vr", "adaptive_resolution");
if (auto value = FindConfigValue<std::string>(document, "vr", "mirror_view");
value && IsSupportedVrMirrorView(*value)) {
config.vrMirrorView = *value;
@@ -1345,6 +1351,11 @@ inline bool SetVrRepeatFrames(bool value) {
return WriteSetting("vr", "repeat_frames", value ? "true" : "false");
}
inline bool SetVrAdaptiveResolution(bool value) {
Mutable().vrAdaptiveResolution = value;
return WriteSetting("vr", "adaptive_resolution", value ? "true" : "false");
}
inline bool SetVrEyeTrackedFoveation(bool value) {
Mutable().vrEyeTrackedFoveation = value;
return WriteSetting("vr", "eye_tracked_foveation", value ? "true" : "false");
@@ -1880,6 +1891,10 @@ inline bool VrRepeatFrames(bool fallback = kVrRepeatFramesDefault) {
return Get().vrRepeatFrames.value_or(fallback);
}
inline bool VrAdaptiveResolution(bool fallback = false) {
return Get().vrAdaptiveResolution.value_or(fallback);
}
inline bool VrEyeTrackedFoveation(bool fallback = kVrEyeTrackedFoveationDefault) {
return Get().vrEyeTrackedFoveation.value_or(fallback);
}