Skip to content

Commit 426d981

Browse files
authored
Merge pull request #248 from asuessenbach/17_swap_chain_creation
Correctly handle vk::Result::eOutOfDate from vk::raii::SwapchainKHR::acquireNextImage and vk::raii::Queue::presentKHR
2 parents 18261ad + 18233af commit 426d981

24 files changed

Lines changed: 516 additions & 603 deletions

attachments/17_swap_chain_recreation.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -513,17 +513,24 @@ class HelloTriangleApplication
513513

514514
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
515515

516+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
517+
// here and does not need to be caught by an exception.
516518
if (result == vk::Result::eErrorOutOfDateKHR)
517519
{
518520
recreateSwapChain();
519521
return;
520522
}
521-
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
523+
// On other success codes than eSuccess and eSuboptimalKHR we just throw an exception.
524+
// On any error code, aquireNextImage already threw an exception.
525+
else if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
522526
{
527+
assert(result == vk::Result::eTimeout || result == vk::Result::eNotReady);
523528
throw std::runtime_error("failed to acquire swap chain image!");
524529
}
525530

531+
// Only reset the fence if we are submitting work
526532
device.resetFences(*inFlightFences[frameIndex]);
533+
527534
commandBuffers[frameIndex].reset();
528535
recordCommandBuffer(imageIndex);
529536

@@ -537,35 +544,23 @@ class HelloTriangleApplication
537544
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
538545
queue.submit(submitInfo, *inFlightFences[frameIndex]);
539546

540-
try
547+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
548+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
549+
.swapchainCount = 1,
550+
.pSwapchains = &*swapChain,
551+
.pImageIndices = &imageIndex};
552+
result = queue.presentKHR(presentInfoKHR);
553+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
554+
// here and does not need to be caught by an exception.
555+
if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)
541556
{
542-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
543-
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
544-
.swapchainCount = 1,
545-
.pSwapchains = &*swapChain,
546-
.pImageIndices = &imageIndex};
547-
result = queue.presentKHR(presentInfoKHR);
548-
if (result == vk::Result::eSuboptimalKHR || framebufferResized)
549-
{
550-
framebufferResized = false;
551-
recreateSwapChain();
552-
}
553-
else if (result != vk::Result::eSuccess)
554-
{
555-
throw std::runtime_error("failed to present swap chain image!");
556-
}
557+
framebufferResized = false;
558+
recreateSwapChain();
557559
}
558-
catch (const vk::SystemError &e)
560+
else
559561
{
560-
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR))
561-
{
562-
recreateSwapChain();
563-
return;
564-
}
565-
else
566-
{
567-
throw;
568-
}
562+
// There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception.
563+
assert(result == vk::Result::eSuccess);
569564
}
570565
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
571566
}

attachments/18_vertex_input.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -532,17 +532,24 @@ class HelloTriangleApplication
532532

533533
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
534534

535+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
536+
// here and does not need to be caught by an exception.
535537
if (result == vk::Result::eErrorOutOfDateKHR)
536538
{
537539
recreateSwapChain();
538540
return;
539541
}
542+
// On other success codes than eSuccess and eSuboptimalKHR we just throw an exception.
543+
// On any error code, aquireNextImage already threw an exception.
540544
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
541545
{
546+
assert(result == vk::Result::eTimeout || result == vk::Result::eNotReady);
542547
throw std::runtime_error("failed to acquire swap chain image!");
543548
}
544549

550+
// Only reset the fence if we are submitting work
545551
device.resetFences(*inFlightFences[frameIndex]);
552+
546553
commandBuffers[frameIndex].reset();
547554
recordCommandBuffer(imageIndex);
548555

@@ -556,37 +563,25 @@ class HelloTriangleApplication
556563
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
557564
queue.submit(submitInfo, *inFlightFences[frameIndex]);
558565

