The open source OpenXR runtime
at mr/scanout-values 201 lines 5.3 kB view raw
1// Copyright 2023-2024, Collabora, Ltd. 2// Copyright 2025, NVIDIA CORPORATION. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Compositor rendering code helpers. 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 * @ingroup comp_util 9 */ 10 11#pragma once 12 13#include "xrt/xrt_compositor.h" 14 15#include "render/render_interface.h" 16 17#include "util/comp_base.h" 18#include "util/comp_render.h" 19 20#ifdef __cplusplus 21extern "C" { 22#endif 23 24 25/* 26 * 27 * Swapchain helpers. 28 * 29 */ 30 31static inline VkImageView 32get_image_view(const struct comp_swapchain_image *image, enum xrt_layer_composition_flags flags, uint32_t array_index) 33{ 34 if (flags & XRT_LAYER_COMPOSITION_BLEND_TEXTURE_SOURCE_ALPHA_BIT) { 35 return image->views.alpha[array_index]; 36 } 37 38 return image->views.no_alpha[array_index]; 39} 40 41 42/* 43 * 44 * View index helpers. 45 * 46 */ 47 48static inline bool 49is_view_index_right(uint32_t view_index) 50{ 51 return view_index % 2 == 1; 52} 53 54static inline void 55view_index_to_projection_data(uint32_t view_index, 56 const struct xrt_layer_data *data, 57 const struct xrt_layer_projection_view_data **out_vd) 58{ 59 const struct xrt_layer_projection_data *proj = &data->proj; 60 *out_vd = &proj->v[view_index]; 61} 62 63static inline void 64view_index_to_depth_data(uint32_t view_index, 65 const struct xrt_layer_data *data, 66 const struct xrt_layer_projection_view_data **out_vd, 67 const struct xrt_layer_depth_data **out_dvd) 68{ 69 const struct xrt_layer_projection_depth_data *depth = &data->depth; 70 *out_vd = &depth->v[view_index]; 71 *out_dvd = &depth->d[view_index]; 72} 73 74 75/* 76 * 77 * Layer data helpers. 78 * 79 */ 80 81static inline bool 82is_layer_view_visible(const struct xrt_layer_data *data, uint32_t view_index) 83{ 84 enum xrt_layer_eye_visibility visibility; 85 switch (data->type) { 86 case XRT_LAYER_CUBE: visibility = data->cube.visibility; break; 87 case XRT_LAYER_CYLINDER: visibility = data->cylinder.visibility; break; 88 case XRT_LAYER_EQUIRECT1: visibility = data->equirect1.visibility; break; 89 case XRT_LAYER_EQUIRECT2: visibility = data->equirect2.visibility; break; 90 case XRT_LAYER_QUAD: visibility = data->quad.visibility; break; 91 case XRT_LAYER_PROJECTION: 92 case XRT_LAYER_PROJECTION_DEPTH: return true; 93 default: return false; 94 }; 95 96 switch (visibility) { 97 case XRT_LAYER_EYE_VISIBILITY_LEFT_BIT: return !is_view_index_right(view_index); 98 case XRT_LAYER_EYE_VISIBILITY_RIGHT_BIT: return is_view_index_right(view_index); 99 case XRT_LAYER_EYE_VISIBILITY_BOTH: return true; 100 case XRT_LAYER_EYE_VISIBILITY_NONE: 101 default: return false; 102 } 103} 104 105static inline bool 106is_layer_view_space(const struct xrt_layer_data *data) 107{ 108 return (data->flags & XRT_LAYER_COMPOSITION_VIEW_SPACE_BIT) != 0; 109} 110 111static inline bool 112is_layer_unpremultiplied(const struct xrt_layer_data *data) 113{ 114 return (data->flags & XRT_LAYER_COMPOSITION_UNPREMULTIPLIED_ALPHA_BIT) != 0; 115} 116 117static inline void 118set_post_transform_rect(const struct xrt_layer_data *data, 119 const struct xrt_normalized_rect *src_norm_rect, 120 bool invert_flip, 121 struct xrt_normalized_rect *out_norm_rect) 122{ 123 struct xrt_normalized_rect rect = *src_norm_rect; 124 125 if (data->flip_y ^ invert_flip) { 126 float h = rect.h; 127 128 rect.h = -h; 129 rect.y = rect.y + h; 130 } 131 132 *out_norm_rect = rect; 133} 134 135 136/* 137 * 138 * Command helpers. 139 * 140 */ 141 142/*! 143 * This inserts a barrier operation that effects all views[X].squash.image 144 * fields (which are VkImages). 145 */ 146static inline void 147cmd_barrier_view_squash_images(struct vk_bundle *vk, 148 const struct comp_render_dispatch_data *d, 149 VkCommandBuffer cmd, 150 VkAccessFlags src_access_mask, 151 VkAccessFlags dst_access_mask, 152 VkImageLayout transition_from, 153 VkImageLayout transition_to, 154 VkPipelineStageFlags src_stage_mask, 155 VkPipelineStageFlags dst_stage_mask) 156{ 157 VkImageSubresourceRange first_color_level_subresource_range = { 158 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 159 .baseMipLevel = 0, 160 .levelCount = 1, 161 .baseArrayLayer = 0, 162 .layerCount = 1, 163 }; 164 165 for (uint32_t i = 0; i < d->squash_view_count; i++) { 166 bool already_barriered = false; 167 168 VkImage image = d->views[i].squash.image; 169 170 uint32_t k = i; 171 while (k > 0) { 172 k--; // k is always greater then zero. 173 174 if (d->views[k].squash.image == image) { 175 already_barriered = true; 176 break; 177 } 178 } 179 180 if (already_barriered) { 181 continue; 182 } 183 184 vk_cmd_image_barrier_locked( // 185 vk, // vk_bundle 186 cmd, // cmd_buffer 187 image, // image 188 src_access_mask, // src_access_mask 189 dst_access_mask, // dst_access_mask 190 transition_from, // old_image_layout 191 transition_to, // new_image_layout 192 src_stage_mask, // src_stage_mask 193 dst_stage_mask, // dst_stage_mask 194 first_color_level_subresource_range); // subresource_range 195 } 196} 197 198 199#ifdef __cplusplus 200} 201#endif