Vulkan: If acquiring a frame fails (happens sometimes during window resize), skip swapping the frame. Should help #10063

This commit is contained in:
Henrik Rydgård 2017-11-07 09:56:41 +01:00
parent 4cee442b0f
commit 7922a2ab5c
2 changed files with 22 additions and 15 deletions

View file

@ -701,6 +701,8 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) {
VkResult res = vkAcquireNextImageKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), UINT64_MAX, acquireSemaphore_, (VkFence)VK_NULL_HANDLE, &frameData.curSwapchainImage); VkResult res = vkAcquireNextImageKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), UINT64_MAX, acquireSemaphore_, (VkFence)VK_NULL_HANDLE, &frameData.curSwapchainImage);
if (res == VK_SUBOPTIMAL_KHR) { if (res == VK_SUBOPTIMAL_KHR) {
// Hopefully the resize will happen shortly. Ignore. // Hopefully the resize will happen shortly. Ignore.
} else if (res == VK_ERROR_OUT_OF_DATE_KHR) {
frameData.skipSwap = true;
} else { } else {
assert(res == VK_SUCCESS); assert(res == VK_SUCCESS);
} }
@ -751,7 +753,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
cmdBufs[numCmdBufs++] = frameData.mainCmd; cmdBufs[numCmdBufs++] = frameData.mainCmd;
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
if (triggerFence) { if (triggerFence && !frameData.skipSwap) {
submit_info.waitSemaphoreCount = 1; submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &acquireSemaphore_; submit_info.pWaitSemaphores = &acquireSemaphore_;
VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
@ -759,7 +761,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
} }
submit_info.commandBufferCount = (uint32_t)numCmdBufs; submit_info.commandBufferCount = (uint32_t)numCmdBufs;
submit_info.pCommandBuffers = cmdBufs; submit_info.pCommandBuffers = cmdBufs;
if (triggerFence) { if (triggerFence && !frameData.skipSwap) {
submit_info.signalSemaphoreCount = 1; submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &renderingCompleteSemaphore_; submit_info.pSignalSemaphores = &renderingCompleteSemaphore_;
} }
@ -785,21 +787,25 @@ void VulkanRenderManager::EndSubmitFrame(int frame) {
Submit(frame, true); Submit(frame, true);
VkSwapchainKHR swapchain = vulkan_->GetSwapchain(); if (!frameData.skipSwap) {
VkPresentInfoKHR present = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; VkSwapchainKHR swapchain = vulkan_->GetSwapchain();
present.swapchainCount = 1; VkPresentInfoKHR present = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
present.pSwapchains = &swapchain; present.swapchainCount = 1;
present.pImageIndices = &frameData.curSwapchainImage; present.pSwapchains = &swapchain;
present.pWaitSemaphores = &renderingCompleteSemaphore_; present.pImageIndices = &frameData.curSwapchainImage;
present.waitSemaphoreCount = 1; present.pWaitSemaphores = &renderingCompleteSemaphore_;
present.waitSemaphoreCount = 1;
VkResult res = vkQueuePresentKHR(vulkan_->GetGraphicsQueue(), &present); VkResult res = vkQueuePresentKHR(vulkan_->GetGraphicsQueue(), &present);
// TODO: Deal with the VK_SUBOPTIMAL_WSI and VK_ERROR_OUT_OF_DATE_WSI // TODO: Deal with the VK_SUBOPTIMAL_WSI and VK_ERROR_OUT_OF_DATE_WSI
// return codes // return codes
if (res == VK_ERROR_OUT_OF_DATE_KHR) { if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain. // ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain.
} else {
assert(res == VK_SUCCESS);
}
} else { } else {
assert(res == VK_SUCCESS); frameData.skipSwap = false;
} }
} }

View file

@ -238,6 +238,7 @@ private:
bool readyForFence = true; bool readyForFence = true;
bool readyForRun = false; bool readyForRun = false;
bool skipSwap = false;
VKRRunType type = VKRRunType::END; VKRRunType type = VKRRunType::END;
VkFence fence; VkFence fence;