From a10fd28d41d6bbc046caf88bc41f286ebabb27fe Mon Sep 17 00:00:00 2001
From: Sebastian Gaida <gaida@ca-digit.com>
Date: Tue, 1 Jun 2021 16:35:45 +0200
Subject: [PATCH] [#34] add recreation for swapchain and imageViews

---
 include/vkcv/Core.hpp            |  4 +-
 include/vkcv/SwapChain.hpp       | 10 ++++-
 projects/first_mesh/src/main.cpp |  2 +-
 src/vkcv/Core.cpp                | 69 +++++++++++++++++++-------------
 src/vkcv/SwapChain.cpp           | 31 ++++++++++++--
 5 files changed, 83 insertions(+), 33 deletions(-)

diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 7d20685f..817672ea 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -88,7 +88,9 @@ namespace vkcv
          * @param[in] width new window width
          * @param[in] height new window hight
          */
-        static void recreateSwapchain( const vk::Device& device ,int width, int height);
+        void recreateSwapchain(int width, int height);
+
+        static std::vector<vk::ImageView> createImageViews( Context &context, SwapChain& swapChain);
 
     public:
         /**
diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp
index 1087d636..71889c07 100644
--- a/include/vkcv/SwapChain.hpp
+++ b/include/vkcv/SwapChain.hpp
@@ -10,6 +10,7 @@ namespace vkcv {
         vk::SurfaceKHR m_surface;
         vk::SwapchainKHR m_swapchain;
         vk::SurfaceFormatKHR m_format;
+        vk::PresentModeKHR m_presentMode;
 
 		uint32_t m_ImageCount;
 
@@ -21,7 +22,7 @@ namespace vkcv {
          * @param swapchain to show images in the window
          * @param format
          */
-        SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount);
+        SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount, vk::PresentModeKHR presentMode);
 
     public:
         SwapChain(const SwapChain &other) = default;
@@ -64,6 +65,13 @@ namespace vkcv {
 		 * @return number of images in swapchain
 		*/
 		uint32_t getImageCount();
+
+		/**
+		 *
+		 * @param width
+		 * @param height
+		 */
+        vk::SwapchainKHR recreateSwapchain( const Context &context, const Window &window, int width, int height);
     };
 
 }
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 6a4b1d01..0899acc8 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -142,8 +142,8 @@ int main(int argc, const char** argv) {
 
 	auto start = std::chrono::system_clock::now();
 	while (window.isWindowOpen()) {
+        window.pollEvents();
 		core.beginFrame();
-		window.pollEvents();
 		auto end = std::chrono::system_clock::now();
 		auto deltatime = end - start;
 		start = end;
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 486c4d5b..527e1453 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -41,31 +41,8 @@ namespace vkcv
 
         SwapChain swapChain = SwapChain::create(window, context, surface);
 
-        std::vector<vk::Image> swapChainImages = context.getDevice().getSwapchainImagesKHR(swapChain.getSwapchain());
         std::vector<vk::ImageView> imageViews;
-        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.getSurfaceFormat().format,
-                    componentMapping,
-                    subResourceRange
-            );
-
-            imageViews.push_back(context.getDevice().createImageView(imageViewCreateInfo));
-        }
+        imageViews = createImageViews( context, swapChain);
 
         const auto& queueManager = context.getQueueManager();
         
@@ -102,7 +79,7 @@ namespace vkcv
     	
     	m_ImageManager->m_core = this;
 
-        m_resizeHandle = window.e_resize.add( [&](int width, int height) { recreateSwapchain( this->getContext().getDevice(),width ,height ); });
+        m_resizeHandle = window.e_resize.add( [&](int width, int height) { recreateSwapchain( width ,height ); });
 	}
 
 	Core::~Core() noexcept {
@@ -306,8 +283,17 @@ namespace vkcv
 		return m_swapchain.getSurfaceFormat().format;
 	}
 
-    void Core::recreateSwapchain( const vk::Device& device, int width, int height) {
-        device.waitIdle();
+    void Core::recreateSwapchain( int width, int height) {
+        m_Context.getDevice().waitIdle();
+
+        destroyTemporaryFramebuffers();
+
+        for (auto image : m_swapchainImageViews) {
+            m_Context.m_Device.destroyImageView(image);
+        }
+
+        m_swapchain.recreateSwapchain(m_Context, m_window, width, height);
+        m_swapchainImageViews = createImageViews(m_Context, m_swapchain);
     }
 	
 	void Core::submitCommands(const SubmitInfo &submitInfo, const RecordCommandFunction& record, const FinishCommandFunction& finish)
@@ -362,4 +348,33 @@ namespace vkcv
 	vk::DescriptorSetLayout Core::getDescritorSetLayout(ResourcesHandle handle, size_t setIndex) {
 		return m_DescriptorManager->getDescriptorSetLayout(handle, setIndex);
 	}
+
+    std::vector<vk::ImageView> Core::createImageViews( 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.getSurfaceFormat().format,
+                    componentMapping,
+                    subResourceRange
+            );
+
+            imageViews.push_back(context.getDevice().createImageView(imageViewCreateInfo));
+        }
+        return imageViews;
+    }
 }
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index 3483ae37..513334ac 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -2,8 +2,8 @@
 
 namespace vkcv {
 
-    SwapChain::SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount)
-        : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount)
+    SwapChain::SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount, vk::PresentModeKHR presentMode)
+        : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount), m_presentMode(presentMode)
     {}
 
     const vk::SwapchainKHR& SwapChain::getSwapchain() const {
@@ -157,7 +157,32 @@ namespace vkcv {
 
         vk::SwapchainKHR swapchain = device.createSwapchainKHR(swapchainCreateInfo);
 
-        return SwapChain(surface, swapchain, surfaceFormat, imageCount);
+        return SwapChain(surface, swapchain, surfaceFormat, imageCount, presentMode);
+    }
+
+    vk::SwapchainKHR SwapChain::recreateSwapchain( const Context &context, const Window &window, int width, int height){
+        vk::SwapchainKHR oldSwapchain = m_swapchain;
+        vk::Extent2D extent2D = chooseSwapExtent(context.getPhysicalDevice(), m_surface, window);
+
+        vk::SwapchainCreateInfoKHR swapchainCreateInfo(
+                vk::SwapchainCreateFlagsKHR(),
+                m_surface,
+                m_ImageCount,
+                m_format.format,
+                m_format.colorSpace,
+                extent2D,
+                1,
+                vk::ImageUsageFlagBits::eColorAttachment,
+                vk::SharingMode::eExclusive,
+                0,
+                nullptr,
+                vk::SurfaceTransformFlagBitsKHR::eIdentity,
+                vk::CompositeAlphaFlagBitsKHR::eOpaque,
+                m_presentMode,
+                true,
+                oldSwapchain
+        );
+        m_swapchain = context.getDevice().createSwapchainKHR(swapchainCreateInfo);
     }
 
 
-- 
GitLab