refactor Renderer and SwapChain initialization for improved frame handling

This commit is contained in:
hoenking 2025-12-14 13:40:46 +08:00
parent b5c15637ec
commit 0bf2e20d96
4 changed files with 31 additions and 15 deletions

Binary file not shown.

View File

@ -7,7 +7,7 @@
namespace hk 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(); recreateSwapChain();
createCommandBuffers(); createCommandBuffers();
@ -46,7 +46,8 @@ namespace hk
} }
} }
// 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(); m_window.resetWindowResizedFlag();
recreateSwapChain(); recreateSwapChain();
} }
else if (result != VK_SUCCESS)
if (result != VK_SUCCESS)
{ {
throw std::runtime_error("failed to present swap chain image!"); throw std::runtime_error("failed to present swap chain image!");
} }

View File

@ -21,6 +21,8 @@ namespace hk
: device{deviceRef}, windowExtent{extent}, oldSwapChain{previous} : device{deviceRef}, windowExtent{extent}, oldSwapChain{previous}
{ {
init(); init();
// Reset currentFrame to 0 when creating a new swap chain
currentFrame = 0;
// clean up old swap chain // clean up old swap chain
oldSwapChain = nullptr; oldSwapChain = nullptr;
@ -65,10 +67,13 @@ namespace hk
vkDestroyRenderPass(device.device(), renderPass, nullptr); vkDestroyRenderPass(device.device(), renderPass, nullptr);
// cleanup synchronization objects // 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(), renderFinishedSemaphores[i], nullptr);
vkDestroySemaphore(device.device(), imageAvailableSemaphores[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); vkDestroyFence(device.device(), inFlightFences[i], nullptr);
} }
} }
@ -82,11 +87,12 @@ namespace hk
VK_TRUE, VK_TRUE,
std::numeric_limits<uint64_t>::max()); std::numeric_limits<uint64_t>::max());
// Acquire with a temporary semaphore, we'll use the imageIndex-specific one later
VkResult result = vkAcquireNextImageKHR( VkResult result = vkAcquireNextImageKHR(
device.device(), device.device(),
swapChain, swapChain,
std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(),
imageAvailableSemaphores[currentFrame], // must be a not signaled semaphore imageAvailableSemaphores[currentFrame % imageAvailableSemaphores.size()],
VK_NULL_HANDLE, VK_NULL_HANDLE,
imageIndex); imageIndex);
@ -105,7 +111,8 @@ namespace hk
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 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}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores;
@ -114,7 +121,8 @@ namespace hk
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = buffers; 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.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
@ -380,8 +388,9 @@ namespace hk
void SwapChain::createSyncObjects() void SwapChain::createSyncObjects()
{ {
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); // Create one set of semaphores for each swapchain image
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); imageAvailableSemaphores.resize(imageCount());
renderFinishedSemaphores.resize(imageCount());
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
imagesInFlight.resize(imageCount(), VK_NULL_HANDLE); imagesInFlight.resize(imageCount(), VK_NULL_HANDLE);
@ -392,13 +401,20 @@ namespace hk
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 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]) != if (vkCreateSemaphore(device.device(), &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) !=
VK_SUCCESS || VK_SUCCESS ||
vkCreateSemaphore(device.device(), &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != vkCreateSemaphore(device.device(), &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) !=
VK_SUCCESS || VK_SUCCESS)
vkCreateFence(device.device(), &fenceInfo, nullptr, &inFlightFences[i]) != 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!"); throw std::runtime_error("failed to create synchronization objects for a frame!");
} }

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#define GRAVITY_SYSTEM 1 #define GRAVITY_SYSTEM 0
int main() int main()
{ {