559-
try
566+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
567+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
568+
.swapchainCount = 1,
569+
.pSwapchains = &*swapChain,
570+
.pImageIndices = &imageIndex};
571+
result = queue.presentKHR(presentInfoKHR);
572+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
573+
// here and does not need to be caught by an exception.
574+
if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)
560575
{
561-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
562-
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
563-
.swapchainCount = 1,
564-
.pSwapchains = &*swapChain,
565-
.pImageIndices = &imageIndex};
566-
result = queue.presentKHR(presentInfoKHR);
567-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized)
568-
{
569-
framebufferResized = false;
570-
recreateSwapChain();
571-
}
572-
else if (result != vk::Result::eSuccess)
573-
{
574-
throw std::runtime_error("failed to present swap chain image!");
575-
}
576+
framebufferResized = false;
577+
recreateSwapChain();
576578
}
577-
catch (const vk::SystemError &e)
579+
else
578580
{
579-
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR))
580-
{
581-
recreateSwapChain();
582-
return;
583-
}
584-
else
585-
{
586-
throw;
587-
}
581+
// There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception.
582+
assert(result == vk::Result::eSuccess);
588583
}
589-
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
584+
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
590585
}
591586

592587
[[nodiscard]] vk::raii::ShaderModule createShaderModule(const std::vector<char> &code) const

attachments/19_vertex_buffer.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -568,17 +568,24 @@ class HelloTriangleApplication
568568

569569
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
570570

571+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
572+
// here and does not need to be caught by an exception.
571573
if (result == vk::Result::eErrorOutOfDateKHR)
572574
{
573575
recreateSwapChain();
574576
return;
575577
}
578+
// On other success codes than eSuccess and eSuboptimalKHR we just throw an exception.
579+
// On any error code, aquireNextImage already threw an exception.
576580
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
577581
{
582+
assert(result == vk::Result::eTimeout || result == vk::Result::eNotReady);
578583
throw std::runtime_error("failed to acquire swap chain image!");
579584
}
580585

586+
// Only reset the fence if we are submitting work
581587
device.resetFences(*inFlightFences[frameIndex]);
588+
582589
commandBuffers[frameIndex].reset();
583590
recordCommandBuffer(imageIndex);
584591

@@ -592,35 +599,23 @@ class HelloTriangleApplication
592599
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
593600
queue.submit(submitInfo, *inFlightFences[frameIndex]);
594601

595-
try
602+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
603+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
604+
.swapchainCount = 1,
605+
.pSwapchains = &*swapChain,
606+
.pImageIndices = &imageIndex};
607+
result = queue.presentKHR(presentInfoKHR);
608+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
609+
// here and does not need to be caught by an exception.
610+
if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)
596611
{
597-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
598-
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
599-
.swapchainCount = 1,
600-
.pSwapchains = &*swapChain,
601-
.pImageIndices = &imageIndex};
602-
result = queue.presentKHR(presentInfoKHR);
603-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized)
604-
{
605-
framebufferResized = false;
606-
recreateSwapChain();
607-
}
608-
else if (result != vk::Result::eSuccess)
609-
{
610-
throw std::runtime_error("failed to present swap chain image!");
611-
}
612+
framebufferResized = false;
613+
recreateSwapChain();
612614
}
613-
catch (const vk::SystemError &e)
615+
else
614616
{
615-
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR))
616-
{
617-
recreateSwapChain();
618-
return;
619-
}
620-
else
621-
{
622-
throw;
623-
}
617+
// There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception.
618+
assert(result == vk::Result::eSuccess);
624619
}
625620
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
626621
}

attachments/20_staging_buffer.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -588,17 +588,24 @@ class HelloTriangleApplication
588588

589589
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
590590

591+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
592+
// here and does not need to be caught by an exception.
591593
if (result == vk::Result::eErrorOutOfDateKHR)
592594
{
593595
recreateSwapChain();
594596
return;
595597
}
598+
// On other success codes than eSuccess and eSuboptimalKHR we just throw an exception.
599+
// On any error code, aquireNextImage already threw an exception.
596600
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
597601
{
602+
assert(result == vk::Result::eTimeout || result == vk::Result::eNotReady);
598603
throw std::runtime_error("failed to acquire swap chain image!");
599604
}
600605

