Recreating swap chain when invalidated

This commit is contained in:
2021-08-18 00:41:31 -07:00
parent 42717276b5
commit 2102faf4e5
4 changed files with 83 additions and 29 deletions

View File

@@ -71,15 +71,24 @@ void KRPresentationThread::run()
m_activeState = PresentThreadState::run; m_activeState = PresentThreadState::run;
while (m_requestedState != PresentThreadRequest::stop) while (m_requestedState != PresentThreadRequest::stop)
{ {
while (m_requestedState == PresentThreadRequest::run) { switch (m_activeState) {
m_activeState = PresentThreadState::run; case PresentThreadState::pause:
renderFrame(); case PresentThreadState::stop:
std::this_thread::sleep_for(sleep_duration); if (m_requestedState == PresentThreadRequest::run) {
} m_activeState = PresentThreadState::run;
while (m_requestedState == PresentThreadRequest::pause) { }
m_activeState = PresentThreadState::pause; break;
std::this_thread::sleep_for(sleep_duration); case PresentThreadState::run:
if (m_requestedState == PresentThreadRequest::pause) {
m_activeState = PresentThreadState::pause;
} else {
renderFrame();
}
break;
case PresentThreadState::error:
break;
} }
std::this_thread::sleep_for(sleep_duration);
} }
m_activeState = PresentThreadState::stop; m_activeState = PresentThreadState::stop;
} }
@@ -99,7 +108,19 @@ void KRPresentationThread::renderFrame()
KRDevice& device = m_pContext->getDeviceManager()->getDeviceInfo(surface.m_deviceHandle); KRDevice& device = m_pContext->getDeviceManager()->getDeviceInfo(surface.m_deviceHandle);
uint32_t imageIndex = 0; uint32_t imageIndex = 0;
vkAcquireNextImageKHR(device.m_logicalDevice, surface.m_swapChain, UINT64_MAX, surface.m_imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(device.m_logicalDevice, surface.m_swapChain, UINT64_MAX, surface.m_imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
// TODO - Must explicitly detect resize and trigger swapchain re-creation as well
vkDeviceWaitIdle(device.m_logicalDevice);
if (surface.recreateSwapChain() != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
}
break;
} else if (result != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
break;
}
// TODO - this will break with more than one surface... Expect to refactor this out // TODO - this will break with more than one surface... Expect to refactor this out
VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex]; VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex];
@@ -111,6 +132,7 @@ void KRPresentationThread::renderFrame()
beginInfo.pInheritanceInfo = nullptr; beginInfo.pInheritanceInfo = nullptr;
if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) { if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling... // TODO - Add error handling...
} }
@@ -130,6 +152,7 @@ void KRPresentationThread::renderFrame()
vkCmdDraw(commandBuffer, 3, 1, 0, 0); vkCmdDraw(commandBuffer, 3, 1, 0, 0);
vkCmdEndRenderPass(commandBuffer); vkCmdEndRenderPass(commandBuffer);
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling... // TODO - Add error handling...
} }
@@ -149,6 +172,7 @@ void KRPresentationThread::renderFrame()
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
if (vkQueueSubmit(device.m_graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) { if (vkQueueSubmit(device.m_graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling... // TODO - Add error handling...
} }

View File

@@ -63,7 +63,7 @@ public:
stop = 0, stop = 0,
run, run,
pause, pause,
wait_recreate_swapchain error
}; };
std::atomic<PresentThreadState> m_activeState; std::atomic<PresentThreadState> m_activeState;

View File

@@ -82,6 +82,36 @@ KrResult KRSurface::initialize()
return KR_ERROR_VULKAN; return KR_ERROR_VULKAN;
} }
return createSwapChain();
}
void KRSurface::destroy()
{
KRDevice& deviceInfo = m_pContext->getDeviceManager()->getDeviceInfo(m_deviceHandle);
destroySwapChain();
if (m_renderFinishedSemaphore != VK_NULL_HANDLE) {
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_renderFinishedSemaphore, nullptr);
m_renderFinishedSemaphore = VK_NULL_HANDLE;
}
if (m_imageAvailableSemaphore != VK_NULL_HANDLE) {
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_imageAvailableSemaphore, nullptr);
m_imageAvailableSemaphore = VK_NULL_HANDLE;
}
if (m_surface != VK_NULL_HANDLE) {
vkDestroySurfaceKHR(m_pContext->getDeviceManager()->getVulkanInstance(), m_surface, nullptr);
m_surface = VK_NULL_HANDLE;
}
}
KrResult KRSurface::createSwapChain()
{
KRDevice* deviceInfo = &m_pContext->getDeviceManager()->getDeviceInfo(m_deviceHandle);
VkSurfaceCapabilitiesKHR surfaceCapabilities{}; VkSurfaceCapabilitiesKHR surfaceCapabilities{};
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(deviceInfo->m_device, m_surface, &surfaceCapabilities); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(deviceInfo->m_device, m_surface, &surfaceCapabilities);
@@ -89,7 +119,6 @@ KrResult KRSurface::initialize()
uint32_t formatCount = 0; uint32_t formatCount = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, nullptr); vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, nullptr);
if (formatCount != 0) { if (formatCount != 0) {
surfaceFormats.resize(formatCount); surfaceFormats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, surfaceFormats.data()); vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, surfaceFormats.data());
@@ -228,8 +257,11 @@ KrResult KRSurface::initialize()
return KR_SUCCESS; return KR_SUCCESS;
} }
void KRSurface::destroy() void KRSurface::destroySwapChain()
{ {
KRPipelineManager* pipelineManager = m_pContext->getPipelineManager();
// TODO - Destroy the dependent pipeline..
KRDevice& deviceInfo = m_pContext->getDeviceManager()->getDeviceInfo(m_deviceHandle); KRDevice& deviceInfo = m_pContext->getDeviceManager()->getDeviceInfo(m_deviceHandle);
for (auto framebuffer : m_swapChainFramebuffers) { for (auto framebuffer : m_swapChainFramebuffers) {
@@ -246,20 +278,15 @@ void KRSurface::destroy()
vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, m_swapChain, nullptr); vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, m_swapChain, nullptr);
m_swapChain = VK_NULL_HANDLE; m_swapChain = VK_NULL_HANDLE;
} }
if (m_renderFinishedSemaphore != VK_NULL_HANDLE) {
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_renderFinishedSemaphore, nullptr);
m_renderFinishedSemaphore = VK_NULL_HANDLE;
}
if (m_imageAvailableSemaphore != VK_NULL_HANDLE) {
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_imageAvailableSemaphore, nullptr);
m_imageAvailableSemaphore = VK_NULL_HANDLE;
}
if (m_surface != VK_NULL_HANDLE) {
vkDestroySurfaceKHR(m_pContext->getDeviceManager()->getVulkanInstance(), m_surface, nullptr);
m_surface = VK_NULL_HANDLE;
}
} }
KrResult KRSurface::recreateSwapChain()
{
destroySwapChain();
KrResult result = createSwapChain();
if (result != KR_SUCCESS) {
destroySwapChain();
}
return result;
}

View File

@@ -50,6 +50,7 @@ public:
KRSurface& operator=(const KRSurface&) = delete; KRSurface& operator=(const KRSurface&) = delete;
KrResult initialize(); KrResult initialize();
KrResult recreateSwapChain();
#ifdef WIN32 #ifdef WIN32
HWND m_hWnd; HWND m_hWnd;
@@ -67,6 +68,8 @@ public:
private: private:
void destroySwapChain();
KrResult createSwapChain();
}; };
#endif // KRSURFACE_H #endif // KRSURFACE_H