From d216fee70b5e3b6d2143d6d751330903dc9123a1 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 23 Apr 2020 22:22:30 -0700 Subject: Fixed issue with infinite Vulkan swap chain growth on Android when orientation changes --- .../include/SwapChainVkImpl.hpp | 2 ++ .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 24 ++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp index 6bfc15ea..01cede61 100644 --- a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp @@ -88,6 +88,8 @@ private: std::shared_ptr m_VulkanInstance; + Uint32 m_DesiredBufferCount = 0; + VkSurfaceKHR m_VkSurface = VK_NULL_HANDLE; VkSwapchainKHR m_VkSwapChain = VK_NULL_HANDLE; VkFormat m_VkColorFormat = VK_FORMAT_UNDEFINED; diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index 69c8d5cc..6b577d95 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -44,6 +44,7 @@ SwapChainVkImpl::SwapChainVkImpl(IReferenceCounters* pRefCounters, // clang-format off TSwapChainBase {pRefCounters, pRenderDeviceVk, pDeviceContextVk, SCDesc}, m_VulkanInstance {pRenderDeviceVk->GetVulkanInstance()}, + m_DesiredBufferCount {SCDesc.BufferCount}, m_pBackBufferRTV (STD_ALLOCATOR_RAW_MEM(RefCntAutoPtr, GetRawAllocator(), "Allocator for vector>")), m_SwapChainImagesInitialized (STD_ALLOCATOR_RAW_MEM(bool, GetRawAllocator(), "Allocator for vector")), m_ImageAcquiredFenceSubmitted(STD_ALLOCATOR_RAW_MEM(bool, GetRawAllocator(), "Allocator for vector")) @@ -314,17 +315,23 @@ void SwapChainVkImpl::CreateVulkanSwapChain() // Asking for minImageCount images ensures that we can acquire // 1 presentable image as long as we present it before attempting // to acquire another. - if (m_SwapChainDesc.BufferCount < surfCapabilities.minImageCount) + if (m_DesiredBufferCount < surfCapabilities.minImageCount) { - LOG_INFO_MESSAGE("Requested back buffer count (", m_SwapChainDesc.BufferCount, ") is smaller than the minimal image count supported for this surface (", surfCapabilities.minImageCount, "). Resetting to ", surfCapabilities.minImageCount); - m_SwapChainDesc.BufferCount = surfCapabilities.minImageCount; + LOG_INFO_MESSAGE("Desired back buffer count (", m_DesiredBufferCount, ") is smaller than the minimal image count supported for this surface (", surfCapabilities.minImageCount, "). Resetting to ", surfCapabilities.minImageCount); + m_DesiredBufferCount = surfCapabilities.minImageCount; } - if (surfCapabilities.maxImageCount != 0 && m_SwapChainDesc.BufferCount > surfCapabilities.maxImageCount) + if (surfCapabilities.maxImageCount != 0 && m_DesiredBufferCount > surfCapabilities.maxImageCount) { - LOG_INFO_MESSAGE("Requested back buffer count (", m_SwapChainDesc.BufferCount, ") is greater than the maximal image count supported for this surface (", surfCapabilities.maxImageCount, "). Resetting to ", surfCapabilities.maxImageCount); - m_SwapChainDesc.BufferCount = surfCapabilities.maxImageCount; + LOG_INFO_MESSAGE("Desired back buffer count (", m_DesiredBufferCount, ") is greater than the maximal image count supported for this surface (", surfCapabilities.maxImageCount, "). Resetting to ", surfCapabilities.maxImageCount); + m_DesiredBufferCount = surfCapabilities.maxImageCount; } - uint32_t desiredNumberOfSwapChainImages = m_SwapChainDesc.BufferCount; + // We must use m_DesiredBufferCount instead of m_SwapChainDesc.BufferCount, because Vulkan on Android + // may decide to always add extra buffers, causing infinite growth of the swap chain when it is recreated: + // m_SwapChainDesc.BufferCount + // CreateVulkanSwapChain() 2 -> 4 + // CreateVulkanSwapChain() 4 -> 6 + // CreateVulkanSwapChain() 6 -> 8 + uint32_t desiredNumberOfSwapChainImages = m_DesiredBufferCount; // Find a supported composite alpha mode - one of these is guaranteed to be set VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; @@ -406,7 +413,8 @@ void SwapChainVkImpl::CreateVulkanSwapChain() VERIFY_EXPR(swapchainImageCount > 0); if (swapchainImageCount != m_SwapChainDesc.BufferCount) { - LOG_INFO_MESSAGE("Actual number of images in the created swap chain: ", m_SwapChainDesc.BufferCount); + LOG_INFO_MESSAGE("Created swap chain with ", swapchainImageCount, + " images vs ", m_SwapChainDesc.BufferCount, " requested."); m_SwapChainDesc.BufferCount = swapchainImageCount; } -- cgit v1.2.3