Update foveation default settings to 'medium' for Quest compatibility

This commit is contained in:
iChris4 committed 2026-09-26 22:12:42 +02:00
1 parent c536f0087d
commit 333b263e9b
5 files changed
+21 -9

No files matched your search

+6 -4
View File
@@ -211,7 +211,7 @@ its CPU and GPU domains: `boost`, `sustained_high`, `sustained_low`, `power_savi
request (see `docs/quest-port.md`); desktop runtimes rarely offer the extension, and the setting
then does nothing. It is read at launch, and the session log records whether the runtime accepted
it and any later performance notification (a thermal or rendering warning).
`foveation` (Quest only, default `off`) shades the edges of the immersive race view more coarsely:
`foveation` (Quest only, default `medium`) shades the edges of the immersive race view more coarsely:
`off`, `low`, `medium` or `high`, see [Foveated rendering](#foveated-rendering). A session launched
with it off runs without fragment density maps, so going from `off` to a level takes a restart;
between levels, and back to `off`, it is live from the headset panel's VR tab. The launcher's
@@ -914,9 +914,11 @@ interleaved within one session (`docs/quest-port.md` has the method).
At the Quest's default 0.8 an eye's time goes mostly to geometry and to storing its tiles at full
resolution. The Wii's shading is cheap, so foveation saves nothing measurable there, although the
density map verifiably applies (4x4 blocks at the view's edges on High). That is why it defaults to
`off`. At higher render scales it takes 8 to 22% off the eyes, which is where it earns its keep,
bought with a softer periphery. The Quest's GPU applies the density per screen tile, and inside a
density map verifiably applies (4x4 blocks at the view's edges on High). At higher render scales it
takes 8 to 22% off the eyes, which is where it earns its keep, bought with a softer periphery. The
Quest defaults to `medium` all the same: it costs nothing measurable at 0.8, it is already on when
the render scale is raised, and a session launched with a level can change it live, where one
launched with `off` needs a restart. The Quest's GPU applies the density per screen tile, and inside a
reduced-rate tile it also samples textures one level blurrier per halving. Most surfaces hide it,
but fine animated detail does not: on Retro Rewind's swamp goo the tiles show as squares where the
ripples give way to a smoother look. It is no fix for a heavy track: on Retro Rewind's SNES Ghost Valley
@@ -228,7 +228,7 @@ class SettingsPage(
R.string.vr_foveation_off, R.string.vr_foveation_low,
R.string.vr_foveation_medium, R.string.vr_foveation_high,
),
read = { stringIndex(it, "vr", "foveation", FOVEATION_LEVELS) },
read = { stringIndex(it, "vr", "foveation", FOVEATION_LEVELS, FOVEATION_DEFAULT) },
write = { c, index -> c.setString("vr", "foveation", FOVEATION_LEVELS[index]) },
)
choice(
@@ -757,8 +757,9 @@ class SettingsPage(
val SEATS = listOf("cockpit", "custom")
// The runtime's default ("boost") first: an absent key reads as index 0.
val PERFORMANCE_LEVELS = listOf("boost", "sustained_high", "sustained_low", "power_savings", "default")
// runtime_config.h's kVrFoveationLevels, the default ("off") first.
// runtime_config.h's kVrFoveationLevels, and its Quest default.
val FOVEATION_LEVELS = listOf("off", "low", "medium", "high")
val FOVEATION_DEFAULT = FOVEATION_LEVELS.indexOf("medium")
val CONTROLLER_MODES = listOf("wii_remote", "gamepad", "none")
val INTERPOLATION_FPS = listOf(0L, 1L, 72L, 90L, 120L)
val RESOLUTIONS = listOf(1.0, 1.5, 2.0, 3.0, 4.0)
+3 -2
View File
@@ -179,8 +179,9 @@ at 0.8, and 492 to 525 MHz at 1.3, the unfoveated windows running at the higher
So an eye's time on these tracks is mostly geometry and full-resolution tile stores, which a
density map does not reduce (the stores stay full size for non-subsampled images). Foveation
stays off by default; it pays only when `render_scale` makes the eyes pixel-bound, as at 1.3 on
Luigi Circuit.
pays only when `render_scale` makes the eyes pixel-bound, as at 1.3 on Luigi Circuit; it
defaults to `medium` anyway, so it is already on when the render scale is raised and can be
changed without a restart.
### Quest 1 renderer compatibility
+5 -1
View File
@@ -261,8 +261,12 @@ inline bool IsSupportedVrPerformanceLevel(std::string_view value) {
// 4x4 pixel blocks, the higher the level the closer to the centre. Whether the
// GPU device gets fragment density maps at all is decided at launch, so going
// from "off" to a level takes a restart; between levels and back to "off" it is
// live.
// live. The Quest starts at "medium"; elsewhere it does nothing.
#if defined(__ANDROID__)
inline constexpr const char* kVrFoveationDefault = "medium";
#else
inline constexpr const char* kVrFoveationDefault = "off";
#endif
inline constexpr std::array<std::string_view, 4> kVrFoveationLevels{"off", "low", "medium", "high"};
inline bool IsSupportedVrFoveation(std::string_view value) {
+4
View File
@@ -23,7 +23,11 @@ int main() {
Require(!Parse("[vr]\nfoveation = \"ultra\"\n").vrFoveation.has_value());
Require(!Parse("[vr]\nfoveation = 2\n").vrFoveation.has_value());
Require(!Parse("[vr]\n").vrFoveation.has_value());
#if defined(__ANDROID__)
Require(std::string_view(RuntimeConfigFile::kVrFoveationDefault) == "medium");
#else
Require(std::string_view(RuntimeConfigFile::kVrFoveationDefault) == "off");
#endif
Require(RuntimeConfigFile::VrFoveationLevelIndex("off") == 0);
Require(RuntimeConfigFile::VrFoveationLevelIndex("low") == 1);
Require(RuntimeConfigFile::VrFoveationLevelIndex("medium") == 2);