Monado OpenXR Runtime
Loading...
Searching...
No Matches
openvr_compositor.hpp
Go to the documentation of this file.
1// Copyright 2026, Beyley Cardellio
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Implementation of compositor-related functionality for OpenVR.
6 *
7 * @author Beyley Cardellio <ep1cm1n10n123@gmail.com>
8 * @ingroup openvr
9 */
10
11#pragma once
12
13#include "xrt/xrt_compositor.h"
14#include "xrt/xrt_config_build.h"
15#include "xrt/xrt_device.h"
16#include "xrt/xrt_system.h"
17#include "xrt/xrt_gfx_vk.h"
18
19#ifdef XRT_HAVE_VULKAN
20#include "vk/vk_helpers.h"
21#include "vk/vk_cmd_pool.h"
22
25#endif
26
27#include "util/u_time.h"
28
30
31#include "openvr_interfaces_unified.h"
32
33#include "openvr_events.hpp"
34
35#include <array>
36#include <optional>
37#include <memory>
38
39
40namespace xrt::state_trackers::openvr {
41
43{
44 //! The swapchain in use
45 xrt_swapchain *xsc{nullptr};
46 //! The index into the eye's swapchain for the currently held texture.
48
49 //! The width of the currently held runtime swapchain texture.
50 uint32_t width;
51 //! The height of the currently held runtime swapchain texture.
52 uint32_t height;
53
54 //! The sub-image of the runtime swapchain texture to submit to the compositor.
56
58 {
59 if (this->xsc != nullptr) {
60 xrt_swapchain_release_image(this->xsc, this->swapchain_index);
61 }
62
63 xrt_swapchain_reference(&this->xsc, nullptr);
64 }
65};
66
68{
70};
71
73{
74 int64_t frame_id{-1};
75 timepoint_ns predicted_display_time{0};
76 time_duration_ns predicted_display_period{0};
77};
78
79/*!
80 * Since eye textures are created by the clients, and not the runtime, we have to do a copy into a runtime-owned
81 * swapchain, this structure cached created swapchains to avoid creating a new one every frame.
82 */
84{
85public: // Fields
86 xrt_swapchain *xsc{nullptr};
87
88 uint32_t width{0};
89 uint32_t height{0};
90 uint32_t storage_format{0};
91 uint32_t sample_format{0};
92
93public: // Methods
94 //! Ensures that there is a swapchain in the cache with the given properties, creating one if necessary.
97 uint32_t storage_format,
98 uint32_t sample_format,
99 uint32_t width,
100 uint32_t height,
101 xrt_swapchain_usage_bits usage_bits,
103
104 //! Resets the internal state of the cache, releasing any swapchain it holds.
105 void
106 Reset();
107
109};
110
112{
113 std::array<xrt_fov, 2> fovs;
114 std::array<xrt_pose, 2> T_head_eyes;
115
116 xrt_pose head_relation;
117};
118
120{
121private: // Fields
122 //! The state for the current active frame
123 std::optional<FrameState> active_frame{std::nullopt};
124 //! The state for each submit eye.
125 std::array<std::optional<EyeState>, 2> frame_eye_states{std::nullopt, std::nullopt};
126 //! Caches of swapchains for each eye, keyed by the runtime storage/sample formats and eye image size.
127 std::array<SwapchainCache, 2> swapchain_caches{};
128
129 //! The active system devices
130 xrt_system_devices *xsysd{nullptr};
131
132 //! The current native compositor
133 xrt_compositor_native *xcn{nullptr};
134
135 xrt_system_compositor *xsysc{nullptr};
136
137 //! The currently active compositor, implicitly also has an active session.
138 xrt_compositor *active_compositor{nullptr};
139
140#ifdef XRT_HAVE_VULKAN
141 //! The active Vulkan compositor.
142 struct xrt_compositor_vk *xc_vk{nullptr};
143
144 //! The vk_bundle for the compositor.
145 vk_bundle *vk{nullptr};
146
147 //! The command buffer pool for doing compositor work.
148 vk_cmd_pool *cmd_pool;
149
150 //! The shaders for the compositor.
151 render_shaders shaders;
152
153 struct
154 {
155 //! The sampler to use during the blit operation
156 VkSampler sampler{VK_NULL_HANDLE};
157
158 //! Private here for now.
159 VkPipelineCache pipeline_cache{VK_NULL_HANDLE};
160
161 //! Pipeline layout for blit pipelines.
162 VkPipelineLayout pipeline_layout{VK_NULL_HANDLE};
163
164 //! Descriptor pool for blit.
165 VkDescriptorPool descriptor_pool{VK_NULL_HANDLE};
166
167 //! Descriptor set layout for blit.
168 VkDescriptorSetLayout descriptor_set_layout{VK_NULL_HANDLE};
169
170 //! Descriptor set for blit.
171 VkDescriptorSet descriptor_set{VK_NULL_HANDLE};
172
173 //! The pipelines for blitting/copying app textures into runtime swapchain images.
174 std::array<VkPipeline, RENDER_BLIT_RESOLVE_COLOR_MODE_COUNT> pipelines{};
175 } blit;
176#endif
177
178 std::optional<RenderStateCache> render_state_cache{std::nullopt};
179
180 std::shared_ptr<Events> events{};
181
182public: // Fields
183 std::optional<timepoint_ns> last_predicted_display_time{std::nullopt};
184 std::optional<time_duration_ns> last_predicted_display_period{std::nullopt};
185
186 std::array<vr::TrackedDevicePose_t, vr::k_unMaxTrackedDeviceCount> last_render_poses{};
187 std::array<vr::TrackedDevicePose_t, vr::k_unMaxTrackedDeviceCount> last_game_poses{};
188
189 vr::ETrackingUniverseOrigin current_tracking_universe{vr::ETrackingUniverseOrigin::TrackingUniverseSeated};
190
191private: // Methods
192#ifdef XRT_HAVE_VULKAN
194 SetupBlitPipelines(openvr_logger &logger);
195
196 //! Sets up the Vulkan compositor as the active compositor, and begins the session.
198 SetupVulkanCompositor(openvr_logger &logger, vr::VRVulkanTextureData_t &vulkan_data);
199
200 void
201 DestroyVulkanResources();
202
204 TransferAppImageToSwapchainImage(openvr_logger &logger,
205 xrt_swapchain *xsc,
206 uint32_t dst_index,
207 vr::VRVulkanTextureData_t &texture_data,
208 VkFormat storage_format,
209 vr::EColorSpace color_space,
210 const xrt_rect &rect);
211
212 //! Handles submission of a Vulkan texture, which involves copying it into a runtime-owned swapchain image.
213 vr::EVRCompositorError
214 SubmitVulkan(openvr_logger &logger,
215 vr::EVREye eye,
216 vr::VRVulkanTextureData_t &texture_data,
217 vr::EColorSpace color_space,
218 const vr::VRTextureBounds_t &bounds);
219
220 void
221 GetVulkanOutputDevice(openvr_logger &logger, uint64_t *out_device, VkInstance pInstance);
222#endif
223
224 //! Gets the projection layer data from the passed eye state
226 GetProjectionLayerDataForEye(vr::EVREye eye, const EyeState &eye_state);
227
228 //! Completes a frame and submits textures to the runtime.
229 vr::EVRCompositorError
230 CompleteFrame(openvr_logger &logger);
231
232public: // Methods
236 std::shared_ptr<Events> &events);
237
238 ~Compositor();
239
240 /*!
241 * Waits for the next frame and begins it, cancelling/releasing any previously active frame and it's resources,
242 * if it exists.
243 */
244 vr::EVRCompositorError
246
247 //! Submits a texture for an eye, completing the frame if both eyes have been submit.
248 vr::EVRCompositorError
249 Submit(openvr_logger &logger,
250 vr::EVREye eye,
251 const vr::Texture_t &texture,
252 const vr::VRTextureBounds_t &bounds,
253 vr::EVRSubmitFlags nSubmitFlags);
254
255 void
256 GetOutputDevice(openvr_logger &logger,
257 uint64_t *out_device,
258 vr::ETextureType texture_type,
259 VkInstance pInstance);
260
262 GetTimeForPredictions();
263
265 GetFramePeriod();
266
268 GetFrameRenderState(std::array<xrt_fov, 2> &fovs,
269 std::array<xrt_pose, 2> &T_head_eyes,
270 xrt_pose &head_relation);
271};
272
273}; // namespace xrt::state_trackers::openvr
int64_t timepoint_ns
Integer timestamp type.
Definition u_time.h:77
int64_t time_duration_ns
Integer duration type in nanoseconds.
Definition u_time.h:88
xrt_swapchain_usage_bits
Usage of the swapchain images.
Definition xrt_compositor.h:563
xrt_swapchain_create_flags
Special flags for creating swapchain images.
Definition xrt_compositor.h:545
enum xrt_result xrt_result_t
Result type used across Monado.
Implementation of OpenVR event handling and related functionality.
Logging functions.
The NEW compositor rendering code header.
Shader loading interface.
Definition m_space.cpp:87
Holds all shaders.
Definition render_shaders_interface.h:26
Helper struct to make code easier to read.
Definition render_distortion.c:183
A bundle of Vulkan functions and objects, used by both Compositor and Compositor client code.
Definition vk_helpers.h:81
Small helper to manage lock around a command pool.
Definition vk_cmd_pool.h:33
Definition openvr_compositor.hpp:120
vr::EVRCompositorError Submit(openvr_logger &logger, vr::EVREye eye, const vr::Texture_t &texture, const vr::VRTextureBounds_t &bounds, vr::EVRSubmitFlags nSubmitFlags)
Submits a texture for an eye, completing the frame if both eyes have been submit.
Definition openvr_compositor.cpp:208
vr::EVRCompositorError WaitBeginFrame(openvr_logger &logger)
Waits for the next frame and begins it, cancelling/releasing any previously active frame and it's res...
Definition openvr_compositor.cpp:142
Definition openvr_compositor.hpp:68
Definition openvr_compositor.hpp:43
xrt_swapchain * xsc
The swapchain in use.
Definition openvr_compositor.hpp:45
xrt_rect bounds
The sub-image of the runtime swapchain texture to submit to the compositor.
Definition openvr_compositor.hpp:55
uint32_t swapchain_index
The index into the eye's swapchain for the currently held texture.
Definition openvr_compositor.hpp:47
uint32_t width
The width of the currently held runtime swapchain texture.
Definition openvr_compositor.hpp:50
uint32_t height
The height of the currently held runtime swapchain texture.
Definition openvr_compositor.hpp:52
Definition openvr_compositor.hpp:73
Definition openvr_compositor.hpp:112
Since eye textures are created by the clients, and not the runtime, we have to do a copy into a runti...
Definition openvr_compositor.hpp:84
void Reset()
Resets the internal state of the cache, releasing any swapchain it holds.
Definition openvr_compositor.cpp:94
xrt_result_t EnsureSwapchain(xrt_compositor *xc, uint32_t storage_format, uint32_t sample_format, uint32_t width, uint32_t height, xrt_swapchain_usage_bits usage_bits, xrt_swapchain_create_flags flags)
Ensures that there is a swapchain in the cache with the given properties, creating one if necessary.
Definition openvr_compositor.cpp:31
Definition openvr_logger.hpp:30
Main compositor server interface.
Definition xrt_compositor.h:2290
Base class for a Vulkan client compositor.
Definition xrt_compositor.h:2085
Common compositor client interface/base.
Definition xrt_compositor.h:1046
All of the pure data values associated with a single view in a projection layer.
Definition xrt_compositor.h:261
A pose composed of a position and orientation.
Definition xrt_defines.h:492
Image rectangle.
Definition xrt_defines.h:457
Common swapchain interface/base.
Definition xrt_compositor.h:593
The system compositor handles composition for a system.
Definition xrt_compositor.h:2531
A collection of xrt_device, and an interface for identifying the roles they have been assigned.
Definition xrt_system.h:215
Time-keeping: a clock that is steady, convertible to system time, and ideally high-resolution.
Command pool helpers.
Common Vulkan code header.
Header declaring XRT graphics interfaces.
Header defining an xrt display or controller device.
Header defining an XRT graphics provider.
Header for system objects.