diff --git a/Common/GPU/Vulkan/VulkanFrameData.cpp b/Common/GPU/Vulkan/VulkanFrameData.cpp index 1bed118491..103604abd8 100644 --- a/Common/GPU/Vulkan/VulkanFrameData.cpp +++ b/Common/GPU/Vulkan/VulkanFrameData.cpp @@ -187,7 +187,14 @@ void FrameData::PresentExtraSwapchains(VulkanContext *vulkan) { VkResult res = vkQueuePresentKHR(vulkan->GetGraphicsQueue(), &present); if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_ERROR_SURFACE_LOST_KHR) { swapchain->outOfDate = true; - } else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) { + } else if (res == VK_SUBOPTIMAL_KHR) { + // Like the main swapchain, recreated once it stays that way (a TV's mode changed without a resize). + if (++swapchain->suboptimalFrames > VulkanContext::MAX_INFLIGHT_FRAMES) { + swapchain->outOfDate = true; + } + } else if (res == VK_SUCCESS) { + swapchain->suboptimalFrames = 0; + } else { ERROR_LOG(Log::G3D, "vkQueuePresentKHR failed for an additional swapchain: %s", VulkanResultToString(res)); } swapchain->acquired = false; diff --git a/Common/GPU/Vulkan/VulkanFrameData.h b/Common/GPU/Vulkan/VulkanFrameData.h index 6019e6dfd6..222325096e 100644 --- a/Common/GPU/Vulkan/VulkanFrameData.h +++ b/Common/GPU/Vulkan/VulkanFrameData.h @@ -94,6 +94,7 @@ struct VKRSwapchain { // Render thread. The image acquired for the frame being run, if any. uint32_t curImage = 0; bool acquired = false; + int suboptimalFrames = 0; // Set by the render thread, which can't recreate it. Checked at the start of a frame. std::atomic outOfDate{false}; }; diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 6486a121ad..0be3f64eae 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -676,6 +676,7 @@ bool VulkanRenderManager::InitExtraSwapchain(VKRSwapchain *swapchain, std::strin swapchain->framebuffers.push_back(framebuffer); } swapchain->outOfDate = false; + swapchain->suboptimalFrames = 0; INFO_LOG(Log::G3D, "Created an additional swapchain: %dx%d, %d images", extent.width, extent.height, (int)count); return true; }