Skip to content

Commit 70c62f0

Browse files
authored
Merge pull request #219 from asuessenbach/16_frames_in_flight
Fix vector size for presentCompleteSemaphores.
2 parents d4b75b3 + 8029949 commit 70c62f0

40 files changed

+989
-814
lines changed

attachments/15_hello_triangle.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ class HelloTriangleApplication
417417
}
418418

419419
void transition_image_layout(
420-
uint32_t currentFrame,
420+
uint32_t imageIndex,
421421
vk::ImageLayout old_layout,
422422
vk::ImageLayout new_layout,
423423
vk::AccessFlags2 src_access_mask,
@@ -434,7 +434,7 @@ class HelloTriangleApplication
434434
.newLayout = new_layout,
435435
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
436436
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
437-
.image = swapChainImages[currentFrame],
437+
.image = swapChainImages[imageIndex],
438438
.subresourceRange = {
439439
.aspectMask = vk::ImageAspectFlagBits::eColor,
440440
.baseMipLevel = 0,

attachments/16_frames_in_flight.cpp

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ class HelloTriangleApplication
6464
vk::raii::CommandPool commandPool = nullptr;
6565
std::vector<vk::raii::CommandBuffer> commandBuffers;
6666

67-
std::vector<vk::raii::Semaphore> presentCompleteSemaphore;
68-
std::vector<vk::raii::Semaphore> renderFinishedSemaphore;
67+
std::vector<vk::raii::Semaphore> presentCompleteSemaphores;
68+
std::vector<vk::raii::Semaphore> renderFinishedSemaphores;
6969
std::vector<vk::raii::Fence> inFlightFences;
70-
uint32_t semaphoreIndex = 0;
71-
uint32_t currentFrame = 0;
70+
uint32_t frameIndex = 0;
7271

7372
std::vector<const char *> requiredDeviceExtension = {
7473
vk::KHRSwapchainExtensionName,
@@ -377,7 +376,8 @@ class HelloTriangleApplication
377376

378377
void recordCommandBuffer(uint32_t imageIndex)
379378
{
380-
commandBuffers[currentFrame].begin({});
379+
auto &commandBuffer = commandBuffers[frameIndex];
380+
commandBuffer.begin({});
381381
// Before starting rendering, transition the swapchain image to COLOR_ATTACHMENT_OPTIMAL
382382
transition_image_layout(
383383
imageIndex,
@@ -400,12 +400,12 @@ class HelloTriangleApplication
400400
.layerCount = 1,
401401
.colorAttachmentCount = 1,
402402
.pColorAttachments = &attachmentInfo};
403-
commandBuffers[currentFrame].beginRendering(renderingInfo);
404-
commandBuffers[currentFrame].bindPipeline(vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
405-
commandBuffers[currentFrame].setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(swapChainExtent.width), static_cast<float>(swapChainExtent.height), 0.0f, 1.0f));
406-
commandBuffers[currentFrame].setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
407-
commandBuffers[currentFrame].draw(3, 1, 0, 0);
408-
commandBuffers[currentFrame].endRendering();
403+
commandBuffer.beginRendering(renderingInfo);
404+
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
405+
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(swapChainExtent.width), static_cast<float>(swapChainExtent.height), 0.0f, 1.0f));
406+
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
407+
commandBuffer.draw(3, 1, 0, 0);
408+
commandBuffer.endRendering();
409409
// After rendering, transition the swapchain image to PRESENT_SRC
410410
transition_image_layout(
411411
imageIndex,
@@ -416,7 +416,7 @@ class HelloTriangleApplication
416416
vk::PipelineStageFlagBits2::eColorAttachmentOutput, // srcStage
417417
vk::PipelineStageFlagBits2::eBottomOfPipe // dstStage
418418
);
419-
commandBuffers[currentFrame].end();
419+
commandBuffer.end();
420420
}
421421

422422
void transition_image_layout(
@@ -448,42 +448,53 @@ class HelloTriangleApplication
448448
.dependencyFlags = {},
449449
.imageMemoryBarrierCount = 1,
450450
.pImageMemoryBarriers = &barrier};
451-
commandBuffers[currentFrame].pipelineBarrier2(dependency_info);
451+
commandBuffers[frameIndex].pipelineBarrier2(dependency_info);
452452
}
453453

454454
void createSyncObjects()
455455
{
456-
presentCompleteSemaphore.clear();
457-
renderFinishedSemaphore.clear();
458-
inFlightFences.clear();
456+
assert(presentCompleteSemaphores.empty() && renderFinishedSemaphores.empty() && inFlightFences.empty());
459457

460458
for (size_t i = 0; i < swapChainImages.size(); i++)
461459
{
462-
presentCompleteSemaphore.emplace_back(device, vk::SemaphoreCreateInfo());
463-
renderFinishedSemaphore.emplace_back(device, vk::SemaphoreCreateInfo());
460+
renderFinishedSemaphores.emplace_back(device, vk::SemaphoreCreateInfo());
464461
}
465462

466463
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
467464
{
465+
presentCompleteSemaphores.emplace_back(device, vk::SemaphoreCreateInfo());
468466
inFlightFences.emplace_back(device, vk::FenceCreateInfo{.flags = vk::FenceCreateFlagBits::eSignaled});
469467
}
470468
}
471469

