The open source OpenXR runtime
1// Copyright 2019-2024, Collabora, Ltd.
2// Copyright 2024-2025, NVIDIA CORPORATION.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Higher level interface for rendering a frame.
7 * @author Jakob Bornecrantz <tbornecrantz@nvidia.com>
8 * @author Christoph Haag <christoph.haag@collabora.com>
9 * @author Fernando Velazquez Innella <finnella@magicleap.com>
10 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
11 * @ingroup comp_util
12 */
13
14#pragma once
15
16
17#include "render/render_interface.h"
18
19#include "comp_render.h"
20#include "comp_high_level_scratch.h"
21
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27
28/*!
29 * Encapsulates all the needed state to run the layer squasher and distortion
30 * passes, state object needs to be kept alive until the GPU work finishes.
31 * None of the functions are thread safe so make sure to synchronize access.
32 *
33 * The lifetime of this struct is one frame, but as stated above it needs to
34 * live for long enough that the GPU work has been finished.
35 *
36 * @comp_util
37 */
38struct chl_frame_state
39{
40 struct chl_scratch *scratch;
41
42 uint32_t view_count;
43
44 struct chl_scratch_state scratch_state;
45
46 struct comp_render_dispatch_data data;
47
48 struct render_compute cs;
49};
50
51
52/*
53 *
54 * Shared functions.
55 *
56 */
57
58/*!
59 * Create the Vulkan resources using the given @p render_resources and the
60 * @p vk_bundle it refers to. Is used for both graphics and compute paths,
61 * also manages the scratch state.
62 *
63 * @memberof chl_frame_state
64 */
65void
66chl_frame_state_init(struct chl_frame_state *frame_state,
67 struct render_resources *rr,
68 uint32_t view_count,
69 bool do_timewarp,
70 bool fast_path,
71 struct chl_scratch *scratch);
72
73/*!
74 * Frees all resources that this frame state tracks and manages the scratch
75 * images state. Must be called after the GPU work has finished and has been
76 * waited on (or the validation layer gets upset).
77 *
78 * @memberof chl_frame_state
79 */
80void
81chl_frame_state_fini(struct chl_frame_state *state);
82
83
84/*
85 *
86 * Graphics.
87 *
88 */
89
90/*!
91 * Sets all the needed state to run the layer squasher to the scratch images,
92 * this is the graphics version.
93 *
94 * @memberof chl_frame_state
95 */
96void
97chl_frame_state_gfx_set_views(struct chl_frame_state *frame_state,
98 const struct xrt_pose world_pose[XRT_MAX_VIEWS],
99 const struct xrt_pose eye_pose[XRT_MAX_VIEWS],
100 const struct xrt_fov fov[XRT_MAX_VIEWS],
101 uint32_t layer_count);
102
103/*!
104 * Adds the needed information to also perform a distortion step, reuses some
105 * information from the _set_views call and as such this needs to be called
106 * before calling this function. This is the graphics version.
107 *
108 * @memberof chl_frame_state
109 */
110void
111chl_frame_state_gfx_set_target(struct chl_frame_state *frame_state,
112 struct render_gfx_target_resources *target_rtr,
113 const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS],
114 const struct xrt_matrix_2x2 vertex_rots[XRT_MAX_VIEWS]);
115
116/*!
117 * A single do all function, runs the default graphics pipeline.
118 *
119 * @memberof chl_frame_state
120 */
121static inline void
122chl_frame_state_gfx_default_pipeline(struct chl_frame_state *frame_state,
123 struct render_gfx *render,
124 const struct comp_layer *layers,
125 uint32_t layer_count,
126 const struct xrt_pose world_poses[XRT_MAX_VIEWS],
127 const struct xrt_pose eye_poses[XRT_MAX_VIEWS],
128 const struct xrt_fov fovs[XRT_MAX_VIEWS],
129 struct render_gfx_target_resources *target_rtr,
130 const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS],
131 const struct xrt_matrix_2x2 vertex_rots[XRT_MAX_VIEWS])
132{
133 chl_frame_state_gfx_set_views( //
134 frame_state, //
135 world_poses, //
136 eye_poses, //
137 fovs, //
138 layer_count); //
139
140 chl_frame_state_gfx_set_target( //
141 frame_state, //
142 target_rtr, //
143 target_viewport_datas, //
144 vertex_rots); //
145
146 // Start the compute pipeline.
147 render_gfx_begin(render);
148
149 // Build the command buffer.
150 comp_render_gfx_dispatch( //
151 render, //
152 layers, //
153 layer_count, //
154 &frame_state->data); //
155
156 // Make the command buffer submittable.
157 render_gfx_end(render);
158}
159
160
161/*
162 *
163 * Compute
164 *
165 */
166
167/*!
168 * Sets all the needed state to run the layer squasher to the scratch images,
169 * this is the compute version.
170 *
171 * @memberof chl_frame_state
172 */
173void
174chl_frame_state_cs_set_views(struct chl_frame_state *frame_state,
175 const struct xrt_pose world_pose_scanout_begin[XRT_MAX_VIEWS],
176 const struct xrt_pose world_pose_scanout_end[XRT_MAX_VIEWS],
177 const struct xrt_pose eye_pose[XRT_MAX_VIEWS],
178 const struct xrt_fov fov[XRT_MAX_VIEWS],
179 uint32_t layer_count);
180
181/*!
182 * Adds the needed information to also perform a distortion step, reuses some
183 * information from the _set_views call and as such this needs to be called
184 * before calling this function. This is the compute version.
185 *
186 * @memberof chl_frame_state
187 */
188void
189chl_frame_state_cs_set_target(struct chl_frame_state *frame_state,
190 VkImage target_image,
191 VkImageView target_storage_view,
192 const struct render_viewport_data views[XRT_MAX_VIEWS]);
193
194/*!
195 * A single do all function, runs the default compute pipeline.
196 *
197 * @memberof chl_frame_state
198 */
199static inline void
200chl_frame_state_cs_default_pipeline(struct chl_frame_state *frame_state,
201 struct render_compute *render,
202 const struct comp_layer *layers,
203 uint32_t layer_count,
204 const struct xrt_pose world_poses_scanout_begin[XRT_MAX_VIEWS],
205 const struct xrt_pose world_poses_scanout_end[XRT_MAX_VIEWS],
206 const struct xrt_pose eye_poses[XRT_MAX_VIEWS],
207 const struct xrt_fov fovs[XRT_MAX_VIEWS],
208 VkImage target_image,
209 VkImageView target_storage_view,
210 const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS])
211{
212 chl_frame_state_cs_set_views( //
213 frame_state, //
214 world_poses_scanout_begin, //
215 world_poses_scanout_end, //
216 eye_poses, //
217 fovs, //
218 layer_count); //
219
220 chl_frame_state_cs_set_target( //
221 frame_state, //
222 target_image, //
223 target_storage_view, //
224 target_viewport_datas); //
225
226 // Start the compute pipeline.
227 render_compute_begin(render);
228
229 // Build the command buffer.
230 comp_render_cs_dispatch( //
231 render, //
232 layers, //
233 layer_count, //
234 &frame_state->data); //
235
236 // Make the command buffer submittable.
237 render_compute_end(render);
238}
239
240#ifdef __cplusplus
241}
242#endif