diff --git a/VulkanTest b/VulkanTest index 90983d9..e8c3f5a 100755 Binary files a/VulkanTest and b/VulkanTest differ diff --git a/hk_renderer.cpp b/hk_renderer.cpp index bd393dc..2ef2e2a 100644 --- a/hk_renderer.cpp +++ b/hk_renderer.cpp @@ -7,7 +7,7 @@ namespace hk { - Renderer::Renderer(Window &window, Device &device) : m_window{window}, m_device{device} + Renderer::Renderer(Window &window, Device &device) : m_window{window}, m_device{device}, m_currentFrameIndex{0}, m_isFrameStarted{false} { recreateSwapChain(); createCommandBuffers(); @@ -45,8 +45,9 @@ namespace hk throw std::runtime_error("Swap chain image(or depth) format has changed!"); } } - - // TODO: we'll come back to this in just a moment + + // Reset currentFrameIndex when recreating swapchain + m_currentFrameIndex = 0; } @@ -120,8 +121,7 @@ namespace hk m_window.resetWindowResizedFlag(); recreateSwapChain(); } - - if (result != VK_SUCCESS) + else if (result != VK_SUCCESS) { throw std::runtime_error("failed to present swap chain image!"); } diff --git a/hk_swap_chain.cpp b/hk_swap_chain.cpp index 50ba3cd..01d7e19 100644 --- a/hk_swap_chain.cpp +++ b/hk_swap_chain.cpp @@ -21,6 +21,8 @@ namespace hk : device{deviceRef}, windowExtent{extent}, oldSwapChain{previous} { init(); + // Reset currentFrame to 0 when creating a new swap chain + currentFrame = 0; // clean up old swap chain oldSwapChain = nullptr; @@ -65,10 +67,13 @@ namespace hk vkDestroyRenderPass(device.device(), renderPass, nullptr); // cleanup synchronization objects - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + for (size_t i = 0; i < imageAvailableSemaphores.size(); i++) { vkDestroySemaphore(device.device(), renderFinishedSemaphores[i], nullptr); vkDestroySemaphore(device.device(), imageAvailableSemaphores[i], nullptr); + } + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + { vkDestroyFence(device.device(), inFlightFences[i], nullptr); } } @@ -82,11 +87,12 @@ namespace hk VK_TRUE, std::numeric_limits::max()); + // Acquire with a temporary semaphore, we'll use the imageIndex-specific one later VkResult result = vkAcquireNextImageKHR( device.device(), swapChain, std::numeric_limits::max(), - imageAvailableSemaphores[currentFrame], // must be a not signaled semaphore + imageAvailableSemaphores[currentFrame % imageAvailableSemaphores.size()], VK_NULL_HANDLE, imageIndex); @@ -105,7 +111,8 @@ namespace hk VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]}; + // Use the semaphore associated with the currentFrame for waiting (from acquireNextImage) + VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame % imageAvailableSemaphores.size()]}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; @@ -114,7 +121,8 @@ namespace hk submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = buffers; - VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]}; + // Use the semaphore associated with this specific image for signaling + VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[*imageIndex]}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; @@ -380,8 +388,9 @@ namespace hk void SwapChain::createSyncObjects() { - imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); - renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); + // Create one set of semaphores for each swapchain image + imageAvailableSemaphores.resize(imageCount()); + renderFinishedSemaphores.resize(imageCount()); inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); imagesInFlight.resize(imageCount(), VK_NULL_HANDLE); @@ -392,13 +401,20 @@ namespace hk fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + for (size_t i = 0; i < imageCount(); i++) { if (vkCreateSemaphore(device.device(), &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS || vkCreateSemaphore(device.device(), &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != - VK_SUCCESS || - vkCreateFence(device.device(), &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) + VK_SUCCESS) + { + throw std::runtime_error("failed to create synchronization objects for a frame!"); + } + } + + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + { + if (vkCreateFence(device.device(), &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) { throw std::runtime_error("failed to create synchronization objects for a frame!"); } diff --git a/main.cpp b/main.cpp index 7d487a9..ee252b8 100644 --- a/main.cpp +++ b/main.cpp @@ -5,7 +5,7 @@ #include #include -#define GRAVITY_SYSTEM 1 +#define GRAVITY_SYSTEM 0 int main() {