From 579a2ce47c72f75ba003fd106a0a1079b1cf405b Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Thu, 1 Jul 2021 16:16:06 +0200
Subject: [PATCH] [#82] Disabled swapchain recreation for too low sizes

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 include/vkcv/Core.hpp      |  2 --
 include/vkcv/Swapchain.hpp |  4 +++
 src/vkcv/Core.cpp          | 71 +++++++++++++++++++++-----------------
 src/vkcv/Swapchain.cpp     | 51 ++++++++++++++++-----------
 4 files changed, 73 insertions(+), 55 deletions(-)

diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index e3a42943..a10cfc55 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -78,8 +78,6 @@ namespace vkcv
 
 		event_handle<int,int> e_resizeHandle;
 
-        static std::vector<vk::ImageView> createSwapchainImageViews( Context &context, Swapchain& swapChain);
-
     public:
         /**
          * Destructor of #Core destroys the Vulkan objects contained in the core's context.
diff --git a/include/vkcv/Swapchain.hpp b/include/vkcv/Swapchain.hpp
index b75fc5a8..5e9bc7d0 100644
--- a/include/vkcv/Swapchain.hpp
+++ b/include/vkcv/Swapchain.hpp
@@ -7,6 +7,9 @@
 
 namespace vkcv
 {
+	
+	const uint32_t MIN_SWAPCHAIN_SIZE = 2;
+	
     class Swapchain final {
     private:
     	friend class Core;
@@ -119,4 +122,5 @@ namespace vkcv
 		const vk::Extent2D& getExtent() const;
     
     };
+    
 }
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index df306be5..6dbc41e4 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -20,6 +20,35 @@
 
 namespace vkcv
 {
+	
+	static std::vector<vk::ImageView> createSwapchainImageViews( Context &context, const std::vector<vk::Image>& images,
+																 vk::Format format){
+		std::vector<vk::ImageView> imageViews;
+		imageViews.reserve( images.size() );
+		//here can be swizzled with vk::ComponentSwizzle if needed
+		vk::ComponentMapping componentMapping(
+				vk::ComponentSwizzle::eR,
+				vk::ComponentSwizzle::eG,
+				vk::ComponentSwizzle::eB,
+				vk::ComponentSwizzle::eA );
+		
+		vk::ImageSubresourceRange subResourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 );
+		
+		for ( auto image : images )
+		{
+			vk::ImageViewCreateInfo imageViewCreateInfo(
+					vk::ImageViewCreateFlags(),
+					image,
+					vk::ImageViewType::e2D,
+					format,
+					componentMapping,
+					subResourceRange);
+			
+			imageViews.push_back(context.getDevice().createImageView(imageViewCreateInfo));
+		}
+		
+		return imageViews;
+	}
 
     Core Core::create(Window &window,
                       const char *applicationName,
@@ -36,8 +65,9 @@ namespace vkcv
 		);
 
         Swapchain swapChain = Swapchain::create(window, context);
-
-		 std::vector<vk::ImageView> swapchainImageViews = createSwapchainImageViews( context, swapChain);
+	
+		const auto swapchainImages = context.getDevice().getSwapchainImagesKHR(swapChain.getSwapchain());
+		const auto swapchainImageViews = createSwapchainImageViews( context, swapchainImages, swapChain.getFormat());
 
         const auto& queueManager = context.getQueueManager();
         
@@ -158,8 +188,13 @@ namespace vkcv
 			m_Context.getDevice().waitIdle();
 
 			m_swapchain.updateSwapchain(m_Context, m_window);
-			const auto swapchainViews = createSwapchainImageViews(m_Context, m_swapchain);
+			
+			if (!m_swapchain.getSwapchain()) {
+				return false;
+			}
+			
 			const auto swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
+			const auto swapchainViews = createSwapchainImageViews(m_Context, swapchainImages, m_swapchain.getFormat());
 			
 			const auto& extent = m_swapchain.getExtent();
 
@@ -176,7 +211,7 @@ namespace vkcv
 		width = extent.width;
 		height = extent.height;
 		
-		if ((width < 2) || (height < 2)) {
+		if ((width < MIN_SWAPCHAIN_SIZE) || (height < MIN_SWAPCHAIN_SIZE)) {
 			return false;
 		}
 		
@@ -505,34 +540,6 @@ namespace vkcv
 		return m_DescriptorManager->getDescriptorSet(handle);
 	}
 
-    std::vector<vk::ImageView> Core::createSwapchainImageViews( Context &context, Swapchain& swapChain){
-        std::vector<vk::ImageView> imageViews;
-        std::vector<vk::Image> swapChainImages = context.getDevice().getSwapchainImagesKHR(swapChain.getSwapchain());
-        imageViews.reserve( swapChainImages.size() );
-        //here can be swizzled with vk::ComponentSwizzle if needed
-        vk::ComponentMapping componentMapping(
-                vk::ComponentSwizzle::eR,
-                vk::ComponentSwizzle::eG,
-                vk::ComponentSwizzle::eB,
-                vk::ComponentSwizzle::eA );
-
-        vk::ImageSubresourceRange subResourceRange( vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 );
-
-        for ( auto image : swapChainImages )
-        {
-            vk::ImageViewCreateInfo imageViewCreateInfo(
-                    vk::ImageViewCreateFlags(),
-                    image,
-                    vk::ImageViewType::e2D,
-                    swapChain.getFormat(),
-                    componentMapping,
-                    subResourceRange);
-
-            imageViews.push_back(context.getDevice().createImageView(imageViewCreateInfo));
-        }
-        return imageViews;
-    }
-
 	void Core::prepareSwapchainImageForPresent(const CommandStreamHandle cmdStream) {
 		auto swapchainHandle = ImageHandle::createSwapchainImageHandle();
 		recordCommandsToStream(cmdStream, [swapchainHandle, this](const vk::CommandBuffer cmdBuffer) {
diff --git a/src/vkcv/Swapchain.cpp b/src/vkcv/Swapchain.cpp
index 4ca8056b..94e7301d 100644
--- a/src/vkcv/Swapchain.cpp
+++ b/src/vkcv/Swapchain.cpp
@@ -221,27 +221,36 @@ namespace vkcv
 		vk::SwapchainKHR oldSwapchain = m_Swapchain;
 		vk::Extent2D extent2D = chooseExtent(context.getPhysicalDevice(), m_Surface.handle, window);
 	
-		vk::SwapchainCreateInfoKHR swapchainCreateInfo(
-				vk::SwapchainCreateFlagsKHR(),
-				m_Surface.handle,
-				m_ImageCount,
-				m_Format,
-				m_ColorSpace,
-				extent2D,
-				1,
-				vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage,
-				vk::SharingMode::eExclusive,
-				0,
-				nullptr,
-				vk::SurfaceTransformFlagBitsKHR::eIdentity,
-				vk::CompositeAlphaFlagBitsKHR::eOpaque,
-				m_PresentMode,
-				true,
-				oldSwapchain
-		);
-	
-		m_Swapchain = context.getDevice().createSwapchainKHR(swapchainCreateInfo);
-		context.getDevice().destroySwapchainKHR(oldSwapchain);
+		if ((extent2D.width >= MIN_SWAPCHAIN_SIZE) && (extent2D.height >= MIN_SWAPCHAIN_SIZE)) {
+			vk::SwapchainCreateInfoKHR swapchainCreateInfo(
+					vk::SwapchainCreateFlagsKHR(),
+					m_Surface.handle,
+					m_ImageCount,
+					m_Format,
+					m_ColorSpace,
+					extent2D,
+					1,
+					vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage,
+					vk::SharingMode::eExclusive,
+					0,
+					nullptr,
+					vk::SurfaceTransformFlagBitsKHR::eIdentity,
+					vk::CompositeAlphaFlagBitsKHR::eOpaque,
+					m_PresentMode,
+					true,
+					oldSwapchain
+			);
+			
+			m_Swapchain = context.getDevice().createSwapchainKHR(swapchainCreateInfo);
+		} else {
+			m_Swapchain = nullptr;
+			
+			signalSwapchainRecreation();
+		}
+		
+		if (oldSwapchain) {
+			context.getDevice().destroySwapchainKHR(oldSwapchain);
+		}
 		
 		m_Extent = extent2D;
     }
-- 
GitLab