| 543 | } |
| 544 | |
| 545 | void ApiVulkanSample::submit_frame() |
| 546 | { |
| 547 | if (get_render_context().has_swapchain()) |
| 548 | { |
| 549 | const auto &queue = get_device().get_queue_by_present(0); |
| 550 | |
| 551 | VkSwapchainKHR sc = get_render_context().get_swapchain().get_handle(); |
| 552 | |
| 553 | VkPresentInfoKHR present_info = {}; |
| 554 | present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; |
| 555 | present_info.pNext = NULL; |
| 556 | present_info.swapchainCount = 1; |
| 557 | present_info.pSwapchains = ≻ |
| 558 | present_info.pImageIndices = ¤t_buffer; |
| 559 | |
| 560 | VkDisplayPresentInfoKHR disp_present_info{}; |
| 561 | if (get_device().get_gpu().is_extension_supported(VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) && |
| 562 | window->get_display_present_info(&disp_present_info, width, height)) |
| 563 | { |
| 564 | // Add display present info if supported and wanted |
| 565 | present_info.pNext = &disp_present_info; |
| 566 | } |
| 567 | |
| 568 | // Check if a wait semaphore has been specified to wait for before presenting the image |
| 569 | if (semaphores.render_complete != VK_NULL_HANDLE) |
| 570 | { |
| 571 | present_info.pWaitSemaphores = &semaphores.render_complete; |
| 572 | present_info.waitSemaphoreCount = 1; |
| 573 | } |
| 574 | |
| 575 | VkResult present_result = queue.present(present_info); |
| 576 | |
| 577 | if (!((present_result == VK_SUCCESS) || (present_result == VK_SUBOPTIMAL_KHR))) |
| 578 | { |
| 579 | if (present_result == VK_ERROR_OUT_OF_DATE_KHR) |
| 580 | { |
| 581 | // Swap chain is no longer compatible with the surface and needs to be recreated |
| 582 | resize(width, height); |
| 583 | return; |
| 584 | } |
| 585 | else |
| 586 | { |
| 587 | VK_CHECK(present_result); |
| 588 | } |
| 589 | } |
| 590 | } |
| 591 | |
| 592 | // DO NOT USE |
| 593 | // vkDeviceWaitIdle and vkQueueWaitIdle are extremely expensive functions, and are used here purely for demonstrating the vulkan API |
| 594 | // without having to concern ourselves with proper syncronization. These functions should NEVER be used inside the render loop like this (every frame). |
| 595 | VK_CHECK(get_device().get_queue_by_present(0).wait_idle()); |
| 596 | } |
| 597 | |
| 598 | ApiVulkanSample::~ApiVulkanSample() |
| 599 | { |
nothing calls this directly
no test coverage detected