The open source OpenXR runtime
0
fork

Configure Feed

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

c/util: Refactor how arguments are given

+835 -535
+86 -19
src/xrt/compositor/main/comp_renderer.c
··· 823 823 world_poses, // world_poses[2] 824 824 eye_poses); // eye_poses[2] 825 825 826 + // Scratch image we are rendering to. 827 + struct render_scratch_images *rsi = &r->scratch; 828 + 829 + // The arguments for the dispatch function. 830 + struct comp_render_dispatch_data data; 831 + comp_render_gfx_initial_init( // 832 + &data, // data 833 + rtr, // rtr 834 + fast_path, // fast_path 835 + do_timewarp); // do_timewarp 836 + 837 + for (uint32_t i = 0; i < 2; i++) { 838 + // Scratch color image. 839 + struct render_scratch_color_image *rsci = &rsi->color[i]; 840 + 841 + // The render target resources for the scratch images. 842 + struct render_gfx_target_resources *rsci_rtr = &r->scratch_targets[i]; 843 + 844 + // Use the whole scratch image. 845 + struct render_viewport_data layer_viewport_data = { 846 + .x = 0, 847 + .y = 0, 848 + .w = rsi->extent.width, 849 + .h = rsi->extent.height, 850 + }; 851 + 852 + // Scratch image covers the whole image. 853 + struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; 854 + 855 + comp_render_gfx_add_view( // 856 + &data, // data 857 + &world_poses[i], // world_pose 858 + &eye_poses[i], // eye_pose 859 + &fovs[i], // fov 860 + rsci_rtr, // rtr 861 + &layer_viewport_data, // layer_viewport_data 862 + &layer_norm_rect, // layer_norm_rect 863 + rsci->image, // image 864 + rsci->srgb_view, // srgb_view 865 + &vertex_rots[i], // vertex_rot 866 + &viewport_datas[i]); // target_viewport_data 867 + } 868 + 826 869 // Start the graphics pipeline. 827 870 render_gfx_begin(rr); 828 871 829 872 // Build the command buffer. 830 873 comp_render_gfx_dispatch( // 831 874 rr, // rr 832 - &r->scratch, // rsi 833 - r->scratch_targets, // rsi_rtrs 834 875 layers, // layers 835 876 layer_count, // layer_count 836 - world_poses, // world_poses 837 - eye_poses, // eye_poses 838 - fovs, // fovs 839 - vertex_rots, // vertex_rots 840 - rtr, // rtr 841 - viewport_datas, // viewport_datas 842 - fast_path, // fast_path 843 - do_timewarp); // do_timewarp 877 + &data); // d 844 878 845 879 // Make the command buffer submittable. 846 880 render_gfx_end(rr); ··· 880 914 bool do_timewarp = !c->debug.atw_off; 881 915 882 916 // Device view information. 883 - struct xrt_fov fovs[2]; // Unused 917 + struct xrt_fov fovs[2]; 884 918 struct xrt_pose world_poses[2]; 885 919 struct xrt_pose eye_poses[2]; 886 920 calc_pose_data( // ··· 898 932 struct render_viewport_data views[2]; 899 933 calc_viewport_data(r, &views[0], &views[1]); 900 934 935 + // Scratch image we are rendering to. 936 + struct render_scratch_images *rsi = &r->scratch; 937 + 938 + // The arguments for the dispatch function. 939 + struct comp_render_dispatch_data data; 940 + comp_render_cs_initial_init( // 941 + &data, // data 942 + target_image, // target_image 943 + target_image_view, // target_unorm_view 944 + fast_path, // fast_path 945 + do_timewarp); // do_timewarp 946 + 947 + for (uint32_t i = 0; i < 2; i++) { 948 + // Scratch color image. 949 + struct render_scratch_color_image *rsci = &rsi->color[i]; 950 + 951 + // Use the whole scratch image. 952 + struct render_viewport_data layer_viewport_data = { 953 + .x = 0, 954 + .y = 0, 955 + .w = rsi->extent.width, 956 + .h = rsi->extent.height, 957 + }; 958 + 959 + // Scratch image covers the whole image. 960 + struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; 961 + 962 + comp_render_cs_add_view( // 963 + &data, // data 964 + &world_poses[i], // world_pose 965 + &eye_poses[i], // eye_pose 966 + &fovs[i], // fov 967 + &layer_viewport_data, // layer_viewport_data 968 + &layer_norm_rect, // layer_norm_rect 969 + rsci->image, // image 970 + rsci->srgb_view, // srgb_view 971 + rsci->unorm_view, // unorm_view 972 + &views[i]); // target_viewport_data 973 + } 974 + 901 975 // Start the compute pipeline. 902 976 render_compute_begin(crc); 903 977 904 978 // Build the command buffer. 905 979 comp_render_cs_dispatch( // 906 980 crc, // crc 907 - &r->scratch, // rsi 908 - world_poses, // world_poses 909 - eye_poses, // eye_poses 910 981 layers, // layers 911 982 layer_count, // layer_count 912 - target_image, // target_image 913 - target_image_view, // target_image_view 914 - views, // views 915 - fast_path, // fast_path 916 - do_timewarp); // do_timewarp 983 + &data); // d 917 984 918 985 // Make the command buffer submittable. 919 986 render_compute_end(crc);
+231 -62
src/xrt/compositor/util/comp_render.h
··· 1 - // Copyright 2019-2023, Collabora, Ltd. 1 + // Copyright 2019-2024, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 22 22 struct comp_layer; 23 23 24 24 25 + /* 26 + * 27 + * Input data struct. 28 + * 29 + */ 30 + 31 + /*! 32 + * The input data needed for a single view, it shared between both GFX and CS 33 + * paths. To fully render a single view two "rendering" might be needed, the 34 + * first being the layer squashing, and the second is the distortion step. The 35 + * target for the layer squashing is referred to as "layer" or "scratch" and 36 + * prefixed with `layer` if needs be. The other final step is referred to as 37 + * "distortion target" or just "target", and is prefixed with `target`. 38 + */ 39 + struct comp_render_view_data 40 + { 41 + //! New world pose of this view. 42 + struct xrt_pose world_pose; 43 + 44 + //! New eye pose of this view. 45 + struct xrt_pose eye_pose; 46 + 47 + /*! 48 + * New fov of this view, used for the layer scratch image. Needs to 49 + * match distortion parameters if distortion is used. 50 + */ 51 + struct xrt_fov fov; 52 + 53 + /*! 54 + * The layer image for this view (aka scratch image), 55 + * used for barrier operations. 56 + */ 57 + VkImage image; 58 + 59 + /*! 60 + * View into layer image (aka scratch image), 61 + * used for both GFX (read/write) and CS (read) paths. 62 + */ 63 + VkImageView srgb_view; 64 + 65 + /*! 66 + * Pre-view layer target viewport_data (where in the image we should 67 + * render the view). 68 + */ 69 + struct render_viewport_data layer_viewport_data; 70 + 71 + /*! 72 + * When sampling from the layer image (aka scratch image), how should we 73 + * transform it to get to the pixels correctly. 74 + */ 75 + struct xrt_normalized_rect layer_norm_rect; 76 + 77 + //! Go from UV to tanangle for the target, this needs to match @p fov. 78 + struct xrt_normalized_rect target_pre_transform; 79 + 80 + // Distortion target viewport data (aka target). 81 + struct render_viewport_data target_viewport_data; 82 + 83 + struct 84 + { 85 + //! Per-view layer target resources. 86 + struct render_gfx_target_resources *rtr; 87 + 88 + //! Distortion target vertex rotation information. 89 + struct xrt_matrix_2x2 vertex_rot; 90 + } gfx; 91 + 92 + struct 93 + { 94 + //! Only used on compute path. 95 + VkImageView unorm_view; 96 + } cs; 97 + }; 98 + 99 + /*! 100 + * The input data needed for a complete layer squashing distortion rendering 101 + * to a target. This struct is shared between GFX and CS paths. 102 + */ 103 + struct comp_render_dispatch_data 104 + { 105 + struct comp_render_view_data views[2]; 106 + 107 + //! The number of views currently in this dispatch data. 108 + uint32_t view_count; 109 + 110 + //! Fast path can be disabled for mirroing so needs to be an argument. 111 + bool fast_path; 112 + 113 + //! Very often true, can be disabled for debugging. 114 + bool do_timewarp; 115 + 116 + struct 117 + { 118 + // The resources needed for the target. 119 + struct render_gfx_target_resources *rtr; 120 + } gfx; 121 + 122 + struct 123 + { 124 + // Target image for distortion, used for barrier. 125 + VkImage target_image; 126 + 127 + // Target image view for distortion. 128 + VkImageView target_unorm_view; 129 + } cs; 130 + }; 131 + 132 + 133 + /* 134 + * 135 + * Gfx functions. 136 + * 137 + */ 138 + 139 + static inline void 140 + comp_render_gfx_initial_init(struct comp_render_dispatch_data *data, 141 + struct render_gfx_target_resources *rtr, 142 + bool fast_path, 143 + bool do_timewarp) 144 + { 145 + U_ZERO(data); 146 + 147 + data->fast_path = fast_path; 148 + data->do_timewarp = do_timewarp; 149 + data->gfx.rtr = rtr; 150 + } 151 + 152 + static inline void 153 + comp_render_gfx_add_view(struct comp_render_dispatch_data *data, 154 + const struct xrt_pose *world_pose, 155 + const struct xrt_pose *eye_pose, 156 + const struct xrt_fov *fov, 157 + struct render_gfx_target_resources *rtr, 158 + const struct render_viewport_data *layer_viewport_data, 159 + const struct xrt_normalized_rect *layer_norm_rect, 160 + VkImage image, 161 + VkImageView srgb_view, 162 + const struct xrt_matrix_2x2 *vertex_rot, 163 + const struct render_viewport_data *target_viewport_data) 164 + { 165 + uint32_t i = data->view_count++; 166 + 167 + assert(i < ARRAY_SIZE(data->views)); 168 + 169 + struct comp_render_view_data *view = &data->views[i]; 170 + 171 + render_calc_uv_to_tangent_lengths_rect(fov, &view->target_pre_transform); 172 + 173 + view->world_pose = *world_pose; 174 + view->eye_pose = *eye_pose; 175 + view->fov = *fov; 176 + view->image = image; 177 + view->srgb_view = srgb_view; 178 + view->layer_viewport_data = *layer_viewport_data; 179 + view->layer_norm_rect = *layer_norm_rect; 180 + view->target_viewport_data = *target_viewport_data; 181 + 182 + view->gfx.rtr = rtr; 183 + view->gfx.vertex_rot = *vertex_rot; 184 + } 185 + 25 186 /*! 26 187 * Helper function that takes a set of layers, new device poses, a scratch 27 188 * images with associated @ref render_gfx_target_resources and writes the needed 28 189 * commands to the @ref render_gfx to do a full composition with distortion. 29 190 * The scratch images are optionally used to squash layers should it not be 30 - * possible to do a @p fast_path. Will use the render passes of the targets 31 - * which set the layout. 191 + * possible to do a @p comp_render_dispatch_data::fast_path. Will use the render 192 + * passes of the targets which set the layout. 32 193 * 33 - * The render passes of @p rsi_rtrs must be created with a final_layout of 34 - * VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL or there will be validation errors. 194 + * The render passes of @p comp_render_dispatch_data::views::rtr must be created 195 + * with a final_layout of VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL or there will 196 + * be validation errors. 35 197 * 36 198 * Expected layouts: 37 199 * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ··· 47 209 */ 48 210 void 49 211 comp_render_gfx_dispatch(struct render_gfx *rr, 50 - struct render_scratch_images *rsi, 51 - struct render_gfx_target_resources rsi_rtrs[2], 52 212 const struct comp_layer *layers, 53 213 const uint32_t layer_count, 54 - struct xrt_pose world_poses[2], 55 - struct xrt_pose eye_poses[2], 56 - struct xrt_fov fovs[2], 57 - struct xrt_matrix_2x2 vertex_rots[2], 58 - struct render_gfx_target_resources *rtr, 59 - const struct render_viewport_data viewport_datas[2], 60 - bool fast_path, 61 - bool do_timewarp); 214 + const struct comp_render_dispatch_data *d); 215 + 216 + 217 + /* 218 + * 219 + * CS functions. 220 + * 221 + */ 222 + 223 + static inline void 224 + comp_render_cs_initial_init(struct comp_render_dispatch_data *data, 225 + VkImage target_image, 226 + VkImageView target_unorm_view, 227 + bool fast_path, 228 + bool do_timewarp) 229 + { 230 + U_ZERO(data); 62 231 232 + data->fast_path = fast_path; 233 + data->do_timewarp = do_timewarp; 234 + 235 + data->cs.target_image = target_image; 236 + data->cs.target_unorm_view = target_unorm_view; 237 + } 238 + 239 + static inline void 240 + comp_render_cs_add_view(struct comp_render_dispatch_data *data, 241 + const struct xrt_pose *world_pose, 242 + const struct xrt_pose *eye_pose, 243 + const struct xrt_fov *fov, 244 + const struct render_viewport_data *layer_viewport_data, 245 + const struct xrt_normalized_rect *layer_norm_rect, 246 + VkImage image, 247 + VkImageView srgb_view, 248 + VkImageView unorm_view, 249 + const struct render_viewport_data *target_viewport_data) 250 + { 251 + uint32_t i = data->view_count++; 252 + 253 + assert(i < ARRAY_SIZE(data->views)); 254 + 255 + struct comp_render_view_data *view = &data->views[i]; 256 + 257 + render_calc_uv_to_tangent_lengths_rect(fov, &view->target_pre_transform); 258 + 259 + view->world_pose = *world_pose; 260 + view->eye_pose = *eye_pose; 261 + view->fov = *fov; 262 + view->layer_viewport_data = *layer_viewport_data; 263 + view->layer_norm_rect = *layer_norm_rect; 264 + view->image = image; 265 + view->srgb_view = srgb_view; 266 + view->target_viewport_data = *target_viewport_data; 267 + 268 + view->cs.unorm_view = unorm_view; 269 + } 63 270 64 271 /*! 65 272 * Helper to dispatch the layer squasher for a single view. ··· 87 294 bool do_timewarp); 88 295 89 296 /*! 90 - * Helper function to dispatch the layer squasher, designed for stereo views. 297 + * Helper function to dispatch the layer squasher, works on any number of views. 91 298 * 92 299 * All source layer images needs to be in the correct image layout, no barrier 93 300 * is inserted for them. The target images are barried from undefined to general ··· 104 311 * @ingroup comp_util 105 312 */ 106 313 void 107 - comp_render_cs_stereo_layers(struct render_compute *crc, 108 - const struct comp_layer *layers, 109 - const uint32_t layer_count, 110 - const struct xrt_normalized_rect pre_transforms[2], 111 - const struct xrt_pose world_poses[2], 112 - const struct xrt_pose eye_poses[2], 113 - const VkImage target_images[2], 114 - const VkImageView target_image_views[2], 115 - const struct render_viewport_data target_views[2], 116 - VkImageLayout transition_to, 117 - bool do_timewarp); 118 - 119 - /*! 120 - * Helper function that takes a set of layers, new device poses, a scratch 121 - * images and writes the needed commands to the @ref render_compute to squash 122 - * the given layers into the given scratch images. Will insert barriers to 123 - * change the scratch images to the needed layout. 124 - * 125 - * Expected layouts: 126 - * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 127 - * * Scratch images: Any 128 - * 129 - * After call layouts: 130 - * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 131 - * * Scratch images: @p transition_to 132 - * 133 - * @ingroup comp_util 134 - */ 135 - void 136 - comp_render_cs_stereo_layers_to_scratch(struct render_compute *crc, 137 - const struct xrt_normalized_rect pre_transforms[2], 138 - struct xrt_pose world_poses[2], 139 - struct xrt_pose eye_poses[2], 140 - const struct comp_layer *layers, 141 - const uint32_t layer_count, 142 - struct render_scratch_images *rsi, 143 - VkImageLayout transition_to, 144 - bool do_timewarp); 314 + comp_render_cs_layers(struct render_compute *crc, 315 + const struct comp_layer *layers, 316 + const uint32_t layer_count, 317 + const struct comp_render_dispatch_data *d, 318 + VkImageLayout transition_to); 145 319 146 320 /*! 147 321 * Helper function that takes a set of layers, new device poses, a scratch ··· 149 323 * composition with distortion. The scratch images are optionally used to squash 150 324 * layers should it not be possible to do a fast_path. Will insert barriers to 151 325 * change the scratch images and target images to the needed layout. 326 + * 327 + * Currently limited to exactly two views. 152 328 * 153 329 * Expected layouts: 154 330 * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ··· 164 340 */ 165 341 void 166 342 comp_render_cs_dispatch(struct render_compute *crc, 167 - struct render_scratch_images *rsi, 168 - struct xrt_pose world_poses[2], 169 - struct xrt_pose eye_poses[2], 170 343 const struct comp_layer *layers, 171 344 const uint32_t layer_count, 172 - VkImage target_image, 173 - VkImageView target_image_view, 174 - const struct render_viewport_data views[2], 175 - bool fast_path, 176 - bool do_timewarp); 345 + const struct comp_render_dispatch_data *d); 177 346 178 347 179 348 #ifdef __cplusplus
+201 -241
src/xrt/compositor/util/comp_render_cs.c
··· 1 - // Copyright 2019-2023, Collabora, Ltd. 1 + // Copyright 2019-2024, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 307 307 *out_cur_image = cur_image; 308 308 } 309 309 310 + 310 311 /* 311 312 * 312 313 * Compute distortion helpers. ··· 314 315 */ 315 316 316 317 static void 317 - do_cs_distortion_for_scratch(struct render_compute *crc, 318 - struct render_scratch_images *rsi, 319 - VkImage target_image, 320 - VkImageView target_image_view, 321 - const struct render_viewport_data views[2]) 318 + do_cs_clear(struct render_compute *crc, const struct comp_render_dispatch_data *d) 322 319 { 323 - VkSampler sampler = crc->r->samplers.clamp_to_border_black; 320 + // Hardcoded to two views. 321 + if (d->view_count != 2) { 322 + U_LOG_E("Only supports exactly 2 views!"); 323 + assert(d->view_count == 2); 324 + return; 325 + } 324 326 325 - VkImageView src_image_views[2] = { 326 - rsi->color[0].srgb_view, // Read with gamma curve. 327 - rsi->color[1].srgb_view, 327 + const struct render_viewport_data target_viewport_datas[2] = { 328 + d->views[0].target_viewport_data, 329 + d->views[1].target_viewport_data, 328 330 }; 329 - VkSampler src_samplers[2] = {sampler, sampler}; 331 + 332 + render_compute_clear( // 333 + crc, // crc 334 + d->cs.target_image, // target_image 335 + d->cs.target_unorm_view, // target_image_view 336 + target_viewport_datas); // views 337 + } 338 + 339 + static void 340 + do_cs_distortion_from_scratch(struct render_compute *crc, const struct comp_render_dispatch_data *d) 341 + { 342 + // Hardcoded to two views. 343 + if (d->view_count != 2) { 344 + U_LOG_E("Only supports exactly 2 views!"); 345 + assert(d->view_count == 2); 346 + return; 347 + } 348 + 349 + VkSampler clamp_to_border_black = crc->r->samplers.clamp_to_border_black; 350 + 351 + struct render_viewport_data target_viewport_datas[2]; 352 + VkImageView src_image_views[2]; 353 + VkSampler src_samplers[2]; 354 + struct xrt_normalized_rect src_norm_rects[2]; 355 + 356 + for (uint32_t i = 0; i < d->view_count; i++) { 357 + // Data to be filled in. 358 + struct render_viewport_data viewport_data; 359 + VkImageView src_image_view; 360 + struct xrt_normalized_rect src_norm_rect; 361 + 362 + // Gather data. 363 + viewport_data = d->views[i].target_viewport_data, 364 + src_image_view = d->views[i].srgb_view; // Read with gamma curve. 365 + src_norm_rect = d->views[i].layer_norm_rect; 330 366 331 - struct xrt_normalized_rect src_norm_rects[2] = { 332 - {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}, 333 - {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}, 334 - }; 367 + // Fill in data. 368 + target_viewport_datas[i] = viewport_data; 369 + src_image_views[i] = src_image_view; 370 + src_samplers[i] = clamp_to_border_black; 371 + src_norm_rects[i] = src_norm_rect; 372 + } 335 373 336 - render_compute_projection( // 337 - crc, // 338 - src_samplers, // 339 - src_image_views, // 340 - src_norm_rects, // 341 - target_image, // 342 - target_image_view, // 343 - views // 344 - ); 374 + render_compute_projection( // 375 + crc, // crc 376 + src_samplers, // src_samplers 377 + src_image_views, // src_image_views 378 + src_norm_rects, // src_rects 379 + d->cs.target_image, // target_image 380 + d->cs.target_unorm_view, // target_image_view 381 + target_viewport_datas); // views 345 382 } 346 383 347 384 static void 348 - do_cs_distortion_for_layer(struct render_compute *crc, 349 - const struct xrt_pose world_poses[2], 350 - const struct comp_layer *layer, 351 - const struct xrt_layer_projection_view_data *lvd, 352 - const struct xrt_layer_projection_view_data *rvd, 353 - VkImage target_image, 354 - VkImageView target_image_view, 355 - const struct render_viewport_data views[2], 356 - bool do_timewarp) 385 + do_cs_distortion_from_stereo_layer(struct render_compute *crc, 386 + const struct comp_layer *layer, 387 + const struct xrt_layer_projection_view_data *lvd, 388 + const struct xrt_layer_projection_view_data *rvd, 389 + const struct comp_render_dispatch_data *d) 357 390 { 391 + // Hardcoded to two views. 392 + if (d->view_count != 2) { 393 + U_LOG_E("Only supports exactly 2 views!"); 394 + assert(d->view_count == 2); 395 + return; 396 + } 397 + 398 + // Fetch from this data. 358 399 const struct xrt_layer_data *data = &layer->data; 359 400 uint32_t left_array_index = lvd->sub.array_index; 360 401 uint32_t right_array_index = rvd->sub.array_index; ··· 362 403 const struct comp_swapchain_image *right = &layer->sc_array[1]->images[rvd->sub.image_index]; 363 404 364 405 VkSampler clamp_to_border_black = crc->r->samplers.clamp_to_border_black; 365 - VkSampler src_samplers[2] = { 366 - clamp_to_border_black, 367 - clamp_to_border_black, 368 - }; 406 + 407 + // Data to fill in. 408 + struct xrt_pose world_poses[2]; 409 + struct render_viewport_data target_viewport_datas[2]; 410 + struct xrt_normalized_rect src_norm_rects[2]; 411 + struct xrt_pose src_poses[2]; 412 + struct xrt_fov src_fovs[2]; 413 + VkSampler src_samplers[2]; 414 + VkImageView src_image_views[2]; 369 415 370 - VkImageView src_image_views[2] = { 371 - get_image_view(left, data->flags, left_array_index), 372 - get_image_view(right, data->flags, right_array_index), 373 - }; 416 + for (uint32_t i = 0; i < d->view_count; i++) { 374 417 375 - struct xrt_normalized_rect src_norm_rects[2] = {lvd->sub.norm_rect, rvd->sub.norm_rect}; 376 - if (data->flip_y) { 377 - src_norm_rects[0].h = -src_norm_rects[0].h; 378 - src_norm_rects[0].y = 1 + src_norm_rects[0].y; 379 - src_norm_rects[1].h = -src_norm_rects[1].h; 380 - src_norm_rects[1].y = 1 + src_norm_rects[1].y; 381 - } 418 + struct xrt_pose world_pose; 419 + struct render_viewport_data viewport_data; 420 + struct xrt_pose src_pose; 421 + struct xrt_fov src_fov; 422 + struct xrt_normalized_rect src_norm_rect; 423 + VkImageView src_image_view; 382 424 383 - if (!do_timewarp) { 384 - render_compute_projection( // 385 - crc, // 386 - src_samplers, // 387 - src_image_views, // 388 - src_norm_rects, // 389 - target_image, // 390 - target_image_view, // 391 - views); // 392 - } else { 393 - struct xrt_pose src_poses[2] = { 394 - lvd->pose, 395 - rvd->pose, 396 - }; 425 + // Gather data. 426 + world_pose = d->views[i].world_pose; 427 + viewport_data = d->views[i].target_viewport_data; 397 428 398 - struct xrt_fov src_fovs[2] = { 399 - lvd->fov, 400 - rvd->fov, 401 - }; 429 + if (!is_view_index_right(i)) { 430 + // Left, aka not right. 431 + src_pose = lvd->pose; 432 + src_fov = lvd->fov; 433 + src_norm_rect = lvd->sub.norm_rect; 434 + src_image_view = get_image_view(left, data->flags, left_array_index); 435 + } else { 436 + // Right 437 + src_pose = rvd->pose; 438 + src_fov = rvd->fov; 439 + src_norm_rect = rvd->sub.norm_rect; 440 + src_image_view = get_image_view(right, data->flags, right_array_index); 441 + } 442 + 443 + if (data->flip_y) { 444 + src_norm_rect.h = -src_norm_rect.h; 445 + src_norm_rect.y = 1 + src_norm_rect.y; 446 + } 402 447 448 + // Fill in data. 449 + world_poses[i] = world_pose; 450 + target_viewport_datas[i] = viewport_data; 451 + src_norm_rects[i] = src_norm_rect; 452 + src_poses[i] = src_pose; 453 + src_fovs[i] = src_fov; 454 + src_samplers[i] = clamp_to_border_black; 455 + src_image_views[i] = src_image_view; 456 + } 457 + 458 + if (!d->do_timewarp) { 459 + render_compute_projection( // 460 + crc, // 461 + src_samplers, // 462 + src_image_views, // 463 + src_norm_rects, // 464 + d->cs.target_image, // 465 + d->cs.target_unorm_view, // 466 + target_viewport_datas); // 467 + } else { 403 468 render_compute_projection_timewarp( // 404 469 crc, // 405 470 src_samplers, // ··· 408 473 src_poses, // 409 474 src_fovs, // 410 475 world_poses, // 411 - target_image, // 412 - target_image_view, // 413 - views); // 476 + d->cs.target_image, // 477 + d->cs.target_unorm_view, // 478 + target_viewport_datas); // 414 479 } 415 480 } 416 481 ··· 597 662 } 598 663 599 664 void 600 - comp_render_cs_stereo_layers(struct render_compute *crc, 601 - const struct comp_layer *layers, 602 - const uint32_t layer_count, 603 - const struct xrt_normalized_rect pre_transforms[2], 604 - const struct xrt_pose world_poses[2], 605 - const struct xrt_pose eye_poses[2], 606 - const VkImage target_images[2], 607 - const VkImageView target_image_views[2], 608 - const struct render_viewport_data target_views[2], 609 - VkImageLayout transition_to, 610 - bool do_timewarp) 665 + comp_render_cs_layers(struct render_compute *crc, 666 + const struct comp_layer *layers, 667 + const uint32_t layer_count, 668 + const struct comp_render_dispatch_data *d, 669 + VkImageLayout transition_to) 611 670 { 612 - VkImageSubresourceRange first_color_level_subresource_range = { 613 - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 614 - .baseMipLevel = 0, 615 - .levelCount = 1, 616 - .baseArrayLayer = 0, 617 - .layerCount = 1, 618 - }; 671 + cmd_barrier_view_images( // 672 + crc->r->vk, // 673 + d, // 674 + crc->r->cmd, // cmd 675 + 0, // src_access_mask 676 + VK_ACCESS_SHADER_WRITE_BIT, // dst_access_mask 677 + VK_IMAGE_LAYOUT_UNDEFINED, // transition_from 678 + VK_IMAGE_LAYOUT_GENERAL, // transition_to 679 + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // src_stage_mask 680 + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); // dst_stage_mask 619 681 620 - vk_cmd_image_barrier_gpu_locked( // 621 - crc->r->vk, // 622 - crc->r->cmd, // 623 - target_images[0], // 624 - 0, // 625 - VK_ACCESS_SHADER_WRITE_BIT, // 626 - VK_IMAGE_LAYOUT_UNDEFINED, // 627 - VK_IMAGE_LAYOUT_GENERAL, // 628 - first_color_level_subresource_range); // 682 + for (uint32_t view_index = 0; view_index < d->view_count; view_index++) { 683 + const struct comp_render_view_data *view = &d->views[view_index]; 629 684 630 - if (target_images[0] != target_images[1]) { 631 - vk_cmd_image_barrier_gpu_locked( // 632 - crc->r->vk, // 633 - crc->r->cmd, // 634 - target_images[1], // 635 - 0, // 636 - VK_ACCESS_SHADER_WRITE_BIT, // 637 - VK_IMAGE_LAYOUT_UNDEFINED, // 638 - VK_IMAGE_LAYOUT_GENERAL, // 639 - first_color_level_subresource_range); // 685 + comp_render_cs_layer( // 686 + crc, // 687 + view_index, // 688 + layers, // 689 + layer_count, // 690 + &view->target_pre_transform, // 691 + &view->world_pose, // 692 + &view->eye_pose, // 693 + view->image, // 694 + view->cs.unorm_view, // 695 + &view->layer_viewport_data, // 696 + d->do_timewarp); // 640 697 } 641 698 642 - for (uint32_t view_index = 0; view_index < 2; view_index++) { 643 - comp_render_cs_layer( // 644 - crc, // 645 - view_index, // 646 - layers, // 647 - layer_count, // 648 - &pre_transforms[view_index], // 649 - &world_poses[view_index], // 650 - &eye_poses[view_index], // 651 - target_images[view_index], // 652 - target_image_views[view_index], // 653 - &target_views[view_index], // 654 - do_timewarp); // 655 - } 656 - 657 - vk_cmd_image_barrier_locked( // 658 - crc->r->vk, // 659 - crc->r->cmd, // 660 - target_images[0], // 661 - VK_ACCESS_SHADER_WRITE_BIT, // 662 - VK_ACCESS_MEMORY_READ_BIT, // 663 - VK_IMAGE_LAYOUT_GENERAL, // 664 - transition_to, // 665 - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // 666 - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // 667 - first_color_level_subresource_range); // 668 - 669 - if (target_images[0] != target_images[1]) { 670 - vk_cmd_image_barrier_locked( // 671 - crc->r->vk, // 672 - crc->r->cmd, // 673 - target_images[1], // 674 - VK_ACCESS_SHADER_WRITE_BIT, // 675 - VK_ACCESS_MEMORY_READ_BIT, // 676 - VK_IMAGE_LAYOUT_GENERAL, // 677 - transition_to, // 678 - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // 679 - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // 680 - first_color_level_subresource_range); // 681 - } 682 - } 683 - 684 - void 685 - comp_render_cs_stereo_layers_to_scratch(struct render_compute *crc, 686 - const struct xrt_normalized_rect pre_transforms[2], 687 - struct xrt_pose world_poses[2], 688 - struct xrt_pose eye_poses[2], 689 - const struct comp_layer *layers, 690 - const uint32_t layer_count, 691 - struct render_scratch_images *rsi, 692 - VkImageLayout transition_to, 693 - bool do_timewarp) 694 - { 695 - struct render_viewport_data target_views[2] = { 696 - {.w = rsi->extent.width, .h = rsi->extent.height}, 697 - {.w = rsi->extent.width, .h = rsi->extent.height}, 698 - }; 699 - 700 - VkImage target_images[2] = { 701 - rsi->color[0].image, 702 - rsi->color[1].image, 703 - }; 704 - 705 - VkImageView target_image_views[2] = { 706 - rsi->color[0].unorm_view, // Have to write in linear 707 - rsi->color[1].unorm_view, 708 - }; 709 - 710 - comp_render_cs_stereo_layers( // 711 - crc, // crc 712 - layers, // layers 713 - layer_count, // layer_count 714 - pre_transforms, // pre_transforms 715 - world_poses, // world_poses 716 - eye_poses, // eye_poses 717 - target_images, // target_images 718 - target_image_views, // target_image_views 719 - target_views, // target_views 720 - transition_to, // transition_to 721 - do_timewarp); // do_timewarp 699 + cmd_barrier_view_images( // 700 + crc->r->vk, // 701 + d, // 702 + crc->r->cmd, // cmd 703 + VK_ACCESS_SHADER_WRITE_BIT, // src_access_mask 704 + VK_ACCESS_MEMORY_READ_BIT, // dst_access_mask 705 + VK_IMAGE_LAYOUT_GENERAL, // transition_from 706 + transition_to, // transition_to 707 + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // src_stage_mask 708 + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); // dst_stage_mask 722 709 } 723 710 724 711 void 725 712 comp_render_cs_dispatch(struct render_compute *crc, 726 - struct render_scratch_images *rsi, 727 - struct xrt_pose world_poses[2], 728 - struct xrt_pose eye_poses[2], 729 713 const struct comp_layer *layers, 730 714 const uint32_t layer_count, 731 - VkImage target_image, 732 - VkImageView target_image_view, 733 - const struct render_viewport_data views[2], 734 - bool fast_path, 735 - bool do_timewarp) 715 + const struct comp_render_dispatch_data *d) 736 716 { 717 + // Convenience. 718 + bool fast_path = d->fast_path; 719 + 737 720 assert(!fast_path || layer_count > 0); 738 721 739 - // We make an assumption that we will be using the distortion code. 740 - const struct xrt_normalized_rect pre_transforms[2] = { 741 - crc->r->distortion.uv_to_tanangle[0], 742 - crc->r->distortion.uv_to_tanangle[1], 743 - }; 744 - 745 722 // We want to read from the images afterwards. 746 723 VkImageLayout transition_to = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 747 724 ··· 752 729 const struct xrt_layer_projection_view_data *lvd = &stereo->l; 753 730 const struct xrt_layer_projection_view_data *rvd = &stereo->r; 754 731 755 - do_cs_distortion_for_layer( // 756 - crc, // crc 757 - world_poses, // world_poses 758 - layer, // layer 759 - lvd, // lvd 760 - rvd, // rvd 761 - target_image, // target_image 762 - target_image_view, // target_image_view 763 - views, // views 764 - do_timewarp); // do_timewarp 732 + do_cs_distortion_from_stereo_layer( // 733 + crc, // crc 734 + layer, // layer 735 + lvd, // lvd 736 + rvd, // rvd 737 + d); // d 765 738 } else if (fast_path && layers[0].data.type == XRT_LAYER_STEREO_PROJECTION_DEPTH) { 766 739 int i = 0; 767 740 const struct comp_layer *layer = &layers[i]; ··· 769 742 const struct xrt_layer_projection_view_data *lvd = &stereo->l; 770 743 const struct xrt_layer_projection_view_data *rvd = &stereo->r; 771 744 772 - do_cs_distortion_for_layer( // 773 - crc, // crc 774 - world_poses, // world_poses 775 - layer, // layer 776 - lvd, // lvd 777 - rvd, // rvd 778 - target_image, // target_image 779 - target_image_view, // target_image_view 780 - views, // views 781 - do_timewarp); // do_timewarp 745 + do_cs_distortion_from_stereo_layer( // 746 + crc, // crc 747 + layer, // layer 748 + lvd, // lvd 749 + rvd, // rvd 750 + d); // d 782 751 } else if (layer_count > 0) { 783 - comp_render_cs_stereo_layers_to_scratch( // 784 - crc, // 785 - pre_transforms, // 786 - world_poses, // 787 - eye_poses, // 788 - layers, // 789 - layer_count, // 790 - rsi, // 791 - transition_to, // 792 - do_timewarp); // 752 + comp_render_cs_layers( // 753 + crc, // 754 + layers, // 755 + layer_count, // 756 + d, // 757 + transition_to); // 793 758 794 - do_cs_distortion_for_scratch( // 795 - crc, // 796 - rsi, // 797 - target_image, // 798 - target_image_view, // 799 - views); // 759 + do_cs_distortion_from_scratch( // 760 + crc, // 761 + d); // 800 762 } else { 801 - render_compute_clear( // 802 - crc, // 803 - target_image, // 804 - target_image_view, // 805 - views); // 763 + do_cs_clear( // 764 + crc, // 765 + d); // 806 766 } 807 767 }
+256 -212
src/xrt/compositor/util/comp_render_gfx.c
··· 1 - // Copyright 2023, Collabora, Ltd. 1 + // Copyright 2023-2024, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 30 30 */ 31 31 32 32 /* 33 - * Internal state for a single view. 33 + * Internal per-view for the layer shashing render step. 34 34 */ 35 - struct gfx_view_state 35 + struct gfx_layer_view_state 36 36 { 37 37 // Filled out descriptor sets. 38 38 VkDescriptorSet descriptor_sets[RENDER_MAX_LAYERS]; ··· 64 64 struct xrt_matrix_4x4 eye_vp_rot_only; 65 65 }; 66 66 67 + /* 68 + * Internal state for the layer squashing render step. 69 + */ 70 + struct gfx_layer_state 71 + { 72 + struct gfx_layer_view_state views[2]; 73 + }; 74 + 75 + /* 76 + * Internal state for the mesh rendering step. 77 + */ 78 + struct gfx_mesh_state 79 + { 80 + VkDescriptorSet descriptor_sets[2]; 81 + }; 82 + 83 + /* 84 + * Per-view input data for the mesh rendering step. 85 + */ 86 + struct gfx_mesh_view_data 87 + { 88 + struct xrt_pose src_pose; 89 + struct xrt_fov src_fov; 90 + struct xrt_normalized_rect src_norm_rect; 91 + VkSampler src_sampler; 92 + VkImageView src_image_view; 93 + }; 94 + 95 + /* 96 + * Input data for the mesh rendering step, 97 + * combined with comp_render_dispatch_data. 98 + */ 99 + struct gfx_mesh_data 100 + { 101 + struct gfx_mesh_view_data views[2]; 102 + }; 103 + 67 104 68 105 /* 69 106 * ··· 82 119 83 120 /* 84 121 * 122 + * Input builder functions. 123 + * 124 + */ 125 + 126 + inline static void 127 + gfx_mesh_add_view(struct gfx_mesh_data *md, 128 + uint32_t view_index, 129 + const struct xrt_pose *src_pose, 130 + const struct xrt_fov *src_fov, 131 + const struct xrt_normalized_rect *src_norm_rect, 132 + VkSampler src_sampler, 133 + VkImageView src_image_view) 134 + { 135 + md->views[view_index].src_pose = *src_pose; 136 + md->views[view_index].src_fov = *src_fov; 137 + md->views[view_index].src_norm_rect = *src_norm_rect; 138 + md->views[view_index].src_sampler = src_sampler; 139 + md->views[view_index].src_image_view = src_image_view; 140 + } 141 + 142 + 143 + 144 + /* 145 + * 85 146 * Model view projection helper functions. 86 147 * 87 148 */ 88 149 89 150 static inline void 90 - calc_mvp_full(struct gfx_view_state *state, 151 + calc_mvp_full(struct gfx_layer_view_state *state, 91 152 const struct xrt_layer_data *layer_data, 92 153 const struct xrt_pose *pose, 93 154 const struct xrt_vec3 *scale, ··· 104 165 } 105 166 106 167 static inline void 107 - calc_mv_inv_full(struct gfx_view_state *state, 168 + calc_mv_inv_full(struct gfx_layer_view_state *state, 108 169 const struct xrt_layer_data *layer_data, 109 170 const struct xrt_pose *pose, 110 171 const struct xrt_vec3 *scale, ··· 127 188 } 128 189 129 190 static inline void 130 - calc_mvp_rot_only(struct gfx_view_state *state, 191 + calc_mvp_rot_only(struct gfx_layer_view_state *state, 131 192 const struct xrt_layer_data *data, 132 193 const struct xrt_pose *pose, 133 194 const struct xrt_vec3 *scale, ··· 155 216 */ 156 217 157 218 static inline void 158 - add_layer(struct gfx_view_state *state, const struct xrt_layer_data *data, VkDescriptorSet descriptor_set) 219 + add_layer(struct gfx_layer_view_state *state, const struct xrt_layer_data *data, VkDescriptorSet descriptor_set) 159 220 { 160 221 uint32_t cur_layer = state->layer_count++; 161 222 state->descriptor_sets[cur_layer] = descriptor_set; ··· 169 230 uint32_t view_index, 170 231 VkSampler clamp_to_edge, 171 232 VkSampler clamp_to_border_black, 172 - struct gfx_view_state *state) 233 + struct gfx_layer_view_state *state) 173 234 { 174 235 const struct xrt_layer_data *layer_data = &layer->data; 175 236 const struct xrt_layer_cylinder_data *c = &layer_data->cylinder; ··· 233 294 uint32_t view_index, 234 295 VkSampler clamp_to_edge, 235 296 VkSampler clamp_to_border_black, 236 - struct gfx_view_state *state) 297 + struct gfx_layer_view_state *state) 237 298 { 238 299 const struct xrt_layer_data *layer_data = &layer->data; 239 300 const struct xrt_layer_equirect2_data *eq2 = &layer_data->equirect2; ··· 297 358 uint32_t view_index, 298 359 VkSampler clamp_to_edge, 299 360 VkSampler clamp_to_border_black, 300 - struct gfx_view_state *state) 361 + struct gfx_layer_view_state *state) 301 362 { 302 363 const struct xrt_layer_data *layer_data = &layer->data; 303 364 const struct xrt_layer_projection_view_data *vd = NULL; ··· 359 420 uint32_t view_index, 360 421 VkSampler clamp_to_edge, 361 422 VkSampler clamp_to_border_black, 362 - struct gfx_view_state *state) 423 + struct gfx_layer_view_state *state) 363 424 { 364 425 const struct xrt_layer_data *layer_data = &layer->data; 365 426 const struct xrt_layer_quad_data *q = &layer_data->quad; ··· 406 467 407 468 static void 408 469 do_layers(struct render_gfx *rr, 409 - struct render_gfx_target_resources rtrs[2], 410 - const struct render_viewport_data viewport_datas[2], 411 - const struct xrt_fov new_fovs[2], 412 - const struct xrt_pose world_poses[2], 413 - const struct xrt_pose eye_poses[2], 414 470 const struct comp_layer *layers, 415 - uint32_t layer_count) 471 + uint32_t layer_count, 472 + const struct comp_render_dispatch_data *d) 416 473 { 417 474 COMP_TRACE_MARKER(); 418 475 ··· 420 477 VkResult ret; 421 478 422 479 // Hardcoded to stereo. 423 - struct gfx_view_state views[2] = XRT_STRUCT_INIT; 480 + struct gfx_layer_state ls = XRT_STRUCT_INIT; 481 + 482 + for (uint32_t view = 0; view < d->view_count; view++) { 483 + 484 + // Data for this view, convenience. 485 + const struct xrt_pose world_pose = d->views[view].world_pose; 486 + const struct xrt_pose eye_pose = d->views[view].eye_pose; 487 + const struct xrt_fov new_fov = d->views[view].fov; 424 488 425 - for (uint32_t view = 0; view < ARRAY_SIZE(views); view++) { 489 + // Current state we are writing to. 490 + struct gfx_layer_view_state *state = &ls.views[view]; 426 491 427 492 // Used to go from UV to tangent space. 428 - render_calc_uv_to_tangent_lengths_rect(&new_fovs[view], &views[view].to_tangent); 493 + render_calc_uv_to_tangent_lengths_rect(&new_fov, &state->to_tangent); 429 494 430 495 // Projection 431 496 struct xrt_matrix_4x4 p; 432 - math_matrix_4x4_projection_vulkan_infinite_reverse(&new_fovs[view], 0.1, &p); 497 + math_matrix_4x4_projection_vulkan_infinite_reverse(&new_fov, 0.1, &p); 433 498 434 499 // Reused view matrix. 435 500 struct xrt_matrix_4x4 v; 436 501 437 502 // World 438 - math_matrix_4x4_view_from_pose(&world_poses[view], &v); 439 - math_matrix_4x4_multiply(&p, &v, &views[view].world_vp_full); 440 - math_matrix_4x4_inverse(&v, &views[view].world_v_inv_full); 503 + math_matrix_4x4_view_from_pose(&world_pose, &v); 504 + math_matrix_4x4_multiply(&p, &v, &state->world_vp_full); 505 + math_matrix_4x4_inverse(&v, &state->world_v_inv_full); 441 506 442 - struct xrt_pose world_rot_only = {world_poses[view].orientation, XRT_VEC3_ZERO}; 507 + struct xrt_pose world_rot_only = {world_pose.orientation, XRT_VEC3_ZERO}; 443 508 math_matrix_4x4_view_from_pose(&world_rot_only, &v); 444 - math_matrix_4x4_multiply(&p, &v, &views[view].world_vp_rot_only); 509 + math_matrix_4x4_multiply(&p, &v, &state->world_vp_rot_only); 445 510 446 511 // Eye 447 - math_matrix_4x4_view_from_pose(&eye_poses[view], &v); 448 - math_matrix_4x4_multiply(&p, &v, &views[view].eye_vp_full); 449 - math_matrix_4x4_inverse(&v, &views[view].eye_v_inv_full); 512 + math_matrix_4x4_view_from_pose(&eye_pose, &v); 513 + math_matrix_4x4_multiply(&p, &v, &state->eye_vp_full); 514 + math_matrix_4x4_inverse(&v, &state->eye_v_inv_full); 450 515 451 - struct xrt_pose eye_rot_only = {eye_poses[view].orientation, XRT_VEC3_ZERO}; 516 + struct xrt_pose eye_rot_only = {eye_pose.orientation, XRT_VEC3_ZERO}; 452 517 math_matrix_4x4_view_from_pose(&eye_rot_only, &v); 453 - math_matrix_4x4_multiply(&p, &v, &views[view].eye_vp_rot_only); 518 + math_matrix_4x4_multiply(&p, &v, &state->eye_vp_rot_only); 454 519 } 455 520 456 521 /* ··· 464 529 VkSampler clamp_to_edge = rr->r->samplers.clamp_to_edge; 465 530 VkSampler clamp_to_border_black = rr->r->samplers.clamp_to_border_black; 466 531 467 - for (uint32_t view = 0; view < ARRAY_SIZE(views); view++) { 532 + for (uint32_t view = 0; view < d->view_count; view++) { 533 + 534 + // Source for data and written to as well, read and write. 535 + struct gfx_layer_view_state *state = &ls.views[view]; 536 + 468 537 for (uint32_t i = 0; i < layer_count; i++) { 469 538 const struct xrt_layer_data *data = &layers[i].data; 470 539 if (!is_layer_view_visible(data, view)) { ··· 479 548 view, // view_index 480 549 clamp_to_edge, // clamp_to_edge 481 550 clamp_to_border_black, // clamp_to_border_black 482 - &views[view]); // state 551 + state); // state 483 552 VK_CHK_WITH_GOTO(ret, "do_cylinder_layer", err_layer); 484 553 break; 485 554 case XRT_LAYER_EQUIRECT2: ··· 489 558 view, // view_index 490 559 clamp_to_edge, // clamp_to_edge 491 560 clamp_to_border_black, // clamp_to_border_black 492 - &views[view]); // state 561 + state); // state 493 562 VK_CHK_WITH_GOTO(ret, "do_equirect2_layer", err_layer); 494 563 break; 495 564 case XRT_LAYER_STEREO_PROJECTION: ··· 500 569 view, // view_index 501 570 clamp_to_edge, // clamp_to_edge 502 571 clamp_to_border_black, // clamp_to_border_black 503 - &views[view]); // state 572 + state); // state 504 573 VK_CHK_WITH_GOTO(ret, "do_projection_layer", err_layer); 505 574 break; 506 575 case XRT_LAYER_QUAD: ··· 510 579 view, // view_index 511 580 clamp_to_edge, // clamp_to_edge 512 581 clamp_to_border_black, // clamp_to_border_black 513 - &views[view]); // state 582 + state); // state 514 583 VK_CHK_WITH_GOTO(ret, "do_quad_layer", err_layer); 515 584 break; 516 585 default: break; ··· 525 594 526 595 const VkClearColorValue *color = layer_count == 0 ? &background_color_idle : &background_color_active; 527 596 528 - for (uint32_t view = 0; view < ARRAY_SIZE(views); view++) { 529 - render_gfx_begin_target( // 530 - rr, // 531 - &rtrs[view], // 532 - color); // 597 + for (uint32_t view = 0; view < d->view_count; view++) { 598 + 599 + // Convenience. 600 + const struct render_viewport_data *viewport_data = &d->views[view].layer_viewport_data; 533 601 534 - render_gfx_begin_view( // 602 + render_gfx_begin_target( // 535 603 rr, // 536 - view, // view_index 537 - &viewport_datas[view]); // viewport_data 604 + d->views[view].gfx.rtr, // 605 + color); // 606 + 607 + render_gfx_begin_view( // 608 + rr, // 609 + view, // view_index 610 + viewport_data); // viewport_data 538 611 539 - struct gfx_view_state *state = &views[view]; 612 + // Only source for data here, read only. 613 + const struct gfx_layer_view_state *state = &ls.views[view]; 540 614 541 615 for (uint32_t i = 0; i < state->layer_count; i++) { 542 616 switch (state->types[i]) { ··· 591 665 592 666 static void 593 667 do_mesh(struct render_gfx *rr, 594 - struct render_gfx_target_resources *rtr, 595 - const struct render_viewport_data viewport_datas[2], 596 - const struct xrt_matrix_2x2 vertex_rots[2], 597 - VkSampler src_samplers[2], 598 - VkImageView src_image_views[2], 599 - const struct xrt_normalized_rect src_norm_rects[2], 600 - const struct xrt_pose src_poses[2], 601 - const struct xrt_fov src_fovs[2], 602 - const struct xrt_pose new_poses[2], 603 - bool do_timewarp) 668 + bool do_timewarp, 669 + const struct gfx_mesh_data *md, 670 + const struct comp_render_dispatch_data *d) 604 671 { 605 672 struct vk_bundle *vk = rr->r->vk; 606 673 VkResult ret; ··· 611 678 * write a copy command before the other gfx commands. 612 679 */ 613 680 614 - VkDescriptorSet descriptor_sets[2] = XRT_STRUCT_INIT; 615 - for (uint32_t i = 0; i < 2; i++) { 681 + struct gfx_mesh_state ms = XRT_STRUCT_INIT; 682 + 683 + for (uint32_t i = 0; i < d->view_count; i++) { 616 684 617 685 struct render_gfx_mesh_ubo_data data = { 618 - .vertex_rot = vertex_rots[i], 619 - .post_transform = src_norm_rects[i], 686 + .vertex_rot = d->views[i].gfx.vertex_rot, 687 + .post_transform = md->views[i].src_norm_rect, 620 688 }; 621 689 622 690 // Extra arguments for timewarp. 623 691 if (do_timewarp) { 624 - data.pre_transform = rr->r->distortion.uv_to_tanangle[i]; 692 + data.pre_transform = d->views[i].target_pre_transform; 625 693 626 694 render_calc_time_warp_matrix( // 627 - &src_poses[i], // 628 - &src_fovs[i], // 629 - &new_poses[i], // 695 + &md->views[i].src_pose, // 696 + &md->views[i].src_fov, // 697 + &d->views[i].world_pose, // 630 698 &data.transform); // 631 699 } 632 700 633 701 ret = render_gfx_mesh_alloc_and_write( // 634 702 rr, // 635 703 &data, // 636 - src_samplers[i], // 637 - src_image_views[i], // 638 - &descriptor_sets[i]); // 704 + md->views[i].src_sampler, // 705 + md->views[i].src_image_view, // 706 + &ms.descriptor_sets[i]); // 639 707 VK_CHK_WITH_GOTO(ret, "render_gfx_mesh_alloc", err_no_memory); 640 708 641 - VK_NAME_DESCRIPTOR_SET(vk, descriptor_sets[i], "render_gfx mesh descriptor sets"); 709 + VK_NAME_DESCRIPTOR_SET(vk, ms.descriptor_sets[i], "render_gfx mesh descriptor sets"); 642 710 } 643 711 644 712 ··· 648 716 649 717 render_gfx_begin_target( // 650 718 rr, // 651 - rtr, // 719 + d->gfx.rtr, // 652 720 &background_color_active); // 653 721 654 - for (uint32_t i = 0; i < 2; i++) { 655 - render_gfx_begin_view( // 656 - rr, // 657 - i, // view_index 658 - &viewport_datas[i]); // viewport_data 722 + for (uint32_t i = 0; i < d->view_count; i++) { 723 + // Convenience. 724 + const struct render_viewport_data *viewport_data = &d->views[i].target_viewport_data; 725 + 726 + render_gfx_begin_view( // 727 + rr, // 728 + i, // view_index 729 + viewport_data); // viewport_data 659 730 660 - render_gfx_mesh_draw( // 661 - rr, // rr 662 - i, // mesh_index 663 - descriptor_sets[i], // descriptor_set 664 - do_timewarp); // do_timewarp 731 + render_gfx_mesh_draw( // 732 + rr, // rr 733 + i, // mesh_index 734 + ms.descriptor_sets[i], // descriptor_set 735 + do_timewarp); // do_timewarp 665 736 666 737 render_gfx_end_view(rr); 667 738 } ··· 677 748 678 749 static void 679 750 do_mesh_from_proj(struct render_gfx *rr, 680 - struct render_gfx_target_resources *rts, 681 - const struct render_viewport_data viewport_datas[2], 682 - const struct xrt_matrix_2x2 vertex_rots[2], 751 + const struct comp_render_dispatch_data *d, 683 752 const struct comp_layer *layer, 684 753 const struct xrt_layer_projection_view_data *lvd, 685 - const struct xrt_layer_projection_view_data *rvd, 686 - const struct xrt_pose new_poses[2], 687 - bool do_timewarp) 754 + const struct xrt_layer_projection_view_data *rvd) 688 755 { 689 756 const struct xrt_layer_data *data = &layer->data; 690 757 const uint32_t left_array_index = lvd->sub.array_index; ··· 692 759 const struct comp_swapchain_image *left = &layer->sc_array[0]->images[lvd->sub.image_index]; 693 760 const struct comp_swapchain_image *right = &layer->sc_array[1]->images[rvd->sub.image_index]; 694 761 695 - struct xrt_normalized_rect src_norm_rects[2] = {lvd->sub.norm_rect, rvd->sub.norm_rect}; 696 - if (data->flip_y) { 697 - src_norm_rects[0].h = -src_norm_rects[0].h; 698 - src_norm_rects[0].y = 1 + src_norm_rects[0].y; 699 - src_norm_rects[1].h = -src_norm_rects[1].h; 700 - src_norm_rects[1].y = 1 + src_norm_rects[1].y; 701 - } 762 + VkSampler clamp_to_border_black = rr->r->samplers.clamp_to_border_black; 763 + 764 + struct gfx_mesh_data md = XRT_STRUCT_INIT; 765 + for (uint32_t i = 0; i < d->view_count; i++) { 702 766 703 - VkSampler clamp_to_border_black = rr->r->samplers.clamp_to_border_black; 704 - VkSampler src_samplers[2] = { 705 - clamp_to_border_black, 706 - clamp_to_border_black, 707 - }; 767 + struct xrt_pose src_pose; 768 + struct xrt_fov src_fov; 769 + struct xrt_normalized_rect src_norm_rect; 770 + VkImageView src_image_view; 771 + 772 + if (!is_view_index_right(i)) { 773 + // Left, aka not right. 774 + src_pose = lvd->pose; 775 + src_fov = lvd->fov; 776 + src_norm_rect = lvd->sub.norm_rect; 777 + src_image_view = get_image_view(left, data->flags, left_array_index); 778 + } else { 779 + // Right 780 + src_pose = rvd->pose; 781 + src_fov = rvd->fov; 782 + src_norm_rect = rvd->sub.norm_rect; 783 + src_image_view = get_image_view(right, data->flags, right_array_index); 784 + } 708 785 709 - VkImageView src_image_views[2] = { 710 - get_image_view(left, data->flags, left_array_index), 711 - get_image_view(right, data->flags, right_array_index), 712 - }; 786 + if (data->flip_y) { 787 + src_norm_rect.h = -src_norm_rect.h; 788 + src_norm_rect.y = 1 + src_norm_rect.y; 789 + } 713 790 714 - const struct xrt_pose src_poses[2] = {lvd->pose, rvd->pose}; 715 - const struct xrt_fov src_fovs[2] = {lvd->fov, rvd->fov}; 791 + gfx_mesh_add_view( // 792 + &md, // md 793 + i, // view_index 794 + &src_pose, // src_pose 795 + &src_fov, // src_fov 796 + &src_norm_rect, // src_norm_rect 797 + clamp_to_border_black, // src_sampler 798 + src_image_view); // src_image_view 799 + } 716 800 717 - do_mesh( // 718 - rr, // 719 - rts, // 720 - viewport_datas, // 721 - vertex_rots, // 722 - src_samplers, // 723 - src_image_views, // 724 - src_norm_rects, // 725 - src_poses, // 726 - src_fovs, // 727 - new_poses, // 728 - do_timewarp); // 801 + do_mesh( // 802 + rr, // 803 + d->do_timewarp, // 804 + &md, // 805 + d); // 729 806 } 730 807 731 808 809 + /* 810 + * 811 + * 'Exported' function(s). 812 + * 813 + */ 814 + 732 815 void 733 816 comp_render_gfx_dispatch(struct render_gfx *rr, 734 - struct render_scratch_images *rsi, 735 - struct render_gfx_target_resources rsi_rtrs[2], 736 817 const struct comp_layer *layers, 737 818 const uint32_t layer_count, 738 - struct xrt_pose world_poses[2], 739 - struct xrt_pose eye_poses[2], 740 - struct xrt_fov fovs[2], 741 - struct xrt_matrix_2x2 vertex_rots[2], 742 - struct render_gfx_target_resources *rtr, 743 - const struct render_viewport_data viewport_datas[2], 744 - bool fast_path, 745 - bool do_timewarp) 819 + const struct comp_render_dispatch_data *d) 746 820 { 821 + // Convenience. 822 + bool fast_path = d->fast_path; 823 + 747 824 // Only used if fast_path is true. 748 825 const struct comp_layer *layer = &layers[0]; 749 826 ··· 756 833 const struct xrt_layer_projection_view_data *lvd = &stereo->l; 757 834 const struct xrt_layer_projection_view_data *rvd = &stereo->r; 758 835 759 - do_mesh_from_proj( // 760 - rr, // 761 - rtr, // 762 - viewport_datas, // 763 - vertex_rots, // 764 - layer, // 765 - lvd, // 766 - rvd, // 767 - world_poses, // 768 - do_timewarp); // 836 + do_mesh_from_proj( // 837 + rr, // 838 + d, // 839 + layer, // 840 + lvd, // 841 + rvd); // 769 842 770 843 } else if (fast_path && layer->data.type == XRT_LAYER_STEREO_PROJECTION_DEPTH) { 771 844 // Fast path. ··· 773 846 const struct xrt_layer_projection_view_data *lvd = &stereo->l; 774 847 const struct xrt_layer_projection_view_data *rvd = &stereo->r; 775 848 776 - do_mesh_from_proj( // 777 - rr, // 778 - rtr, // 779 - viewport_datas, // 780 - vertex_rots, // 781 - layer, // 782 - lvd, // 783 - rvd, // 784 - world_poses, // 785 - do_timewarp); // 849 + do_mesh_from_proj( // 850 + rr, // 851 + d, // 852 + layer, // 853 + lvd, // 854 + rvd); // 786 855 787 856 } else { 788 857 if (fast_path) { 789 858 U_LOG_W("Wanted fast path but no projection layer, falling back to layer squasher."); 790 859 } 791 860 792 - struct render_viewport_data layer_viewport_datas[2] = { 793 - {.x = 0, .y = 0, .w = rsi->extent.width, .h = rsi->extent.height}, 794 - {.x = 0, .y = 0, .w = rsi->extent.width, .h = rsi->extent.height}, 795 - }; 796 861 797 - do_layers( // 798 - rr, // rr 799 - rsi_rtrs, // rtrs 800 - layer_viewport_datas, // viewport_datas 801 - fovs, // new_fovs 802 - world_poses, // world_poses 803 - eye_poses, // eye_poses 804 - layers, // layers 805 - layer_count); // layer_count 862 + /* 863 + * Layer squashing. 864 + */ 865 + 866 + do_layers( // 867 + rr, // rr 868 + layers, // layers 869 + layer_count, // layer_count 870 + d); // d 806 871 807 872 808 - VkImageSubresourceRange first_color_level_subresource_range = { 809 - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 810 - .baseMipLevel = 0, 811 - .levelCount = 1, 812 - .baseArrayLayer = 0, 813 - .layerCount = 1, 814 - }; 873 + /* 874 + * Distortion. 875 + */ 815 876 816 877 VkImageLayout transition_from = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 817 878 VkImageLayout transition_to = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 818 879 819 - vk_cmd_image_barrier_locked( // 880 + cmd_barrier_view_images( // 820 881 rr->r->vk, // 821 - rr->r->cmd, // 822 - rsi->color[0].image, // 823 - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // 824 - VK_ACCESS_SHADER_READ_BIT, // 825 - transition_from, // 826 - transition_to, // 827 - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 828 - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // 829 - first_color_level_subresource_range); // 882 + d, // 883 + rr->r->cmd, // cmd 884 + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // src_access_mask 885 + VK_ACCESS_SHADER_READ_BIT, // dst_access_mask 886 + transition_from, // transition_from 887 + transition_to, // transition_to 888 + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // src_stage_mask 889 + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); // dst_stage_mask 830 890 831 - if (rsi->color[0].image != rsi->color[1].image) { 832 - vk_cmd_image_barrier_locked( // 833 - rr->r->vk, // 834 - rr->r->cmd, // 835 - rsi->color[1].image, // 836 - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // 837 - VK_ACCESS_SHADER_READ_BIT, // 838 - transition_from, // 839 - transition_to, // 840 - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 841 - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // 842 - first_color_level_subresource_range); // 843 - } 891 + // Shared between all views. 892 + VkSampler clamp_to_border_black = rr->r->samplers.clamp_to_border_black; 844 893 845 - VkSampler clamp_to_border_black = rr->r->samplers.clamp_to_border_black; 846 - VkSampler src_samplers[2] = { 847 - clamp_to_border_black, 848 - clamp_to_border_black, 849 - }; 850 - VkImageView src_image_views[2] = { 851 - rsi->color[0].srgb_view, 852 - rsi->color[1].srgb_view, 853 - }; 894 + struct gfx_mesh_data md = XRT_STRUCT_INIT; 895 + for (uint32_t i = 0; i < d->view_count; i++) { 896 + struct xrt_pose src_pose = d->views[i].world_pose; 897 + struct xrt_fov src_fov = d->views[i].fov; 898 + VkImageView src_image_view = d->views[i].srgb_view; 899 + struct xrt_normalized_rect src_norm_rect = d->views[i].layer_norm_rect; 854 900 855 - struct xrt_normalized_rect src_norm_rects[2] = { 856 - {.x = 0, .y = 0, .w = 1, .h = 1}, 857 - {.x = 0, .y = 0, .w = 1, .h = 1}, 858 - }; 901 + gfx_mesh_add_view( // 902 + &md, // md 903 + i, // view_index 904 + &src_pose, // src_pose 905 + &src_fov, // src_fov 906 + &src_norm_rect, // src_norm_rect 907 + clamp_to_border_black, // src_sampler 908 + src_image_view); // src_image_view 909 + } 859 910 860 911 // We are passing in the same old and new poses. 861 - do_mesh( // 862 - rr, // 863 - rtr, // 864 - viewport_datas, // 865 - vertex_rots, // 866 - src_samplers, // 867 - src_image_views, // 868 - src_norm_rects, // 869 - world_poses, // 870 - fovs, // 871 - world_poses, // 872 - false); // 912 + do_mesh( // 913 + rr, // 914 + false, // do_timewarp 915 + &md, // md 916 + d); // d 873 917 } 874 918 }
+61 -1
src/xrt/compositor/util/comp_render_helpers.h
··· 1 - // Copyright 2023, Collabora, Ltd. 1 + // Copyright 2023-2024, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file ··· 14 14 #include "render/render_interface.h" 15 15 16 16 #include "util/comp_base.h" 17 + #include "util/comp_render.h" 17 18 18 19 19 20 /* ··· 136 137 137 138 *out_norm_rect = rect; 138 139 } 140 + 141 + 142 + /* 143 + * 144 + * Command helpers. 145 + * 146 + */ 147 + 148 + static inline void 149 + cmd_barrier_view_images(struct vk_bundle *vk, 150 + const struct comp_render_dispatch_data *d, 151 + VkCommandBuffer cmd, 152 + VkAccessFlags src_access_mask, 153 + VkAccessFlags dst_access_mask, 154 + VkImageLayout transition_from, 155 + VkImageLayout transition_to, 156 + VkPipelineStageFlags src_stage_mask, 157 + VkPipelineStageFlags dst_stage_mask) 158 + { 159 + VkImageSubresourceRange first_color_level_subresource_range = { 160 + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 161 + .baseMipLevel = 0, 162 + .levelCount = 1, 163 + .baseArrayLayer = 0, 164 + .layerCount = 1, 165 + }; 166 + 167 + for (uint32_t i = 0; i < d->view_count; i++) { 168 + bool already_barried = false; 169 + 170 + VkImage image = d->views[i].image; 171 + 172 + uint32_t k = i; 173 + while (k > 0) { 174 + k--; // k is always greater then zero. 175 + 176 + if (d->views[k].image == image) { 177 + already_barried = true; 178 + break; 179 + } 180 + } 181 + 182 + if (already_barried) { 183 + continue; 184 + } 185 + 186 + vk_cmd_image_barrier_locked( // 187 + vk, // vk_bundle 188 + cmd, // cmd_buffer 189 + image, // image 190 + src_access_mask, // src_access_mask 191 + dst_access_mask, // dst_access_mask 192 + transition_from, // old_image_layout 193 + transition_to, // new_image_layout 194 + src_stage_mask, // src_stage_mask 195 + dst_stage_mask, // dst_stage_mask 196 + first_color_level_subresource_range); // subresource_range 197 + } 198 + }