diff --git a/include/iwa/swapchain.hpp b/include/iwa/swapchain.hpp index 7a1a1c2..690f094 100644 --- a/include/iwa/swapchain.hpp +++ b/include/iwa/swapchain.hpp @@ -34,6 +34,7 @@ private: std::uint32_t mCurrentImageIdx = INVALID_IMAGE_INDEX; unsigned mCurrentFrameIdx = 0; + unsigned mCurrentSemaphoreIdx = 0; ObjectPtr mWindow; std::vector> mImages; std::vector> mImageAvailableSemaphores; @@ -45,8 +46,8 @@ public: ~Swapchain() noexcept override; [[nodiscard]] const ObjectPtr& getWindow() const noexcept { return mWindow; } - [[nodiscard]] std::size_t getNumParallelFrames() const noexcept { return mImageAvailableSemaphores.size(); } - [[nodiscard]] const ObjectPtr& getCurrentAvailableSemaphore() const noexcept { return mImageAvailableSemaphores[mCurrentFrameIdx]; } + [[nodiscard]] std::size_t getNumParallelFrames() const noexcept { return mImageAvailableSemaphores.size() - 1; } + [[nodiscard]] const ObjectPtr& getCurrentAvailableSemaphore() const noexcept { return mImageAvailableSemaphores[mCurrentSemaphoreIdx]; } [[nodiscard]] unsigned getCurrentFrameIdx() const noexcept { return mCurrentFrameIdx; } [[nodiscard]] const std::vector>& getImages() const noexcept { return mImages; } [[nodiscard]] std::uint32_t getCurrentImageIdx() const noexcept { return mCurrentImageIdx; } diff --git a/source/swapchain.cpp b/source/swapchain.cpp index 79afe4b..f9f9bce 100644 --- a/source/swapchain.cpp +++ b/source/swapchain.cpp @@ -97,8 +97,9 @@ Swapchain::Swapchain(ObjectPtr owner, SwapchainCreationArgs args) : super_t(std::move(owner)), mWindow(std::move(args.window)), mImageUsage(args.imageUsage) { MIJIN_ASSERT(mWindow, "Invalid SwapchainCreationArgs: window cannot be NULL."); + MIJIN_ASSERT_FATAL(args.parallelFrames > 0, "Invalid SwapchainCreationArgs: parallelFrames must be > 0."); - mImageAvailableSemaphores.resize(args.parallelFrames); + mImageAvailableSemaphores.resize(args.parallelFrames - 1); recreate(); } Swapchain::~Swapchain() noexcept @@ -131,6 +132,8 @@ mijin::Task<> Swapchain::c_present(const PresentArgs& args) // next image, please mCurrentFrameIdx = (mCurrentFrameIdx + 1) % static_cast(getNumParallelFrames()); + mCurrentSemaphoreIdx = (mCurrentSemaphoreIdx + 1) % static_cast(mImageAvailableSemaphores.size()); + // logMsg("frame: {}, semaphore: {}", mCurrentFrameIdx, mCurrentSemaphoreIdx); if (result == vk::Result::eSuccess) { co_await c_acquireImage(); } @@ -280,7 +283,7 @@ void Swapchain::acquireImage() try { - const vk::ResultValue result = getOwner()->getVkHandle().acquireNextImageKHR(mHandle, std::numeric_limits::max(), *mImageAvailableSemaphores[mCurrentFrameIdx]); + const vk::ResultValue result = getOwner()->getVkHandle().acquireNextImageKHR(mHandle, std::numeric_limits::max(), *getCurrentAvailableSemaphore()); if (result.result != vk::Result::eSuccess) { assert(result.result == vk::Result::eSuboptimalKHR); @@ -302,7 +305,7 @@ mijin::Task<> Swapchain::c_acquireImage() vk::ResultValue result = vk::ResultValue(vk::Result::eTimeout, 0); while(true) { - result = getOwner()->getVkHandle().acquireNextImageKHR(mHandle, 0, *mImageAvailableSemaphores[mCurrentFrameIdx]); + result = getOwner()->getVkHandle().acquireNextImageKHR(mHandle, 0, *getCurrentAvailableSemaphore()); if (result.result != vk::Result::eTimeout && result.result != vk::Result::eNotReady) { break; }