Render through public Qt API: OpenGL and Vulkan backends, --graphics-api

Replace the QRhi rendering in OverlayController (private Qt API) with the
render backends of the vrdashboard template (src/render/), which use public
Qt API only (QQuickRenderTarget::fromOpenGLTexture / fromVulkanImage). The
binary then runs on another Qt 6 patch release, e.g. the Steam Frame's system
Qt.

The Vulkan backend also does what SteamVR requires and the QRhi path lacked:
the required instance/device extensions and the HMD's GPU (via
openvr_init::renderInterop()), VK_FORMAT_R8G8B8A8_UNORM, and the transition to
TRANSFER_SRC_OPTIMAL after each frame.

- New option --graphics-api opengl|vulkan (default opengl, no fallback).
- Shutdown() calls VR_Shutdown before the render target and Qt's device go
  (crash on the Steam Frame with Vulkan otherwise); it runs only once.
- Mouse y is flipped on every platform: SteamVR reports it in GL convention.
- Render delay 5 -> 16 ms (about 60 fps).
- GuiPrivate is no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Matthias Janetschek
2026-10-07 13:41:13 +02:00
co-authored by Claude Opus 5.5
parent 423ea57db7
commit 4826686a4d
15 changed files with 1243 additions and 140 deletions
+22 -7
View File
@@ -13,11 +13,9 @@ set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
#find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Multimedia Qml Quick WebSockets Widgets QuickControls2 QuickDialogs2 Svg)
#find_package(Qt${QT_VERSION_MAJOR} OPTIONAL_COMPONENTS DBus)
# Core5Compat removed: nothing uses it, and the Steam Frame's system Qt
# doesn't ship it.
# GuiPrivate: QRhi (overlaycontroller.cpp) needs it. Since Qt 6.10 private
# modules must be requested explicitly. Temporary: it goes away when rendering
# switches to public API (docs/steamframe/DESIGN.md, section 3).
find_package(Qt6 REQUIRED COMPONENTS Gui Multimedia Qml Quick WebSockets Widgets QuickControls2 QuickDialogs2 Svg Qml GuiPrivate)
# doesn't ship it. No private Qt modules: the binary must run on another Qt 6
# patch release, e.g. the Frame's system Qt (docs/steamframe/DESIGN.md).
find_package(Qt6 REQUIRED COMPONENTS Gui Multimedia Qml Quick WebSockets Widgets QuickControls2 QuickDialogs2 Svg Qml)
find_package(Vulkan REQUIRED)
qt_standard_project_setup(REQUIRES 6.8)
@@ -69,6 +67,8 @@ set(SRCS
src/utils/paths.cpp
src/utils/setup.cpp
src/utils/update_rate.cpp
src/render/RenderBackend.cpp
src/render/OpenGLRenderBackend.cpp
)
set(HEADERS
@@ -112,6 +112,8 @@ set(HEADERS
src/utils/setup.h
src/utils/update_rate.h
src/utils/platform_capabilities.h
src/render/RenderBackend.h
src/render/OpenGLRenderBackend.h
src/utils/Matrix.h
src/quaternion/quaternion.h
)
@@ -291,6 +293,21 @@ target_compile_definitions(AdvancedSettings PRIVATE
APPLICATION_VERSION=\"${PROJECT_VERSION}\"
)
# Vulkan render backend (src/render/VulkanRenderBackend.*), selected at run
# time with --graphics-api vulkan. Needs a Qt built with Vulkan support; the
# Vulkan headers come from find_package(Vulkan) above. Nothing links against
# libvulkan: Qt loads it at run time.
if (QT_FEATURE_vulkan)
target_sources(AdvancedSettings PRIVATE
src/render/VulkanRenderBackend.cpp
src/render/VulkanRenderBackend.h
)
target_compile_definitions(AdvancedSettings PRIVATE OVRAS_HAS_VULKAN=1)
else ()
target_compile_definitions(AdvancedSettings PRIVATE OVRAS_HAS_VULKAN=0)
endif ()
message(STATUS "Vulkan render backend: ${QT_FEATURE_vulkan}")
# Build for the Steam Frame (SteamOS, aarch64). Switches off what doesn't work
# there and changes some defaults; the details are named capability constants
# in src/utils/platform_capabilities.h, the only place reading this definition.
@@ -324,8 +341,6 @@ target_link_directories(AdvancedSettings PRIVATE ${OPENVR_LIB_DIR})
target_link_libraries(AdvancedSettings PRIVATE
Qt::Gui
# For QRhi; temporary, see find_package(Qt6 ...) above.
Qt::GuiPrivate
Qt::Multimedia
Qt::Qml
Qt::Quick