The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/util: Add high-level render helper

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2493>

+463
+2
src/xrt/compositor/CMakeLists.txt
··· 146 146 comp_util STATIC 147 147 util/comp_base.h 148 148 util/comp_base.c 149 + util/comp_high_level_render.c 150 + util/comp_high_level_render.h 149 151 util/comp_high_level_scratch.c 150 152 util/comp_high_level_scratch.h 151 153 util/comp_layer_accum.h
+222
src/xrt/compositor/util/comp_high_level_render.c
··· 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 + #include "comp_high_level_render.h" 15 + 16 + 17 + /* 18 + * 19 + * Common 20 + * 21 + */ 22 + 23 + void 24 + chl_frame_state_init(struct chl_frame_state *frame_state, 25 + struct render_resources *rr, 26 + uint32_t view_count, 27 + bool do_timewarp, 28 + bool fast_path, 29 + struct chl_scratch *scratch) 30 + { 31 + assert(rr != NULL); 32 + assert(rr->vk != NULL); 33 + assert(view_count <= rr->view_count); 34 + 35 + U_ZERO(frame_state); 36 + frame_state->view_count = view_count; 37 + frame_state->scratch = scratch; 38 + 39 + comp_render_initial_init( // 40 + &frame_state->data, // data 41 + fast_path, // fast_path 42 + do_timewarp); // do_timewarp 43 + 44 + chl_scratch_state_init_and_get(&frame_state->scratch_state, scratch); 45 + } 46 + 47 + void 48 + chl_frame_state_fini(struct chl_frame_state *frame_state) 49 + { 50 + if (frame_state->scratch == NULL) { 51 + return; 52 + } 53 + 54 + chl_scratch_state_discard_or_done(&frame_state->scratch_state, frame_state->scratch); 55 + 56 + U_ZERO(frame_state); 57 + } 58 + 59 + 60 + /* 61 + * 62 + * Graphics 63 + * 64 + */ 65 + 66 + void 67 + chl_frame_state_gfx_set_views(struct chl_frame_state *frame_state, 68 + const struct xrt_pose world_poses[XRT_MAX_VIEWS], 69 + const struct xrt_pose eye_poses[XRT_MAX_VIEWS], 70 + const struct xrt_fov fovs[XRT_MAX_VIEWS], 71 + uint32_t layer_count) 72 + { 73 + for (uint32_t i = 0; i < frame_state->view_count; i++) { 74 + // Which image of the scratch images for this view are we using. 75 + uint32_t scratch_index = frame_state->scratch_state.views[i].index; 76 + 77 + // The set of scratch images we are using for this view. 78 + struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; 79 + 80 + // The render target resources for the scratch images. 81 + struct render_gfx_target_resources *rsci_rtr = &frame_state->scratch->views[i].targets[scratch_index]; 82 + 83 + // Scratch color image. 84 + struct render_scratch_color_image *rsci = &scratch_view->images[scratch_index]; 85 + 86 + // Use the whole scratch image. 87 + struct render_viewport_data layer_viewport_data = { 88 + .x = 0, 89 + .y = 0, 90 + .w = scratch_view->info.width, 91 + .h = scratch_view->info.height, 92 + }; 93 + 94 + comp_render_gfx_add_squash_view( // 95 + &frame_state->data, // 96 + &world_poses[i], // 97 + &eye_poses[i], // 98 + &fovs[i], // 99 + rsci->image, // squash_image 100 + rsci_rtr, // squash_rtr 101 + &layer_viewport_data); // squash_viewport_data 102 + 103 + if (layer_count == 0) { 104 + frame_state->scratch_state.views[i].used = false; 105 + } else { 106 + frame_state->scratch_state.views[i].used = !frame_state->data.fast_path; 107 + } 108 + } 109 + } 110 + 111 + void 112 + chl_frame_state_gfx_set_target(struct chl_frame_state *frame_state, 113 + struct render_gfx_target_resources *target_rtr, 114 + const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS], 115 + const struct xrt_matrix_2x2 vertex_rots[XRT_MAX_VIEWS]) 116 + { 117 + // Add the target info. 118 + comp_render_gfx_add_target(&frame_state->data, target_rtr); 119 + 120 + for (uint32_t i = 0; i < frame_state->view_count; i++) { 121 + // Which image of the scratch images for this view are we using. 122 + uint32_t scratch_index = frame_state->scratch_state.views[i].index; 123 + 124 + // The set of scratch images we are using for this view. 125 + struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; 126 + 127 + // Scratch image covers the whole image. 128 + struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; 129 + 130 + VkImageView sample_view = comp_scratch_single_images_get_sample_view(scratch_view, scratch_index); 131 + 132 + comp_render_gfx_add_target_view( // 133 + &frame_state->data, // 134 + sample_view, // squash_as_src_sample_view 135 + &layer_norm_rect, // squash_as_src_norm_rect 136 + &vertex_rots[i], // target_vertex_rot 137 + &target_viewport_datas[i]); // target_viewport_data 138 + } 139 + } 140 + 141 + 142 + /* 143 + * 144 + * Compute 145 + * 146 + */ 147 + 148 + void 149 + chl_frame_state_cs_set_views(struct chl_frame_state *frame_state, 150 + const struct xrt_pose world_poses[XRT_MAX_VIEWS], 151 + const struct xrt_pose eye_poses[XRT_MAX_VIEWS], 152 + const struct xrt_fov fovs[XRT_MAX_VIEWS], 153 + uint32_t layer_count) 154 + { 155 + for (uint32_t i = 0; i < frame_state->view_count; i++) { 156 + // Which image of the scratch images for this view are we using. 157 + uint32_t scratch_index = frame_state->scratch_state.views[i].index; 158 + 159 + // The set of scratch images we are using for this view. 160 + struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; 161 + 162 + // Scratch color image. 163 + struct render_scratch_color_image *rsci = &scratch_view->images[scratch_index]; 164 + 165 + // Use the whole scratch image. 166 + struct render_viewport_data layer_viewport_data = { 167 + .x = 0, 168 + .y = 0, 169 + .w = scratch_view->info.width, 170 + .h = scratch_view->info.height, 171 + }; 172 + 173 + VkImageView storage_view = comp_scratch_single_images_get_storage_view(scratch_view, scratch_index); 174 + 175 + comp_render_cs_add_squash_view( // 176 + &frame_state->data, // 177 + &world_poses[i], // 178 + &eye_poses[i], // 179 + &fovs[i], // 180 + rsci->image, // squash_image 181 + storage_view, // squash_storage_view 182 + &layer_viewport_data); // squash_viewport_data 183 + 184 + if (layer_count == 0) { 185 + frame_state->scratch_state.views[i].used = false; 186 + } else { 187 + frame_state->scratch_state.views[i].used = !frame_state->data.fast_path; 188 + } 189 + } 190 + } 191 + 192 + void 193 + chl_frame_state_cs_set_target(struct chl_frame_state *frame_state, 194 + VkImage target_image, 195 + VkImageView target_storage_view, 196 + const struct render_viewport_data views[XRT_MAX_VIEWS]) 197 + { 198 + // Add the target info. 199 + comp_render_cs_add_target( // 200 + &frame_state->data, // data 201 + target_image, // target_image 202 + target_storage_view); // target_unorm_view 203 + 204 + for (uint32_t i = 0; i < frame_state->view_count; i++) { 205 + // Which image of the scratch images for this view are we using. 206 + uint32_t scratch_index = frame_state->scratch_state.views[i].index; 207 + 208 + // The set of scratch images we are using for this view. 209 + struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; 210 + 211 + // Scratch image covers the whole image. 212 + struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; 213 + 214 + VkImageView sample_view = comp_scratch_single_images_get_sample_view(scratch_view, scratch_index); 215 + 216 + comp_render_cs_add_target_view( // 217 + &frame_state->data, // 218 + sample_view, // squash_as_src_sample_view 219 + &layer_norm_rect, // squash_as_src_norm_rect 220 + &views[i]); // target_viewport_data 221 + } 222 + }
+239
src/xrt/compositor/util/comp_high_level_render.h
··· 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 24 + extern "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 + */ 38 + struct 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 + */ 65 + void 66 + chl_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 + */ 80 + void 81 + chl_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 + */ 96 + void 97 + chl_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 + */ 110 + void 111 + chl_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 + */ 121 + static inline void 122 + chl_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 + */ 173 + void 174 + chl_frame_state_cs_set_views(struct chl_frame_state *frame_state, 175 + const struct xrt_pose world_pose[XRT_MAX_VIEWS], 176 + const struct xrt_pose eye_pose[XRT_MAX_VIEWS], 177 + const struct xrt_fov fov[XRT_MAX_VIEWS], 178 + uint32_t layer_count); 179 + 180 + /*! 181 + * Adds the needed information to also perform a distortion step, reuses some 182 + * information from the _set_views call and as such this needs to be called 183 + * before calling this function. This is the compute version. 184 + * 185 + * @memberof chl_frame_state 186 + */ 187 + void 188 + chl_frame_state_cs_set_target(struct chl_frame_state *frame_state, 189 + VkImage target_image, 190 + VkImageView target_storage_view, 191 + const struct render_viewport_data views[XRT_MAX_VIEWS]); 192 + 193 + /*! 194 + * A single do all function, runs the default compute pipeline. 195 + * 196 + * @memberof chl_frame_state 197 + */ 198 + static inline void 199 + chl_frame_state_cs_default_pipeline(struct chl_frame_state *frame_state, 200 + struct render_compute *render, 201 + const struct comp_layer *layers, 202 + uint32_t layer_count, 203 + const struct xrt_pose world_poses[XRT_MAX_VIEWS], 204 + const struct xrt_pose eye_poses[XRT_MAX_VIEWS], 205 + const struct xrt_fov fovs[XRT_MAX_VIEWS], 206 + VkImage target_image, 207 + VkImageView target_storage_view, 208 + const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS]) 209 + { 210 + chl_frame_state_cs_set_views( // 211 + frame_state, // 212 + world_poses, // 213 + eye_poses, // 214 + fovs, // 215 + layer_count); // 216 + 217 + chl_frame_state_cs_set_target( // 218 + frame_state, // 219 + target_image, // 220 + target_storage_view, // 221 + target_viewport_datas); // 222 + 223 + // Start the compute pipeline. 224 + render_compute_begin(render); 225 + 226 + // Build the command buffer. 227 + comp_render_cs_dispatch( // 228 + render, // 229 + layers, // 230 + layer_count, // 231 + &frame_state->data); // 232 + 233 + // Make the command buffer submittable. 234 + render_compute_end(render); 235 + } 236 + 237 + #ifdef __cplusplus 238 + } 239 + #endif