Browse Source

Fix crash when resizing a window in Linux

When Vulkan returns VK_SUBOPTIMAL_KHR we have already acquired an image, meaning that if we recreate the swap chain at that point, we'll mess with the state of the fences and trigger errors in Vulkan. Now storing this result and recreating the swap chain the next frame.
Jorrit Rouwe 7 months ago
parent
commit
10c95a0dfe
2 changed files with 10 additions and 2 deletions
  1. 9 2
      TestFramework/Renderer/VK/RendererVK.cpp
  2. 1 0
      TestFramework/Renderer/VK/RendererVK.h

+ 9 - 2
TestFramework/Renderer/VK/RendererVK.cpp

@@ -804,8 +804,8 @@ void RendererVK::BeginFrame(const CameraState &inCamera, float inWorldScale)
 	// Wait for this frame to complete
 	vkWaitForFences(mDevice, 1, &mInFlightFences[mFrameIndex], VK_TRUE, UINT64_MAX);
 
-	VkResult result = vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
-	if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
+	VkResult result = mSubOptimalSwapChain? VK_ERROR_OUT_OF_DATE_KHR : vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
+	if (result == VK_ERROR_OUT_OF_DATE_KHR)
 	{
 		vkDeviceWaitIdle(mDevice);
 		DestroySwapChain();
@@ -813,6 +813,13 @@ void RendererVK::BeginFrame(const CameraState &inCamera, float inWorldScale)
 		if (mSwapChain == nullptr)
 			return;
 		result = vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
+		mSubOptimalSwapChain = false;
+	}
+	else if (result == VK_SUBOPTIMAL_KHR)
+	{
+		// Render this frame with the suboptimal swap chain as we've already acquired an image
+		mSubOptimalSwapChain = true;
+		result = VK_SUCCESS;
 	}
 	FatalErrorIfFailed(result);
 

+ 1 - 0
TestFramework/Renderer/VK/RendererVK.h

@@ -78,6 +78,7 @@ private:
 	VkQueue							mPresentQueue = VK_NULL_HANDLE;
 	VkSurfaceKHR					mSurface = VK_NULL_HANDLE;
 	VkSwapchainKHR					mSwapChain = VK_NULL_HANDLE;
+	bool							mSubOptimalSwapChain = false;
 	Array<VkImage>					mSwapChainImages;
 	VkFormat						mSwapChainImageFormat;
 	VkExtent2D						mSwapChainExtent;