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;
while (m_requestedState != PresentThreadRequest::stop)
{
while (m_requestedState == PresentThreadRequest::run) {
m_activeState = PresentThreadState::run;
renderFrame();
std::this_thread::sleep_for(sleep_duration);
}
while (m_requestedState == PresentThreadRequest::pause) {
m_activeState = PresentThreadState::pause;
std::this_thread::sleep_for(sleep_duration);
switch (m_activeState) {
case PresentThreadState::pause:
case PresentThreadState::stop:
if (m_requestedState == PresentThreadRequest::run) {
m_activeState = PresentThreadState::run;
}
break;
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;
}
@@ -99,7 +108,19 @@ void KRPresentationThread::renderFrame()
KRDevice& device = m_pContext->getDeviceManager()->getDeviceInfo(surface.m_deviceHandle);
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
VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex];
@@ -111,6 +132,7 @@ void KRPresentationThread::renderFrame()
beginInfo.pInheritanceInfo = nullptr;
if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling...
}
@@ -130,6 +152,7 @@ void KRPresentationThread::renderFrame()
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
vkCmdEndRenderPass(commandBuffer);
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling...
}
@@ -149,6 +172,7 @@ void KRPresentationThread::renderFrame()
submitInfo.pSignalSemaphores = signalSemaphores;
if (vkQueueSubmit(device.m_graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS) {
m_activeState = PresentThreadState::error;
// TODO - Add error handling...
}

View File

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

View File

@@ -82,6 +82,36 @@ KrResult KRSurface::initialize()
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{};
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(deviceInfo->m_device, m_surface, &surfaceCapabilities);
@@ -89,7 +119,6 @@ KrResult KRSurface::initialize()
uint32_t formatCount = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, nullptr);
if (formatCount != 0) {
surfaceFormats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, surfaceFormats.data());
@@ -228,8 +257,11 @@ KrResult KRSurface::initialize()
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);
for (auto framebuffer : m_swapChainFramebuffers) {
@@ -246,20 +278,15 @@ void KRSurface::destroy()
vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, m_swapChain, nullptr);
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;
KrResult initialize();
KrResult recreateSwapChain();
#ifdef WIN32
HWND m_hWnd;
@@ -67,6 +68,8 @@ public:
private:
void destroySwapChain();
KrResult createSwapChain();
};
#endif // KRSURFACE_H