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

+ 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
 	// Wait for this frame to complete
 	vkWaitForFences(mDevice, 1, &mInFlightFences[mFrameIndex], VK_TRUE, UINT64_MAX);
 	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);
 		vkDeviceWaitIdle(mDevice);
 		DestroySwapChain();
 		DestroySwapChain();
@@ -813,6 +813,13 @@ void RendererVK::BeginFrame(const CameraState &inCamera, float inWorldScale)
 		if (mSwapChain == nullptr)
 		if (mSwapChain == nullptr)
 			return;
 			return;
 		result = vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphores[mFrameIndex], VK_NULL_HANDLE, &mImageIndex);
 		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);
 	FatalErrorIfFailed(result);
 
 

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

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