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 scratch helper

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

+346
+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_scratch.c 150 + util/comp_high_level_scratch.h 149 151 util/comp_layer_accum.h 150 152 util/comp_layer_accum.c 151 153 util/comp_render.h
+144
src/xrt/compositor/util/comp_high_level_scratch.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 scratch images. 7 + * @author Jakob Bornecrantz <tbornecrantz@nvidia.com> 8 + * @author Andrei Aristarkhov <aaristarkhov@nvidia.com> 9 + * @author Gareth Morgan <gmorgan@nvidia.com> 10 + * @author Rylie Pavlik <rylie.pavlik@collabora.com> 11 + * @ingroup comp_main 12 + */ 13 + 14 + 15 + #include "comp_high_level_scratch.h" 16 + 17 + 18 + void 19 + chl_scratch_init(struct chl_scratch *scratch) 20 + { 21 + for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) { 22 + comp_scratch_single_images_init(&scratch->views[i].cssi); 23 + } 24 + } 25 + 26 + void 27 + chl_scratch_fini(struct chl_scratch *scratch) 28 + { 29 + for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) { 30 + comp_scratch_single_images_destroy(&scratch->views[i].cssi); 31 + } 32 + } 33 + 34 + bool 35 + chl_scratch_ensure(struct chl_scratch *scratch, 36 + struct render_resources *rr, 37 + uint32_t view_count, 38 + VkExtent2D extent, 39 + const VkFormat format) 40 + { 41 + struct vk_bundle *vk = rr->vk; 42 + bool bret = false; 43 + 44 + // Is everything already correct? 45 + if (scratch->view_count == view_count && // 46 + scratch->extent.width == extent.width && // 47 + scratch->extent.height == extent.height && // 48 + scratch->format == format) { 49 + return true; 50 + } 51 + 52 + // Free all old resources. 53 + chl_scratch_free_resources(scratch, rr); 54 + 55 + // Shared render pass between all scratch images. 56 + bret = render_gfx_render_pass_init( // 57 + &scratch->render_pass, // rgrp 58 + rr, // struct render_resources 59 + format, // format 60 + VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op 61 + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // final_layout 62 + if (!bret) { 63 + VK_ERROR(vk, "render_gfx_render_pass_init: false"); 64 + return false; 65 + } 66 + 67 + // Need to track if the render pass has been initialized. 68 + scratch->render_pass_initialized = true; 69 + 70 + for (uint32_t i = 0; i < view_count; i++) { 71 + // Helper. 72 + struct comp_scratch_single_images *cssi = &scratch->views[i].cssi; 73 + 74 + if (format == VK_FORMAT_R8G8B8A8_SRGB) { 75 + // Special creation function for the mutable format. 76 + bret = comp_scratch_single_images_ensure_mutable(cssi, vk, extent); 77 + } else { 78 + bret = comp_scratch_single_images_ensure(cssi, vk, extent, format); 79 + } 80 + 81 + if (!bret) { 82 + VK_ERROR(vk, "comp_scratch_single_images_ensure[_mutable]: false"); 83 + // Free any that has already been allocated. 84 + chl_scratch_free_resources(scratch, rr); 85 + return false; 86 + } 87 + 88 + for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) { 89 + 90 + /* 91 + * For graphics parts we use the same image view as the 92 + * source. In other words the sRGB image view for the 93 + * non-linear formats. 94 + */ 95 + VkImageView target_image_view = chl_scratch_get_sample_view(scratch, i, k); 96 + 97 + render_gfx_target_resources_init( // 98 + &scratch->views[i].targets[k], // rtr 99 + rr, // struct render_resources 100 + &scratch->render_pass, // struct render_gfx_render_pass 101 + target_image_view, // target 102 + extent); // extent 103 + } 104 + 105 + /* 106 + * Update the count, doing it this way means free_resources 107 + * will free the allocated images correctly. The count is one 108 + * more then the index. 109 + */ 110 + scratch->view_count = i + 1; 111 + } 112 + 113 + // Update the cached values. 114 + scratch->extent = extent; 115 + scratch->format = format; 116 + 117 + return true; 118 + } 119 + 120 + void 121 + chl_scratch_free_resources(struct chl_scratch *scratch, struct render_resources *rr) 122 + { 123 + struct vk_bundle *vk = rr->vk; 124 + 125 + for (uint32_t i = 0; i < scratch->view_count; i++) { 126 + for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) { 127 + render_gfx_target_resources_fini(&scratch->views[i].targets[k]); 128 + } 129 + 130 + comp_scratch_single_images_free(&scratch->views[i].cssi, vk); 131 + } 132 + 133 + // Nothing allocated. 134 + scratch->view_count = 0; 135 + scratch->extent.width = 0; 136 + scratch->extent.height = 0; 137 + scratch->format = VK_FORMAT_UNDEFINED; 138 + 139 + // Do this after the image targets as they reference the render pass. 140 + if (scratch->render_pass_initialized) { 141 + render_gfx_render_pass_fini(&scratch->render_pass); 142 + scratch->render_pass_initialized = false; 143 + } 144 + }
+200
src/xrt/compositor/util/comp_high_level_scratch.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 scratch images. 7 + * @author Jakob Bornecrantz <tbornecrantz@nvidia.com> 8 + * @ingroup comp_util 9 + */ 10 + 11 + #pragma once 12 + 13 + 14 + #include "render/render_interface.h" 15 + 16 + #include "comp_scratch.h" 17 + 18 + 19 + #ifdef __cplusplus 20 + extern "C" { 21 + #endif 22 + 23 + /*! 24 + * Scratch images that can be used for staging buffers. 25 + * 26 + * @ingroup comp_util 27 + */ 28 + struct chl_scratch 29 + { 30 + //! Shared render passed for the views. 31 + struct render_gfx_render_pass render_pass; 32 + 33 + struct 34 + { 35 + //! Per-view scratch images. 36 + struct comp_scratch_single_images cssi; 37 + 38 + //! Targets for rendering to the scratch buffer. 39 + struct render_gfx_target_resources targets[COMP_SCRATCH_NUM_IMAGES]; 40 + } views[XRT_MAX_VIEWS]; 41 + 42 + /*! 43 + * Number of views that has been ensured and have Vulkan resources, 44 + * all comp_scratch_single_images are always inited. 45 + */ 46 + uint32_t view_count; 47 + 48 + //! The extent used to create the images. 49 + VkExtent2D extent; 50 + 51 + //! Format requested. 52 + VkFormat format; 53 + 54 + //! Has the render pass been initialized. 55 + bool render_pass_initialized; 56 + }; 57 + 58 + /*! 59 + * Must becalled before used and before the scratch images are registered with 60 + * the u_var system. 61 + * 62 + * @memberof chl_scratch 63 + */ 64 + void 65 + chl_scratch_init(struct chl_scratch *scratch); 66 + 67 + /*! 68 + * Resources must be manually called before calling this functions, and the 69 + * scratch images unregistered from the u_var system. 70 + * 71 + * @memberof chl_scratch 72 + */ 73 + void 74 + chl_scratch_fini(struct chl_scratch *scratch); 75 + 76 + /*! 77 + * Ensure the scratch images and the render target resources are created. 78 + * 79 + * @memberof chl_scratch 80 + */ 81 + bool 82 + chl_scratch_ensure(struct chl_scratch *scratch, 83 + struct render_resources *rr, 84 + uint32_t view_count, 85 + VkExtent2D extent, 86 + const VkFormat format); 87 + 88 + /*! 89 + * Free all Vulkan resources that this scratch has created. 90 + * 91 + * @memberof chl_scratch 92 + */ 93 + void 94 + chl_scratch_free_resources(struct chl_scratch *scratch, struct render_resources *rr); 95 + 96 + /*! 97 + * Get the image, see @ref comp_scratch_single_images_get_image. 98 + * 99 + * @memberof chl_scratch 100 + */ 101 + static inline VkImage 102 + chl_scratch_get_image(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index) 103 + { 104 + return comp_scratch_single_images_get_image(&scratch->views[view_index].cssi, image_index); 105 + } 106 + 107 + /*! 108 + * Get the sample view, see @ref comp_scratch_single_images_get_sample_view. 109 + * 110 + * @memberof chl_scratch 111 + */ 112 + static inline VkImageView 113 + chl_scratch_get_sample_view(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index) 114 + { 115 + return comp_scratch_single_images_get_sample_view(&scratch->views[view_index].cssi, image_index); 116 + } 117 + 118 + /*! 119 + * Get the storage view, see @ref comp_scratch_single_images_get_storage_view. 120 + * 121 + * @memberof chl_scratch 122 + */ 123 + static inline VkImageView 124 + chl_scratch_get_storage_view(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index) 125 + { 126 + return comp_scratch_single_images_get_storage_view(&scratch->views[view_index].cssi, image_index); 127 + } 128 + 129 + 130 + /* 131 + * 132 + * State 133 + * 134 + */ 135 + 136 + /*! 137 + * Per view frame state tracking which index was gotten and if it was used. 138 + * 139 + * @ingroup comp_util 140 + */ 141 + struct chl_scratch_state_view 142 + { 143 + uint32_t index; 144 + 145 + bool used; 146 + }; 147 + 148 + /*! 149 + * Used to track the index of images gotten for the images, and if it has been 150 + * used. The user will need to mark images as used. 151 + * 152 + * @ingroup comp_util 153 + */ 154 + struct chl_scratch_state 155 + { 156 + struct chl_scratch_state_view views[XRT_MAX_VIEWS]; 157 + }; 158 + 159 + /*! 160 + * Zeros out the struct and calls get on all the images, setting the @p index 161 + * field on the state for each view. 162 + * 163 + * @memberof chl_scratch_state 164 + */ 165 + static inline void 166 + chl_scratch_state_init_and_get(struct chl_scratch_state *scratch_state, struct chl_scratch *scratch) 167 + { 168 + U_ZERO(scratch_state); 169 + 170 + // Loop over all the of the images in the scratch view. 171 + for (uint32_t i = 0; i < scratch->view_count; i++) { 172 + comp_scratch_single_images_get(&scratch->views[i].cssi, &scratch_state->views[i].index); 173 + } 174 + } 175 + 176 + /*! 177 + * Calls discard or done on all the scratch images, it calls done if the @p used 178 + * field is set to true. 179 + * 180 + * @memberof chl_scratch_state 181 + */ 182 + static inline void 183 + chl_scratch_state_discard_or_done(struct chl_scratch_state *scratch_state, struct chl_scratch *scratch) 184 + { 185 + // Loop over all the of the images in the scratch view. 186 + for (uint32_t i = 0; i < scratch->view_count; i++) { 187 + if (scratch_state->views[i].used) { 188 + comp_scratch_single_images_done(&scratch->views[i].cssi); 189 + } else { 190 + comp_scratch_single_images_discard(&scratch->views[i].cssi); 191 + } 192 + } 193 + 194 + U_ZERO(scratch_state); 195 + } 196 + 197 + 198 + #ifdef __cplusplus 199 + } 200 + #endif