472470
void drawFrame()
473471
{
474-
while (vk::Result::eTimeout == device.waitForFences(*inFlightFences[currentFrame], vk::True, UINT64_MAX))
472+
// Note: inFlightFences, presentCompleteSemaphores, and commandBuffers are indexed by frameIndex,
473+
// while renderFinishedSemaphores is indexed by imageIndex
474+
while (vk::Result::eTimeout == device.waitForFences(*inFlightFences[frameIndex], vk::True, UINT64_MAX))
475475
;
476-
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphore[semaphoreIndex], nullptr);
476+
device.resetFences(*inFlightFences[frameIndex]);
477477

478-
device.resetFences(*inFlightFences[currentFrame]);
479-
commandBuffers[currentFrame].reset();
478+
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
479+
480+
commandBuffers[frameIndex].reset();
480481
recordCommandBuffer(imageIndex);
481482

482483
vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
483-
const vk::SubmitInfo submitInfo{.waitSemaphoreCount = 1, .pWaitSemaphores = &*presentCompleteSemaphore[semaphoreIndex], .pWaitDstStageMask = &waitDestinationStageMask, .commandBufferCount = 1, .pCommandBuffers = &*commandBuffers[currentFrame], .signalSemaphoreCount = 1, .pSignalSemaphores = &*renderFinishedSemaphore[imageIndex]};
484-
queue.submit(submitInfo, *inFlightFences[currentFrame]);
485-
486-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex], .swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex};
484+
const vk::SubmitInfo submitInfo{.waitSemaphoreCount = 1,
485+
.pWaitSemaphores = &*presentCompleteSemaphores[frameIndex],
486+
.pWaitDstStageMask = &waitDestinationStageMask,
487+
.commandBufferCount = 1,
488+
.pCommandBuffers = &*commandBuffers[frameIndex],
489+
.signalSemaphoreCount = 1,
490+
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
491+
queue.submit(submitInfo, *inFlightFences[frameIndex]);
492+
493+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
494+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
495+
.swapchainCount = 1,
496+
.pSwapchains = &*swapChain,
497+
.pImageIndices = &imageIndex};
487498
result = queue.presentKHR(presentInfoKHR);
488499
switch (result)
489500
{
@@ -495,8 +506,7 @@ class HelloTriangleApplication
495506
default:
496507
break; // an unexpected result is returned!
497508
}
498-
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
499-
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
509+
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
500510
}
501511

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

attachments/17_swap_chain_recreation.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ class HelloTriangleApplication
6464
vk::raii::CommandPool commandPool = nullptr;
6565
std::vector<vk::raii::CommandBuffer> commandBuffers;
6666

67-
std::vector<vk::raii::Semaphore> presentCompleteSemaphore;
68-
std::vector<vk::raii::Semaphore> renderFinishedSemaphore;
67+
std::vector<vk::raii::Semaphore> presentCompleteSemaphores;
68+
std::vector<vk::raii::Semaphore> renderFinishedSemaphores;
6969
std::vector<vk::raii::Fence> inFlightFences;
70-
uint32_t semaphoreIndex = 0;
71-
uint32_t currentFrame = 0;
70+
uint32_t frameIndex = 0;
7271

7372
bool framebufferResized = false;
7473

@@ -411,7 +410,8 @@ class HelloTriangleApplication
411410

412411
void recordCommandBuffer(uint32_t imageIndex)
413412
{
414-
commandBuffers[currentFrame].begin({});
413+
auto &commandBuffer = commandBuffers[frameIndex];
414+
commandBuffer.begin({});
415415
// Before starting rendering, transition the swapchain image to COLOR_ATTACHMENT_OPTIMAL
416416
transition_image_layout(
417417
imageIndex,
@@ -434,12 +434,12 @@ class HelloTriangleApplication
434434
.layerCount = 1,
435435
.colorAttachmentCount = 1,
436436
.pColorAttachments = &attachmentInfo};
437-
commandBuffers[currentFrame].beginRendering(renderingInfo);
438-
commandBuffers[currentFrame].bindPipeline(vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
439-
commandBuffers[currentFrame].setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(swapChainExtent.width), static_cast<float>(swapChainExtent.height), 0.0f, 1.0f));
440-
commandBuffers[currentFrame].setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
441-
commandBuffers[currentFrame].draw(3, 1, 0, 0);
442-
commandBuffers[currentFrame].endRendering();
437+
commandBuffer.beginRendering(renderingInfo);
438+
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
439+
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(swapChainExtent.width), static_cast<float>(swapChainExtent.height), 0.0f, 1.0f));
440+
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
441+
commandBuffer.draw(3, 1, 0, 0);
442+
commandBuffer.endRendering();
443443
// After rendering, transition the swapchain image to PRESENT_SRC
444444
transition_image_layout(
445445
imageIndex,
@@ -450,7 +450,7 @@ class HelloTriangleApplication
450450
vk::PipelineStageFlagBits2::eColorAttachmentOutput, // srcStage
451451
vk::PipelineStageFlagBits2::eBottomOfPipe // dstStage
452452
);
453-
commandBuffers[currentFrame].end();
453+
commandBuffer.end();
454454
}
455455

