フレーム・イン・フライト
テクニカル諏訪子 <suwako@076.moe>、2026-07-21 13:59
コミット eb2c9ba2c636f2344fc3ecdb50268eef124cf04b
・親 6b7ea3f
・ファイルを見る
1個のファイル、+32 -18
| @@ -16,6 +16,9 @@ | ||
| 16 | 16 | #include <util/root.hh> |
| 17 | 17 | VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE |
| 18 | 18 | |
| 19 | +constexpr int MAX_FRAMES_IN_FLIGHT = 2; | |
| 20 | +uint32_t frameIdx = 0; | |
| 21 | + | |
| 19 | 22 | std::vector<vk::Image> swapChainImages; |
| 20 | 23 | vk::CommandBuffer cmdBuf; |
| 21 | 24 | vk::CommandBufferBeginInfo beginInfo; |
| @@ -526,7 +529,7 @@ | ||
| 526 | 529 | vk::CommandBufferAllocateInfo allocInfo = {}; |
| 527 | 530 | allocInfo.commandPool = cmdPool; |
| 528 | 531 | allocInfo.level = vk::CommandBufferLevel::ePrimary; |
| 529 | - allocInfo.commandBufferCount = 1; | |
| 532 | + allocInfo.commandBufferCount = MAX_FRAMES_IN_FLIGHT; | |
| 530 | 533 | |
| 531 | 534 | std::vector<vk::CommandBuffer> cmdBufs = device.allocateCommandBuffers(allocInfo); |
| 532 | 535 | cmdBuf = cmdBufs.front(); |
| @@ -538,13 +541,22 @@ | ||
| 538 | 541 | #pragma endregion |
| 539 | 542 | |
| 540 | 543 | #pragma region syncObjects |
| 541 | - vk::Semaphore presentCompleteSemaphore = device.createSemaphore(vk::SemaphoreCreateInfo()); | |
| 542 | - vk::Semaphore renderFinishedSemaphore = device.createSemaphore(vk::SemaphoreCreateInfo()); | |
| 544 | + std::vector<vk::Semaphore> presentCompleteSemaphores; | |
| 545 | + std::vector<vk::Semaphore> renderFinishedSemaphores; | |
| 546 | + std::vector<vk::Fence> inFlightFences; | |
| 547 | + assert(presentCompleteSemaphores.empty() && renderFinishedSemaphores.empty() && inFlightFences.empty()); | |
| 543 | 548 | |
| 544 | - vk::FenceCreateInfo fenceInfo = {}; | |
| 545 | - fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled; | |
| 549 | + for (size_t i = 0; i < swapChainImages.size(); ++i) { | |
| 550 | + renderFinishedSemaphores.emplace_back(device.createSemaphore(vk::SemaphoreCreateInfo())); | |
| 551 | + } | |
| 546 | 552 | |
| 547 | - vk::Fence drawFence = device.createFence(fenceInfo); | |
| 553 | + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { | |
| 554 | + presentCompleteSemaphores.emplace_back(device.createSemaphore(vk::SemaphoreCreateInfo())); | |
| 555 | + | |
| 556 | + vk::FenceCreateInfo fenceInfo = {}; | |
| 557 | + fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled; | |
| 558 | + inFlightFences.emplace_back(device.createFence(fenceInfo)); | |
| 559 | + } | |
| 548 | 560 | #pragma endregion |
| 549 | 561 | |
| 550 | 562 | #pragma region framesInFlight |
| @@ -552,7 +564,7 @@ | ||
| 552 | 564 | |
| 553 | 565 | #pragma region swapChainRecreate |
| 554 | 566 | #pragma endregion |
| 555 | - | |
| 567 | + | |
| 556 | 568 | while (!glfwWindowShouldClose(window)) { |
| 557 | 569 | if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) { |
| 558 | 570 | glfwSetWindowShouldClose(window, true); |
| @@ -561,15 +573,15 @@ | ||
| 561 | 573 | glfwPollEvents(); |
| 562 | 574 | |
| 563 | 575 | #pragma region drawFrame |
| 564 | - auto fenceResult = device.waitForFences(drawFence, vk::True, UINT64_MAX); | |
| 576 | + auto fenceResult = device.waitForFences(inFlightFences[frameIdx], vk::True, UINT64_MAX); | |
| 565 | 577 | if (fenceResult != vk::Result::eSuccess) { |
| 566 | 578 | assert(false && "フェンスまで待つに失敗。"); |
| 567 | 579 | break; |
| 568 | 580 | } |
| 569 | 581 | |
| 570 | - device.resetFences(drawFence); | |
| 571 | - auto [acquireRes, imgIdx] = device.acquireNextImageKHR(swapChain, UINT64_MAX, presentCompleteSemaphore, nullptr); | |
| 572 | - | |
| 582 | + device.resetFences(inFlightFences[frameIdx]); | |
| 583 | + auto [acquireRes, imgIdx] = device.acquireNextImageKHR(swapChain, UINT64_MAX, presentCompleteSemaphores[frameIdx], nullptr); | |
| 584 | + | |
| 573 | 585 | if (acquireRes == vk::Result::eErrorOutOfDateKHR || acquireRes == vk::Result::eSuboptimalKHR) continue; |
| 574 | 586 | if (acquireRes != vk::Result::eSuccess) { |
| 575 | 587 | assert(false && "次の画像の受け取りに失敗。"); |
| @@ -582,14 +594,14 @@ | ||
| 582 | 594 | |
| 583 | 595 | vk::SubmitInfo submitInfo = {}; |
| 584 | 596 | submitInfo.waitSemaphoreCount = 1; |
| 585 | - submitInfo.pWaitSemaphores = &presentCompleteSemaphore; | |
| 597 | + submitInfo.pWaitSemaphores = &presentCompleteSemaphores[frameIdx]; | |
| 586 | 598 | submitInfo.pWaitDstStageMask = &waitStage; |
| 587 | 599 | submitInfo.commandBufferCount = 1; |
| 588 | 600 | submitInfo.pCommandBuffers = &cmdBuf; |
| 589 | 601 | submitInfo.signalSemaphoreCount = 1; |
| 590 | - submitInfo.pSignalSemaphores = &renderFinishedSemaphore; | |
| 602 | + submitInfo.pSignalSemaphores = &renderFinishedSemaphores[frameIdx]; | |
| 591 | 603 | |
| 592 | - gfxQueue.submit(submitInfo, drawFence); | |
| 604 | + gfxQueue.submit(submitInfo, inFlightFences[frameIdx]); | |
| 593 | 605 | |
| 594 | 606 | vk::SubpassDependency depend = {}; |
| 595 | 607 | depend.srcSubpass = vk::SubpassExternal; |
| @@ -601,12 +613,14 @@ | ||
| 601 | 613 | |
| 602 | 614 | vk::PresentInfoKHR presentInfo = {}; |
| 603 | 615 | presentInfo.waitSemaphoreCount = 1; |
| 604 | - presentInfo.pWaitSemaphores = &renderFinishedSemaphore; | |
| 616 | + presentInfo.pWaitSemaphores = &renderFinishedSemaphores[frameIdx]; | |
| 605 | 617 | presentInfo.swapchainCount = 1; |
| 606 | 618 | presentInfo.pSwapchains = &swapChain; |
| 607 | 619 | presentInfo.pImageIndices = &imgIdx; |
| 608 | 620 | |
| 609 | 621 | vk::Result presentRes = gfxQueue.presentKHR(presentInfo); |
| 622 | + | |
| 623 | + frameIdx = (frameIdx + 1) % MAX_FRAMES_IN_FLIGHT; | |
| 610 | 624 | #pragma endregion |
| 611 | 625 | |
| 612 | 626 | device.waitIdle(); |
| @@ -623,9 +637,9 @@ | ||
| 623 | 637 | swapChainImageViews.clear(); |
| 624 | 638 | |
| 625 | 639 | if (swapChain) device.destroySwapchainKHR(swapChain); |
| 626 | - if (presentCompleteSemaphore) device.destroySemaphore(presentCompleteSemaphore); | |
| 627 | - if (renderFinishedSemaphore) device.destroySemaphore(renderFinishedSemaphore); | |
| 628 | - if (drawFence) device.destroyFence(drawFence); | |
| 640 | + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) device.destroySemaphore(presentCompleteSemaphores[i]); | |
| 641 | + for (size_t i = 0; i < swapChainImages.size(); ++i) device.destroySemaphore(renderFinishedSemaphores[i]); | |
| 642 | + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) device.destroyFence(inFlightFences[i]); | |
| 629 | 643 | if (device) device.destroy(); |
| 630 | 644 | #ifndef NDEBUG |
| 631 | 645 | if (debugMessenger) instance.destroyDebugUtilsMessengerEXT(debugMessenger); |