606+
// Only reset the fence if we are submitting work
601607
device.resetFences(*inFlightFences[frameIndex]);
608+
602609
commandBuffers[frameIndex].reset();
603610
recordCommandBuffer(imageIndex);
604611

@@ -612,35 +619,23 @@ class HelloTriangleApplication
612619
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
613620
queue.submit(submitInfo, *inFlightFences[frameIndex]);
614621

615-
try
622+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
623+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
624+
.swapchainCount = 1,
625+
.pSwapchains = &*swapChain,
626+
.pImageIndices = &imageIndex};
627+
result = queue.presentKHR(presentInfoKHR);
628+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
629+
// here and does not need to be caught by an exception.
630+
if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)
616631
{
617-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
618-
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
619-
.swapchainCount = 1,
620-
.pSwapchains = &*swapChain,
621-
.pImageIndices = &imageIndex};
622-
result = queue.presentKHR(presentInfoKHR);
623-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized)
624-
{
625-
framebufferResized = false;
626-
recreateSwapChain();
627-
}
628-
else if (result != vk::Result::eSuccess)
629-
{
630-
throw std::runtime_error("failed to present swap chain image!");
631-
}
632+
framebufferResized = false;
633+
recreateSwapChain();
632634
}
633-
catch (const vk::SystemError &e)
635+
else
634636
{
635-
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR))
636-
{
637-
recreateSwapChain();
638-
return;
639-
}
640-
else
641-
{
642-
throw;
643-
}
637+
// There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception.
638+
assert(result == vk::Result::eSuccess);
644639
}
645640
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
646641
}

attachments/21_index_buffer.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -614,17 +614,24 @@ class HelloTriangleApplication
614614

615615
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
616616

617+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
618+
// here and does not need to be caught by an exception.
617619
if (result == vk::Result::eErrorOutOfDateKHR)
618620
{
619621
recreateSwapChain();
620622
return;
621623
}
624+
// On other success codes than eSuccess and eSuboptimalKHR we just throw an exception.
625+
// On any error code, aquireNextImage already threw an exception.
622626
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR)
623627
{
628+
assert(result == vk::Result::eTimeout || result == vk::Result::eNotReady);
624629
throw std::runtime_error("failed to acquire swap chain image!");
625630
}
626631

632+
// Only reset the fence if we are submitting work
627633
device.resetFences(*inFlightFences[frameIndex]);
634+
628635
commandBuffers[frameIndex].reset();
629636
recordCommandBuffer(imageIndex);
630637

@@ -638,35 +645,23 @@ class HelloTriangleApplication
638645
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
639646
queue.submit(submitInfo, *inFlightFences[frameIndex]);
640647

641-
try
648+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
649+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
650+
.swapchainCount = 1,
651+
.pSwapchains = &*swapChain,
652+
.pImageIndices = &imageIndex};
653+
result = queue.presentKHR(presentInfoKHR);
654+
// Due to VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS being defined, eErrorOutOfDateKHR can be checked as a result
655+
// here and does not need to be caught by an exception.
656+
if ((result == vk::Result::eSuboptimalKHR) || (result == vk::Result::eErrorOutOfDateKHR) || framebufferResized)
642657
{
643-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
644-
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
645-
.swapchainCount = 1,
646-
.pSwapchains = &*swapChain,
647-
.pImageIndices = &imageIndex};
648-
result = queue.presentKHR(presentInfoKHR);
649-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized)
650-
{
651-
framebufferResized = false;
652-
recreateSwapChain();
653-
}
654-
else if (result != vk::Result::eSuccess)
655-
{
656-
throw std::runtime_error("failed to present swap chain image!");
657-
}
658+
framebufferResized = false;
659+
recreateSwapChain();
658660
}
659-
catch (const vk::SystemError &e)
661+
else
660662
{
661-
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR))
662-
{
663-
recreateSwapChain();
664-
return;
665-
}
666-
else
667-
{
668-
throw;
669-
}
663+
// There are no other success codes than eSuccess; on any error code, presentKHR already threw an exception.
664+
assert(result == vk::Result::eSuccess);
670665
}
671666
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
672667
}

0 commit comments

Comments
 (0)