456456
void transition_image_layout(
@@ -482,32 +482,34 @@ class HelloTriangleApplication
482482
.dependencyFlags = {},
483483
.imageMemoryBarrierCount = 1,
484484
.pImageMemoryBarriers = &barrier};
485-
commandBuffers[currentFrame].pipelineBarrier2(dependency_info);
485+
commandBuffers[frameIndex].pipelineBarrier2(dependency_info);
486486
}
487487

488488
void createSyncObjects()
489489
{
490-
presentCompleteSemaphore.clear();
491-
renderFinishedSemaphore.clear();
492-
inFlightFences.clear();
490+
assert(presentCompleteSemaphores.empty() && renderFinishedSemaphores.empty() && inFlightFences.empty());
493491

494492
for (size_t i = 0; i < swapChainImages.size(); i++)
495493
{
496-
presentCompleteSemaphore.emplace_back(device, vk::SemaphoreCreateInfo());
497-
renderFinishedSemaphore.emplace_back(device, vk::SemaphoreCreateInfo());
494+
renderFinishedSemaphores.emplace_back(device, vk::SemaphoreCreateInfo());
498495
}
499496

500497
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
501498
{
499+
presentCompleteSemaphores.emplace_back(device, vk::SemaphoreCreateInfo());
502500
inFlightFences.emplace_back(device, vk::FenceCreateInfo{.flags = vk::FenceCreateFlagBits::eSignaled});
503501
}
504502
}
505503

506504
void drawFrame()
507505
{
508-
while (vk::Result::eTimeout == device.waitForFences(*inFlightFences[currentFrame], vk::True, UINT64_MAX))
506+
// Note: inFlightFences, presentCompleteSemaphores, and commandBuffers are indexed by frameIndex,
507+
// while renderFinishedSemaphores is indexed by imageIndex
508+
while (vk::Result::eTimeout == device.waitForFences(*inFlightFences[frameIndex], vk::True, UINT64_MAX))
509509
;
510-
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphore[semaphoreIndex], nullptr);
510+
device.resetFences(*inFlightFences[frameIndex]);
511+
512+
auto [result, imageIndex] = swapChain.acquireNextImage(UINT64_MAX, *presentCompleteSemaphores[frameIndex], nullptr);
511513

512514
if (result == vk::Result::eErrorOutOfDateKHR)
513515
{
@@ -519,19 +521,29 @@ class HelloTriangleApplication
519521
throw std::runtime_error("failed to acquire swap chain image!");
520522
}
521523

522-
device.resetFences(*inFlightFences[currentFrame]);
523-
commandBuffers[currentFrame].reset();
524+
device.resetFences(*inFlightFences[frameIndex]);
525+
commandBuffers[frameIndex].reset();
524526
recordCommandBuffer(imageIndex);
525527

526528
vk::PipelineStageFlags waitDestinationStageMask(vk::PipelineStageFlagBits::eColorAttachmentOutput);
527-
const vk::SubmitInfo submitInfo{.waitSemaphoreCount = 1, .pWaitSemaphores = &*presentCompleteSemaphore[semaphoreIndex], .pWaitDstStageMask = &waitDestinationStageMask, .commandBufferCount = 1, .pCommandBuffers = &*commandBuffers[currentFrame], .signalSemaphoreCount = 1, .pSignalSemaphores = &*renderFinishedSemaphore[imageIndex]};
528-
queue.submit(submitInfo, *inFlightFences[currentFrame]);
529+
const vk::SubmitInfo submitInfo{.waitSemaphoreCount = 1,
530+
.pWaitSemaphores = &*presentCompleteSemaphores[frameIndex],
531+
.pWaitDstStageMask = &waitDestinationStageMask,
532+
.commandBufferCount = 1,
533+
.pCommandBuffers = &*commandBuffers[frameIndex],
534+
.signalSemaphoreCount = 1,
535+
.pSignalSemaphores = &*renderFinishedSemaphores[imageIndex]};
536+
queue.submit(submitInfo, *inFlightFences[frameIndex]);
529537

530538
try
531539
{
532-
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex], .swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex};
540+
const vk::PresentInfoKHR presentInfoKHR{.waitSemaphoreCount = 1,
541+
.pWaitSemaphores = &*renderFinishedSemaphores[imageIndex],
542+
.swapchainCount = 1,
543+
.pSwapchains = &*swapChain,
544+
.pImageIndices = &imageIndex};
533545
result = queue.presentKHR(presentInfoKHR);
534-
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized)
546+
if (result == vk::Result::eSuboptimalKHR || framebufferResized)
535547
{
536548
framebufferResized = false;
537549
recreateSwapChain();
@@ -553,8 +565,7 @@ class HelloTriangleApplication
553565
throw;
554566
}
555567
}
556-
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
557-
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
568+
frameIndex = (frameIndex + 1) % MAX_FRAMES_IN_FLIGHT;
558569
}
559570

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

0 commit comments

Comments
 (0)