diff --git a/OPENXR.md b/OPENXR.md index 574e677..2d243a2 100644 --- a/OPENXR.md +++ b/OPENXR.md @@ -117,7 +117,8 @@ The old Eager Frame Heartbeat option has been removed and existing `eager_frame_ settings are ignored. Completed rendering wakes the XR thread immediately. A 50 ms keep-alive still protects pauses and window dragging without eager repeats during rendering. -`render_scale` scales the per-eye size recommended by the OpenXR runtime. +`render_scale` scales the per-eye size recommended by the OpenXR runtime. It defaults to 1.0 on PC +and 0.8 on the Quest, whose mobile GPU needs the headroom. `world_units_per_meter` controls the scale of headset translation in the game world. `hud_distance_meters` and `hud_width_meters` place and size the virtual screen. They are read at launch and govern both the menu screen and the in-race 2D screen, so 2D content keeps its place diff --git a/android/app/src/main/java/org/wiicompiled/quest/GameStorage.kt b/android/app/src/main/java/org/wiicompiled/quest/GameStorage.kt index 92a04fc..e535c3e 100644 --- a/android/app/src/main/java/org/wiicompiled/quest/GameStorage.kt +++ b/android/app/src/main/java/org/wiicompiled/quest/GameStorage.kt @@ -20,6 +20,8 @@ object GameStorage { const val DISC_DIRECTORY = "DATA" /** The Retro Rewind pack the modded product reads (`[paths] retro_rewind_root`). */ const val MOD_DIRECTORY = "RetroRewind6" + /** `[vr] render_scale` until the player changes it; must match kVrRenderScaleDefault on Android. */ + const val DEFAULT_RENDER_SCALE = 0.8 enum class DiscStatus { Missing, Incomplete, Ready } @@ -91,7 +93,7 @@ object GameStorage { "", "[vr]", "enabled = true", - "render_scale = 1.0", + "render_scale = $DEFAULT_RENDER_SCALE", ) config.writeText(lines.joinToString("\n", postfix = "\n")) } else { diff --git a/android/app/src/main/java/org/wiicompiled/quest/launcher/SettingsPage.kt b/android/app/src/main/java/org/wiicompiled/quest/launcher/SettingsPage.kt index 914e6e0..2ba8ee8 100644 --- a/android/app/src/main/java/org/wiicompiled/quest/launcher/SettingsPage.kt +++ b/android/app/src/main/java/org/wiicompiled/quest/launcher/SettingsPage.kt @@ -161,7 +161,7 @@ class SettingsPage( section(R.string.section_vr_headset) { slider( R.string.vr_render_scale, R.string.vr_render_scale_helper, 0.25, 2.0, 0.05, - read = { number(it, "vr", "render_scale", 0.25, 2.0, 1.0) }, + read = { number(it, "vr", "render_scale", 0.25, 2.0, GameStorage.DEFAULT_RENDER_SCALE) }, format = { "%.2f×".format(it) }, write = { c, value -> c.setFloat("vr", "render_scale", value) }, ) diff --git a/docs/quest-port.md b/docs/quest-port.md index 1be513e..fbde6a3 100644 --- a/docs/quest-port.md +++ b/docs/quest-port.md @@ -670,8 +670,9 @@ or `EndAccess` errors); a black mirror too points at Aurora itself. - **Performance.** The desktop product targets x86-64-v3; nothing has been profiled on the XR2. The first run compiles every bundled pipeline recipe (about half a minute); later runs load Dawn's pipeline cache from `Cache/` - next to `DATA`. Start with `render_scale` below 1.0 if the - compositor reports missed frames. `XR_FB_foveation` is not used yet. + next to `DATA`. `render_scale` defaults to 0.8 here (1.0 on + PC); lower it further if the compositor reports missed frames. + `XR_FB_foveation` is not used yet. - **Lifecycle.** Backgrounding (the Quest menu, guardian) pauses the session through the ordinary `STOPPING`/`READY` events; SDL's Android surface loss is handled by Aurora's existing Android paths. Neither has been exercised. diff --git a/runtime/include/runtime_config.h b/runtime/include/runtime_config.h index 2c1e40c..63ed564 100644 --- a/runtime/include/runtime_config.h +++ b/runtime/include/runtime_config.h @@ -164,6 +164,17 @@ inline constexpr int kPortableSearchDepth = 4; inline constexpr uint32_t kPostProcessingBloomPath = 0x10u; inline constexpr uint32_t kDisabledPostProcessingPathsDefault = kPostProcessingBloomPath; +// Headset eye size as a fraction of what the OpenXR runtime recommends. A +// standalone headset renders on a mobile GPU, so the Quest starts below it; +// the launcher's first Config.toml (GameStorage.kt) writes the same value. +#if defined(__ANDROID__) +inline constexpr float kVrRenderScaleDefault = 0.8f; +#define MKW_VR_RENDER_SCALE_DEFAULT_TEXT "0.8" +#else +inline constexpr float kVrRenderScaleDefault = 1.0f; +#define MKW_VR_RENDER_SCALE_DEFAULT_TEXT "1.0" +#endif + // First-person camera defaults and the range its head offsets accept, in one // place: the config getters, the on-disk template and the F10 bar's reset all // read them from here, so they cannot drift apart again. @@ -427,7 +438,7 @@ inline void EnsureConfigFile() { "controller_mode = \"wii_remote\"\n" "# VR interpolation: 0 = Off, 1 = Auto, or 72/90/120 FPS. Live.\n" "frame_interpolation_fps = 0\n" - "render_scale = 1.0\n" + "render_scale = " MKW_VR_RENDER_SCALE_DEFAULT_TEXT "\n" "world_units_per_meter = 500.0\n" "hud_distance_meters = 2.0\n" "hud_width_meters = 2.4\n" @@ -1307,7 +1318,7 @@ inline bool VrRequired(bool fallback = false) { return Get().vrRequired.value_or(fallback); } -inline float VrRenderScale(float fallback = 1.0f) { +inline float VrRenderScale(float fallback = kVrRenderScaleDefault) { return std::clamp(Get().vrRenderScale.value_or(fallback), 0.25f, 2.0f); } diff --git a/runtime/src/vr/openxr_integration.cpp b/runtime/src/vr/openxr_integration.cpp index 4073be1..f66aef4 100644 --- a/runtime/src/vr/openxr_integration.cpp +++ b/runtime/src/vr/openxr_integration.cpp @@ -365,7 +365,7 @@ public: config.application_name = aurora_config.appName != nullptr ? aurora_config.appName : "WiiCompiled"; config.engine_name = "Aurora"; - config.resolution_scale = RuntimeConfigFile::VrRenderScale(1.0f); + config.resolution_scale = RuntimeConfigFile::VrRenderScale(); #if defined(_WIN32) config.required_extensions = {"XR_KHR_D3D12_enable"}; config.optional_extensions = {"XR_KHR_win32_convert_performance_counter_time",