Added foveated rendering for the Quest

- Eyes render under a VK_EXT_fragment_density_map: full rate around each eye's forward direction,
  2x2 then 4x4 pixel blocks towards the edges ([vr] foveation = off|low|medium|high, default off).
  XR_FB_foveation cannot help here: the runtime's maps only shape passes drawing into its
  swapchain, and the eyes reach it through a copy.
- aurora-main/patches/dawn/aurora_fdm.inc: Dawn enables the extension only on request and for
  dynamic rendering, flags every render pipeline, and chains an immutable RG8 map into any pass
  whose first color attachment is a view bound to one (ABI: include/aurora/dawn_fdm_abi.h).
- android/Build-QuestDawn.ps1 builds the pinned Dawn revision with those patches for arm64
  (dawn-build CI flags, protobuf off) into a cached package; Build-Quest.ps1 links it
  (-StockDawn opts out) and AuroraDawnProvider.cmake enables the ABI from its manifest.
- lib/gfx/foveation.hpp generates the maps (32 px per texel, densities 255/127/63); an eye is
  foveated only when single_pass_eyes draws it in one render pass. Menus never are.
- Live level from the headset panel's VR tab and the launcher; the launch decides whether the
  device has maps. debug.wiicompiled.foveation and debug.wiicompiled.fdm for A/B.
- Tests: Foveation cases in gx_fifo_tests, mkw_vr_config_tests. Docs: OPENXR.md, quest-port.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
iChris4andClaude Opus 5.5 committed 2026-09-24 19:03:17 +02:00
1 parent ceeeba0332
commit cc653272c8
30 files changed
+1527 -14

No files matched your search

+12
View File
@@ -36,6 +36,18 @@ if(DEFINED MKW_DEPENDENCIES_DIR AND IS_DIRECTORY "${MKW_DEPENDENCIES_DIR}")
endforeach()
endif()
# The Dawn package android/Build-QuestDawn.ps1 built with Aurora's patches (fragment density maps for
# foveated rendering) stands in for the stock prebuilt one. The override lives in this build
# directory's cache, so a build without the package clears it rather than keep the last one.
if(DEFINED MKW_QUEST_DAWN_PACKAGE_DIR AND NOT MKW_QUEST_DAWN_PACKAGE_DIR STREQUAL "")
if(NOT EXISTS "${MKW_QUEST_DAWN_PACKAGE_DIR}/aurora-dawn.json")
message(FATAL_ERROR "No patched Dawn package at ${MKW_QUEST_DAWN_PACKAGE_DIR}; run android/Build-QuestDawn.ps1")
endif()
set(FETCHCONTENT_SOURCE_DIR_DAWN_PREBUILT "${MKW_QUEST_DAWN_PACKAGE_DIR}" CACHE PATH "" FORCE)
else()
unset(FETCHCONTENT_SOURCE_DIR_DAWN_PREBUILT CACHE)
endif()
find_package(SDL3 REQUIRED CONFIG)
set(AURORA_SDL3_PROVIDER system CACHE STRING "" FORCE)
set(AURORA_SDL3_LINKAGE shared CACHE STRING "" FORCE)
@@ -200,6 +200,15 @@ class SettingsPage(
read = { stringIndex(it, "vr", "performance_level", PERFORMANCE_LEVELS) },
write = { c, index -> c.setString("vr", "performance_level", PERFORMANCE_LEVELS[index]) },
)
choice(
R.string.vr_foveation, R.string.vr_foveation_helper,
listOf(
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) },
write = { c, index -> c.setString("vr", "foveation", FOVEATION_LEVELS[index]) },
)
choice(
R.string.vr_interpolation, R.string.vr_interpolation_helper,
listOf(activity.getString(R.string.vr_interpolation_off), activity.getString(R.string.vr_interpolation_auto), "72 FPS", "90 FPS", "120 FPS"),
@@ -725,6 +734,8 @@ 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.
val FOVEATION_LEVELS = listOf("off", "low", "medium", "high")
val CONTROLLER_MODES = listOf("wii_remote", "gamepad")
val INTERPOLATION_FPS = listOf(0L, 1L, 72L, 90L, 120L)
val RESOLUTIONS = listOf(1.0, 1.5, 2.0, 3.0, 4.0)
@@ -543,6 +543,12 @@
<string name="vr_performance_level_sustained_low">Sustained low</string>
<string name="vr_performance_level_power_savings">Power savings</string>
<string name="vr_performance_level_default">Headset default</string>
<string name="vr_foveation">Foveated rendering</string>
<string name="vr_foveation_helper">Shades the edges of the race view in coarser blocks, where the lenses blur the picture anyway, to free GPU time for a higher render scale or a steadier frame rate. Higher levels start closer to the centre; High also coarsens the corners of the HUD. Menus are never foveated.</string>
<string name="vr_foveation_off">Off</string>
<string name="vr_foveation_low">Low</string>
<string name="vr_foveation_medium">Medium</string>
<string name="vr_foveation_high">High</string>
<string name="vr_interpolation">VR frame interpolation</string>
<string name="vr_interpolation_helper">Experimental. Renders extra frames between game frames at the headset\'s rate. Needs GPU headroom and adds one game frame of latency.</string>
<string name="vr_interpolation_off">Off</string>