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

@@ -150,8 +150,11 @@ public:
for (uint32_t i = 0; i < images; ++i) {
const auto& eye = sources[i];
const auto& target = targets[i];
if (!eye.texture || eye.size.width != target.width || eye.size.height != target.height ||
!CopyCompatible(VkFormat(eye.format), target.dxgiFormat)) return false;
// An eye smaller than its target goes in the target's top-left corner, which is all the
// projection layer shows of it; the panel and the virtual screen are always full size.
const bool fits = i < count ? eye.size.width <= target.width && eye.size.height <= target.height
: eye.size.width == target.width && eye.size.height == target.height;
if (!eye.texture || !fits || !CopyCompatible(VkFormat(eye.format), target.dxgiFormat)) return false;
const uint64_t image = reinterpret_cast<uintptr_t>(target.resource);
auto it = std::find_if(imports.begin(), imports.end(), [&](const Import& entry) { return entry.image == image; });
if (it == imports.end()) {
@@ -179,7 +182,7 @@ public:
wgpu::TexelCopyTextureInfo source, destination;
source.texture = *sources[i].texture;
destination.texture = active[i];
wgpu::Extent3D size{targets[i].width, targets[i].height, 1};
wgpu::Extent3D size{sources[i].size.width, sources[i].size.height, 1};
encoder.CopyTextureToTexture(&source, &destination, &size);
}
encoded = true;