Browse Source

Fix a bug in swapchain re-creation

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
ff39e26c2e
2 changed files with 17 additions and 5 deletions
  1. 4 1
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  2. 13 4
      AnKi/Gr/Vulkan/MicroObjectRecycler.inl.h

+ 4 - 1
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -929,6 +929,7 @@ TexturePtr GrManagerImpl::acquireNextPresentableTexture()
 		{
 		{
 			vkQueueWaitIdle(queue);
 			vkQueueWaitIdle(queue);
 		}
 		}
+		m_crntSwapchain.reset(nullptr);
 		m_crntSwapchain = m_swapchainFactory.newInstance();
 		m_crntSwapchain = m_swapchainFactory.newInstance();
 
 
 		// Can't fail a second time
 		// Can't fail a second time
@@ -983,11 +984,13 @@ void GrManagerImpl::endFrame()
 	const VkResult res1 = vkQueuePresentKHR(m_queues[frame.m_queueWroteToSwapchainImage], &present);
 	const VkResult res1 = vkQueuePresentKHR(m_queues[frame.m_queueWroteToSwapchainImage], &present);
 	if(res1 == VK_ERROR_OUT_OF_DATE_KHR)
 	if(res1 == VK_ERROR_OUT_OF_DATE_KHR)
 	{
 	{
-		ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queue and create a new one");
+		ANKI_VK_LOGW("Swapchain is out of date. Will wait for the queues and create a new one");
 		for(VkQueue queue : m_queues)
 		for(VkQueue queue : m_queues)
 		{
 		{
 			vkQueueWaitIdle(queue);
 			vkQueueWaitIdle(queue);
 		}
 		}
+		vkDeviceWaitIdle(m_device);
+		m_crntSwapchain.reset(nullptr);
 		m_crntSwapchain = m_swapchainFactory.newInstance();
 		m_crntSwapchain = m_swapchainFactory.newInstance();
 	}
 	}
 	else
 	else

+ 13 - 4
AnKi/Gr/Vulkan/MicroObjectRecycler.inl.h

@@ -97,7 +97,7 @@ inline void MicroObjectRecycler<T>::trimCache()
 
 
 	releaseFences();
 	releaseFences();
 
 
-	DynamicArray<T*> newObjects;
+	DynamicArray<T*> aliveObjects;
 
 
 	for(U32 i = 0; i < m_objects.getSize(); ++i)
 	for(U32 i = 0; i < m_objects.getSize(); ++i)
 	{
 	{
@@ -108,19 +108,28 @@ inline void MicroObjectRecycler<T>::trimCache()
 		if(obj->getFence())
 		if(obj->getFence())
 		{
 		{
 			// Can't delete it
 			// Can't delete it
-			newObjects.emplaceBack(m_alloc, obj);
+			aliveObjects.emplaceBack(m_alloc, obj);
 		}
 		}
 		else
 		else
 		{
 		{
 			auto alloc = obj->getAllocator();
 			auto alloc = obj->getAllocator();
 			alloc.deleteInstance(obj);
 			alloc.deleteInstance(obj);
+#if ANKI_EXTRA_CHECKS
+			--m_createdAndNotRecycled;
+#endif
 		}
 		}
 	}
 	}
 
 
-	if(newObjects.getSize() > 0)
+	if(aliveObjects.getSize() > 0)
+	{
+		// Some alive, store the alive
+		m_objects.destroy(m_alloc);
+		m_objects = std::move(aliveObjects);
+	}
+	else if(aliveObjects.getSize() == 0 && m_objects.getSize() >= 0)
 	{
 	{
+		// All dead, destroy the array
 		m_objects.destroy(m_alloc);
 		m_objects.destroy(m_alloc);
-		m_objects = std::move(newObjects);
 	}
 	}
 }
 }