The open source OpenXR runtime
at main 822 lines 29 kB view raw
1// Copyright 2019-2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief The compositor compute based rendering code. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup comp_render 8 */ 9 10#include "math/m_api.h" 11#include "math/m_matrix_4x4_f64.h" 12 13#include "vk/vk_mini_helpers.h" 14 15#include "render/render_interface.h" 16 17 18/* 19 * 20 * Helper functions. 21 * 22 */ 23 24/*! 25 * Get the @ref vk_bundle from @ref render_compute. 26 */ 27static inline struct vk_bundle * 28vk_from_render(struct render_compute *render) 29{ 30 return render->r->vk; 31} 32 33static uint32_t 34uint_divide_and_round_up(uint32_t a, uint32_t b) 35{ 36 return (a + (b - 1)) / b; 37} 38 39static void 40calc_dispatch_dims_1_view(const struct render_viewport_data views, uint32_t *out_w, uint32_t *out_h) 41{ 42 // Power of two divide and round up. 43 uint32_t w = uint_divide_and_round_up(views.w, 8); 44 uint32_t h = uint_divide_and_round_up(views.h, 8); 45 46 *out_w = w; 47 *out_h = h; 48} 49 50/* 51 * For dispatching compute to the view, calculate the number of groups. 52 */ 53static void 54calc_dispatch_dims_views(const struct render_viewport_data views[XRT_MAX_VIEWS], 55 uint32_t view_count, 56 uint32_t *out_w, 57 uint32_t *out_h) 58{ 59#define IMAX(a, b) ((a) > (b) ? (a) : (b)) 60 uint32_t w = 0; 61 uint32_t h = 0; 62 for (uint32_t i = 0; i < view_count; ++i) { 63 w = IMAX(w, views[i].w); 64 h = IMAX(h, views[i].h); 65 } 66#undef IMAX 67 68 // Power of two divide and round up. 69 w = uint_divide_and_round_up(w, 8); 70 h = uint_divide_and_round_up(h, 8); 71 72 *out_w = w; 73 *out_h = h; 74} 75 76 77/* 78 * 79 * Vulkan helpers. 80 * 81 */ 82 83XRT_MAYBE_UNUSED static void 84update_compute_layer_descriptor_set(struct vk_bundle *vk, 85 uint32_t src_binding, 86 VkSampler src_samplers[RENDER_MAX_IMAGES_SIZE], 87 VkImageView src_image_views[RENDER_MAX_IMAGES_SIZE], 88 uint32_t image_count, 89 uint32_t target_binding, 90 VkImageView target_image_view, 91 uint32_t ubo_binding, 92 VkBuffer ubo_buffer, 93 VkDeviceSize ubo_size, 94 VkDescriptorSet descriptor_set) 95{ 96 VkDescriptorImageInfo src_image_info[RENDER_MAX_IMAGES_SIZE]; 97 for (uint32_t i = 0; i < image_count; i++) { 98 src_image_info[i].sampler = src_samplers[i]; 99 src_image_info[i].imageView = src_image_views[i]; 100 src_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 101 } 102 103 VkDescriptorImageInfo target_image_info = { 104 .imageView = target_image_view, 105 .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 106 }; 107 108 VkDescriptorBufferInfo buffer_info = { 109 .buffer = ubo_buffer, 110 .offset = 0, 111 .range = ubo_size, 112 }; 113 114 VkWriteDescriptorSet write_descriptor_sets[3] = { 115 { 116 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 117 .dstSet = descriptor_set, 118 .dstBinding = src_binding, 119 .descriptorCount = image_count, 120 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 121 .pImageInfo = src_image_info, 122 }, 123 { 124 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 125 .dstSet = descriptor_set, 126 .dstBinding = target_binding, 127 .descriptorCount = 1, 128 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 129 .pImageInfo = &target_image_info, 130 }, 131 { 132 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 133 .dstSet = descriptor_set, 134 .dstBinding = ubo_binding, 135 .descriptorCount = 1, 136 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 137 .pBufferInfo = &buffer_info, 138 }, 139 }; 140 141 vk->vkUpdateDescriptorSets( // 142 vk->device, // 143 ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount 144 write_descriptor_sets, // pDescriptorWrites 145 0, // descriptorCopyCount 146 NULL); // pDescriptorCopies 147} 148 149XRT_MAYBE_UNUSED static void 150update_compute_shared_descriptor_set(struct vk_bundle *vk, 151 uint32_t src_binding, 152 VkSampler src_samplers[XRT_MAX_VIEWS], 153 VkImageView src_image_views[XRT_MAX_VIEWS], 154 uint32_t distortion_binding, 155 VkSampler distortion_samplers[3 * XRT_MAX_VIEWS], 156 VkImageView distortion_image_views[3 * XRT_MAX_VIEWS], 157 uint32_t target_binding, 158 VkImageView target_image_view, 159 uint32_t ubo_binding, 160 VkBuffer ubo_buffer, 161 VkDeviceSize ubo_size, 162 VkDescriptorSet descriptor_set, 163 uint32_t view_count) 164{ 165 VkDescriptorImageInfo src_image_info[XRT_MAX_VIEWS]; 166 for (uint32_t i = 0; i < view_count; ++i) { 167 src_image_info[i].sampler = src_samplers[i]; 168 src_image_info[i].imageView = src_image_views[i]; 169 src_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 170 } 171 172 VkDescriptorImageInfo distortion_image_info[3 * XRT_MAX_VIEWS]; 173 for (uint32_t i = 0; i < 3 * view_count; ++i) { 174 distortion_image_info[i].sampler = distortion_samplers[i]; 175 distortion_image_info[i].imageView = distortion_image_views[i]; 176 distortion_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 177 } 178 179 VkDescriptorImageInfo target_image_info = { 180 .imageView = target_image_view, 181 .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 182 }; 183 184 VkDescriptorBufferInfo buffer_info = { 185 .buffer = ubo_buffer, 186 .offset = 0, 187 .range = ubo_size, 188 }; 189 190 VkWriteDescriptorSet write_descriptor_sets[4] = { 191 { 192 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 193 .dstSet = descriptor_set, 194 .dstBinding = src_binding, 195 .descriptorCount = view_count, 196 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 197 .pImageInfo = src_image_info, 198 }, 199 { 200 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 201 .dstSet = descriptor_set, 202 .dstBinding = distortion_binding, 203 .descriptorCount = 3 * view_count, 204 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 205 .pImageInfo = distortion_image_info, 206 }, 207 { 208 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 209 .dstSet = descriptor_set, 210 .dstBinding = target_binding, 211 .descriptorCount = 1, 212 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 213 .pImageInfo = &target_image_info, 214 }, 215 { 216 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 217 .dstSet = descriptor_set, 218 .dstBinding = ubo_binding, 219 .descriptorCount = 1, 220 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 221 .pBufferInfo = &buffer_info, 222 }, 223 }; 224 225 vk->vkUpdateDescriptorSets( // 226 vk->device, // 227 ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount 228 write_descriptor_sets, // pDescriptorWrites 229 0, // descriptorCopyCount 230 NULL); // pDescriptorCopies 231} 232 233XRT_MAYBE_UNUSED static void 234update_compute_descriptor_set_target(struct vk_bundle *vk, 235 uint32_t target_binding, 236 VkImageView target_image_view, 237 uint32_t ubo_binding, 238 VkBuffer ubo_buffer, 239 VkDeviceSize ubo_size, 240 VkDescriptorSet descriptor_set, 241 uint32_t view_count) 242{ 243 VkDescriptorImageInfo target_image_info = { 244 .imageView = target_image_view, 245 .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 246 }; 247 248 VkDescriptorBufferInfo buffer_info = { 249 .buffer = ubo_buffer, 250 .offset = 0, 251 .range = ubo_size, 252 }; 253 254 VkWriteDescriptorSet write_descriptor_sets[2] = { 255 { 256 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 257 .dstSet = descriptor_set, 258 .dstBinding = target_binding, 259 .descriptorCount = 1, 260 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 261 .pImageInfo = &target_image_info, 262 }, 263 { 264 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 265 .dstSet = descriptor_set, 266 .dstBinding = ubo_binding, 267 .descriptorCount = 1, 268 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 269 .pBufferInfo = &buffer_info, 270 }, 271 }; 272 273 vk->vkUpdateDescriptorSets( // 274 vk->device, // 275 ARRAY_SIZE(write_descriptor_sets), // descriptorWriteCount 276 write_descriptor_sets, // pDescriptorWrites 277 0, // descriptorCopyCount 278 NULL); // pDescriptorCopies 279} 280 281static void 282dispatch_project_pipeline(struct render_compute *render, 283 VkSampler src_samplers[XRT_MAX_VIEWS], 284 VkImageView src_image_views[XRT_MAX_VIEWS], 285 const struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS], 286 VkImage target_image, 287 VkImageView target_image_view, 288 const struct render_viewport_data views[XRT_MAX_VIEWS], 289 VkPipeline pipeline) 290{ 291 struct vk_bundle *vk = vk_from_render(render); 292 struct render_resources *r = render->r; 293 294 295 /* 296 * UBO 297 */ 298 299 struct render_compute_distortion_ubo_data *data = 300 (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped; 301 for (uint32_t i = 0; i < render->r->view_count; ++i) { 302 data->views[i] = views[i]; 303 data->post_transforms[i] = src_norm_rects[i]; 304 } 305 306 307 /* 308 * Source, target and distortion images. 309 */ 310 311 VkImageSubresourceRange subresource_range = { 312 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 313 .baseMipLevel = 0, 314 .levelCount = VK_REMAINING_MIP_LEVELS, 315 .baseArrayLayer = 0, 316 .layerCount = VK_REMAINING_ARRAY_LAYERS, 317 }; 318 319 vk_cmd_image_barrier_gpu_locked( // 320 vk, // 321 r->cmd, // 322 target_image, // 323 0, // 324 VK_ACCESS_SHADER_WRITE_BIT, // 325 VK_IMAGE_LAYOUT_UNDEFINED, // 326 VK_IMAGE_LAYOUT_GENERAL, // 327 subresource_range); // 328 329 VkSampler sampler = r->samplers.clamp_to_edge; 330 VkSampler distortion_samplers[3 * XRT_MAX_VIEWS]; 331 for (uint32_t i = 0; i < render->r->view_count; ++i) { 332 distortion_samplers[3 * i + 0] = sampler; 333 distortion_samplers[3 * i + 1] = sampler; 334 distortion_samplers[3 * i + 2] = sampler; 335 } 336 337 update_compute_shared_descriptor_set( // 338 vk, // 339 r->compute.src_binding, // 340 src_samplers, // 341 src_image_views, // 342 r->compute.distortion_binding, // 343 distortion_samplers, // 344 r->distortion.image_views, // 345 r->compute.target_binding, // 346 target_image_view, // 347 r->compute.ubo_binding, // 348 r->compute.distortion.ubo.buffer, // 349 VK_WHOLE_SIZE, // 350 render->shared_descriptor_set, // 351 render->r->view_count); // 352 353 vk->vkCmdBindPipeline( // 354 r->cmd, // 355 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 356 pipeline); // pipeline 357 358 vk->vkCmdBindDescriptorSets( // 359 r->cmd, // 360 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 361 r->compute.distortion.pipeline_layout, // layout 362 0, // firstSet 363 1, // descriptorSetCount 364 &render->shared_descriptor_set, // pDescriptorSets 365 0, // dynamicOffsetCount 366 NULL); // pDynamicOffsets 367 368 369 uint32_t w = 0, h = 0; 370 calc_dispatch_dims_views(views, render->r->view_count, &w, &h); 371 assert(w != 0 && h != 0); 372 373 vk->vkCmdDispatch( // 374 r->cmd, // 375 w, // groupCountX 376 h, // groupCountY 377 2); // groupCountZ 378 379 VkImageMemoryBarrier memoryBarrier = { 380 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 381 .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, 382 .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, 383 .oldLayout = VK_IMAGE_LAYOUT_GENERAL, 384 .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 385 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 386 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 387 .image = target_image, 388 .subresourceRange = subresource_range, 389 }; 390 391 vk->vkCmdPipelineBarrier( // 392 r->cmd, // 393 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // 394 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // 395 0, // 396 0, // 397 NULL, // 398 0, // 399 NULL, // 400 1, // 401 &memoryBarrier); // 402} 403 404 405/* 406 * 407 * 'Exported' functions. 408 * 409 */ 410 411bool 412render_compute_init(struct render_compute *render, struct render_resources *r) 413{ 414 VkResult ret; 415 416 assert(render->r == NULL); 417 418 struct vk_bundle *vk = r->vk; 419 render->r = r; 420 421 for (uint32_t i = 0; i < RENDER_MAX_LAYER_RUNS_COUNT(r); i++) { 422 ret = vk_create_descriptor_set( // 423 vk, // vk_bundle 424 r->compute.descriptor_pool, // descriptor_pool 425 r->compute.layer.descriptor_set_layout, // descriptor_set_layout 426 &render->layer_descriptor_sets[i]); // descriptor_set 427 VK_CHK_WITH_RET(ret, "vk_create_descriptor_set", false); 428 429 VK_NAME_DESCRIPTOR_SET(vk, render->layer_descriptor_sets[i], "render_compute layer descriptor set"); 430 } 431 432 ret = vk_create_descriptor_set( // 433 vk, // vk_bundle 434 r->compute.descriptor_pool, // descriptor_pool 435 r->compute.distortion.descriptor_set_layout, // descriptor_set_layout 436 &render->shared_descriptor_set); // descriptor_set 437 VK_CHK_WITH_RET(ret, "vk_create_descriptor_set", false); 438 439 VK_NAME_DESCRIPTOR_SET(vk, render->shared_descriptor_set, "render_compute shared descriptor set"); 440 441 return true; 442} 443 444bool 445render_compute_begin(struct render_compute *render) 446{ 447 VkResult ret; 448 struct vk_bundle *vk = vk_from_render(render); 449 450 ret = vk->vkResetCommandPool(vk->device, render->r->cmd_pool, 0); 451 VK_CHK_WITH_RET(ret, "vkResetCommandPool", false); 452 453 VkCommandBufferBeginInfo begin_info = { 454 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 455 .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 456 }; 457 458 ret = vk->vkBeginCommandBuffer( // 459 render->r->cmd, // 460 &begin_info); // 461 VK_CHK_WITH_RET(ret, "vkBeginCommandBuffer", false); 462 463 vk->vkCmdResetQueryPool( // 464 render->r->cmd, // 465 render->r->query_pool, // 466 0, // firstQuery 467 2); // queryCount 468 469 vk->vkCmdWriteTimestamp( // 470 render->r->cmd, // 471 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // pipelineStage 472 render->r->query_pool, // 473 0); // query 474 475 return true; 476} 477 478bool 479render_compute_end(struct render_compute *render) 480{ 481 struct vk_bundle *vk = vk_from_render(render); 482 VkResult ret; 483 484 vk->vkCmdWriteTimestamp( // 485 render->r->cmd, // 486 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // pipelineStage 487 render->r->query_pool, // 488 1); // query 489 490 ret = vk->vkEndCommandBuffer(render->r->cmd); 491 VK_CHK_WITH_RET(ret, "vkEndCommandBuffer", false); 492 493 return true; 494} 495 496void 497render_compute_fini(struct render_compute *render) 498{ 499 assert(render->r != NULL); 500 501 struct vk_bundle *vk = vk_from_render(render); 502 503 // Reclaimed by vkResetDescriptorPool. 504 render->shared_descriptor_set = VK_NULL_HANDLE; 505 for (uint32_t i = 0; i < ARRAY_SIZE(render->layer_descriptor_sets); i++) { 506 render->layer_descriptor_sets[i] = VK_NULL_HANDLE; 507 } 508 509 vk->vkResetDescriptorPool(vk->device, render->r->compute.descriptor_pool, 0); 510 511 render->r = NULL; 512} 513 514void 515render_compute_layers(struct render_compute *render, 516 VkDescriptorSet descriptor_set, 517 VkBuffer ubo, 518 VkSampler src_samplers[RENDER_MAX_IMAGES_SIZE], 519 VkImageView src_image_views[RENDER_MAX_IMAGES_SIZE], 520 uint32_t num_srcs, 521 VkImageView target_image_view, 522 const struct render_viewport_data *view, 523 bool do_timewarp) 524{ 525 assert(render->r != NULL); 526 527 struct vk_bundle *vk = vk_from_render(render); 528 struct render_resources *r = render->r; 529 530 531 /* 532 * Source, target and distortion images. 533 */ 534 535 update_compute_layer_descriptor_set( // 536 vk, // 537 r->compute.src_binding, // 538 src_samplers, // 539 src_image_views, // 540 num_srcs, // 541 r->compute.target_binding, // 542 target_image_view, // 543 r->compute.ubo_binding, // 544 ubo, // 545 VK_WHOLE_SIZE, // 546 descriptor_set); // 547 548 VkPipeline pipeline = do_timewarp ? r->compute.layer.timewarp_pipeline : r->compute.layer.non_timewarp_pipeline; 549 vk->vkCmdBindPipeline( // 550 render->r->cmd, // 551 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 552 pipeline); // pipeline 553 554 vk->vkCmdBindDescriptorSets( // 555 r->cmd, // 556 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 557 r->compute.layer.pipeline_layout, // layout 558 0, // firstSet 559 1, // descriptorSetCount 560 &descriptor_set, // pDescriptorSets 561 0, // dynamicOffsetCount 562 NULL); // pDynamicOffsets 563 564 565 uint32_t w = 0, h = 0; 566 calc_dispatch_dims_1_view(*view, &w, &h); 567 assert(w != 0 && h != 0); 568 569 vk->vkCmdDispatch( // 570 r->cmd, // 571 w, // groupCountX 572 h, // groupCountY 573 1); // groupCountZ 574} 575 576void 577render_compute_projection_timewarp(struct render_compute *render, 578 VkSampler src_samplers[XRT_MAX_VIEWS], 579 VkImageView src_image_views[XRT_MAX_VIEWS], 580 const struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS], 581 const struct xrt_pose src_poses[XRT_MAX_VIEWS], 582 const struct xrt_fov src_fovs[XRT_MAX_VIEWS], 583 const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS], 584 const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS], 585 VkImage target_image, 586 VkImageView target_image_view, 587 const struct render_viewport_data views[XRT_MAX_VIEWS]) 588{ 589 assert(render->r != NULL); 590 struct render_resources *r = render->r; 591 592 593 /* 594 * UBO 595 */ 596 597 struct xrt_matrix_4x4 time_warp_matrix_scanout_begin[XRT_MAX_VIEWS]; 598 struct xrt_matrix_4x4 time_warp_matrix_scanout_end[XRT_MAX_VIEWS]; 599 for (uint32_t i = 0; i < render->r->view_count; ++i) { 600 render_calc_time_warp_matrix( // 601 &src_poses[i], // 602 &src_fovs[i], // 603 &new_poses_scanout_begin[i], // 604 &time_warp_matrix_scanout_begin[i]); // 605 606 render_calc_time_warp_matrix( // 607 &src_poses[i], // 608 &src_fovs[i], // 609 &new_poses_scanout_end[i], // 610 &time_warp_matrix_scanout_end[i]); // 611 } 612 613 struct render_compute_distortion_ubo_data *data = 614 (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped; 615 for (uint32_t i = 0; i < render->r->view_count; ++i) { 616 data->views[i] = views[i]; 617 data->pre_transforms[i] = r->distortion.uv_to_tanangle[i]; 618 data->transform_timewarp_scanout_begin[i] = time_warp_matrix_scanout_begin[i]; 619 data->transform_timewarp_scanout_end[i] = time_warp_matrix_scanout_end[i]; 620 data->post_transforms[i] = src_norm_rects[i]; 621 } 622 623 dispatch_project_pipeline(render, src_samplers, src_image_views, src_norm_rects, target_image, 624 target_image_view, views, r->compute.distortion.timewarp_pipeline); 625} 626 627 628/* 629 * This function is intended to be used on content already timewarped to new_poses_scanout_begin. 630 * It performs only the timewarp nesscary to compensate for the time delta between the start and end of 631 * scanout. 632 */ 633void 634render_compute_projection_scanout_compensation(struct render_compute *render, 635 VkSampler src_samplers[XRT_MAX_VIEWS], 636 VkImageView src_image_views[XRT_MAX_VIEWS], 637 const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS], 638 const struct xrt_fov src_fovs[XRT_MAX_VIEWS], 639 const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS], 640 const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS], 641 VkImage target_image, 642 VkImageView target_image_view, 643 const struct render_viewport_data views[XRT_MAX_VIEWS]) 644{ 645 assert(render->r != NULL); 646 struct render_resources *r = render->r; 647 648 649 /* 650 * UBO 651 */ 652 653 struct xrt_matrix_4x4 time_warp_matrix_scanout_begin[XRT_MAX_VIEWS]; 654 struct xrt_matrix_4x4 time_warp_matrix_scanout_end[XRT_MAX_VIEWS]; 655 for (uint32_t i = 0; i < render->r->view_count; ++i) { 656 render_calc_time_warp_projection(&src_fovs[i], &time_warp_matrix_scanout_begin[i]); 657 658 render_calc_time_warp_matrix( // 659 &new_poses_scanout_begin[i], // 660 &src_fovs[i], // 661 &new_poses_scanout_end[i], // 662 &time_warp_matrix_scanout_end[i]); // 663 } 664 665 struct render_compute_distortion_ubo_data *data = 666 (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped; 667 for (uint32_t i = 0; i < render->r->view_count; ++i) { 668 data->views[i] = views[i]; 669 data->pre_transforms[i] = r->distortion.uv_to_tanangle[i]; 670 data->transform_timewarp_scanout_begin[i] = time_warp_matrix_scanout_begin[i]; 671 data->transform_timewarp_scanout_end[i] = time_warp_matrix_scanout_end[i]; 672 data->post_transforms[i] = src_rects[i]; 673 } 674 675 dispatch_project_pipeline(render, src_samplers, src_image_views, src_rects, target_image, target_image_view, 676 views, r->compute.distortion.timewarp_pipeline); 677} 678 679void 680render_compute_projection_no_timewarp(struct render_compute *render, 681 VkSampler src_samplers[XRT_MAX_VIEWS], 682 VkImageView src_image_views[XRT_MAX_VIEWS], 683 const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS], 684 VkImage target_image, 685 VkImageView target_image_view, 686 const struct render_viewport_data views[XRT_MAX_VIEWS]) 687{ 688 assert(render->r != NULL); 689 struct render_resources *r = render->r; 690 691 dispatch_project_pipeline(render, src_samplers, src_image_views, src_rects, target_image, target_image_view, 692 views, r->compute.distortion.pipeline); 693} 694 695void 696render_compute_clear(struct render_compute *render, 697 VkImage target_image, 698 VkImageView target_image_view, 699 const struct render_viewport_data views[XRT_MAX_VIEWS]) 700{ 701 assert(render->r != NULL); 702 703 struct vk_bundle *vk = vk_from_render(render); 704 struct render_resources *r = render->r; 705 706 707 /* 708 * UBO 709 */ 710 711 // Calculate transforms. 712 struct xrt_matrix_4x4 transforms[XRT_MAX_VIEWS]; 713 for (uint32_t i = 0; i < render->r->view_count; i++) { 714 math_matrix_4x4_identity(&transforms[i]); 715 } 716 717 struct render_compute_distortion_ubo_data *data = 718 (struct render_compute_distortion_ubo_data *)r->compute.clear.ubo.mapped; 719 for (uint32_t i = 0; i < render->r->view_count; ++i) { 720 data->views[i] = views[i]; 721 } 722 723 /* 724 * Source, target and distortion images. 725 */ 726 727 VkImageSubresourceRange subresource_range = { 728 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 729 .baseMipLevel = 0, 730 .levelCount = VK_REMAINING_MIP_LEVELS, 731 .baseArrayLayer = 0, 732 .layerCount = VK_REMAINING_ARRAY_LAYERS, 733 }; 734 735 vk_cmd_image_barrier_gpu_locked( // 736 vk, // 737 r->cmd, // 738 target_image, // 739 0, // 740 VK_ACCESS_SHADER_WRITE_BIT, // 741 VK_IMAGE_LAYOUT_UNDEFINED, // 742 VK_IMAGE_LAYOUT_GENERAL, // 743 subresource_range); // 744 745 VkSampler sampler = r->samplers.mock; 746 VkSampler src_samplers[XRT_MAX_VIEWS]; 747 VkImageView src_image_views[XRT_MAX_VIEWS]; 748 VkSampler distortion_samplers[3 * XRT_MAX_VIEWS]; 749 for (uint32_t i = 0; i < render->r->view_count; ++i) { 750 src_samplers[i] = sampler; 751 src_image_views[i] = r->mock.color.image_view; 752 distortion_samplers[3 * i + 0] = sampler; 753 distortion_samplers[3 * i + 1] = sampler; 754 distortion_samplers[3 * i + 2] = sampler; 755 } 756 757 update_compute_shared_descriptor_set( // 758 vk, // 759 r->compute.src_binding, // 760 src_samplers, // 761 src_image_views, // 762 r->compute.distortion_binding, // 763 distortion_samplers, // 764 r->distortion.image_views, // 765 r->compute.target_binding, // 766 target_image_view, // 767 r->compute.ubo_binding, // 768 r->compute.clear.ubo.buffer, // 769 VK_WHOLE_SIZE, // ubo_size 770 render->shared_descriptor_set, // descriptor_set 771 render->r->view_count); // 772 773 vk->vkCmdBindPipeline( // 774 r->cmd, // 775 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 776 r->compute.clear.pipeline); // pipeline 777 778 vk->vkCmdBindDescriptorSets( // 779 r->cmd, // 780 VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint 781 r->compute.distortion.pipeline_layout, // layout 782 0, // firstSet 783 1, // descriptorSetCount 784 &render->shared_descriptor_set, // pDescriptorSets 785 0, // dynamicOffsetCount 786 NULL); // pDynamicOffsets 787 788 789 uint32_t w = 0, h = 0; 790 calc_dispatch_dims_views(views, render->r->view_count, &w, &h); 791 assert(w != 0 && h != 0); 792 793 vk->vkCmdDispatch( // 794 r->cmd, // 795 w, // groupCountX 796 h, // groupCountY 797 2); // groupCountZ 798 799 VkImageMemoryBarrier memoryBarrier = { 800 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 801 .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, 802 .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, 803 .oldLayout = VK_IMAGE_LAYOUT_GENERAL, 804 .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 805 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 806 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 807 .image = target_image, 808 .subresourceRange = subresource_range, 809 }; 810 811 vk->vkCmdPipelineBarrier( // 812 r->cmd, // 813 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // 814 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // 815 0, // 816 0, // 817 NULL, // 818 0, // 819 NULL, // 820 1, // 821 &memoryBarrier); // 822}