refactor Renderer and SwapChain initialization for improved frame handling
This commit is contained in:
parent
b5c15637ec
commit
0bf2e20d96
BIN
VulkanTest
BIN
VulkanTest
Binary file not shown.
|
|
@ -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!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue