diff --git a/config/Sources.cmake b/config/Sources.cmake
index 8fc0aa9a2605a629596e26d5eeb0772164e6ec7a..6fc477cc9552d0a9a8921151ca4435b894630755 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -50,10 +50,7 @@ set(vkcv_sources
         
         ${vkcv_include}/vkcv/QueueManager.hpp
         ${vkcv_source}/vkcv/QueueManager.cpp
-        
-        ${vkcv_source}/vkcv/Surface.hpp
-        ${vkcv_source}/vkcv/Surface.cpp
-        
+
         ${vkcv_source}/vkcv/ImageLayoutTransitions.hpp
         ${vkcv_source}/vkcv/ImageLayoutTransitions.cpp
 
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index c8d69fe14379dee2677bd8a2f829348bc5289cf0..0a50765fedb07f1117b5e0ecaa43c03b362c23ce 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -56,13 +56,12 @@ namespace vkcv
          *
          * @param context encapsulates various Vulkan objects
          */
-        Core(Context &&context, Window &window, SwapChain swapChain,  std::vector<vk::ImageView> imageViews,
+        Core(Context &&context, Window &window, const SwapChain& swapChain,  std::vector<vk::ImageView> imageViews,
 			const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
         // explicit destruction of default constructor
         Core() = delete;
 
 		Result acquireSwapchainImage();
-		void destroyTemporaryFramebuffers();
 
         Context m_Context;
 
@@ -80,16 +79,12 @@ namespace vkcv
 		CommandResources				m_CommandResources;
 		SyncResources					m_SyncResources;
 		uint32_t						m_currentSwapchainImageIndex;
-		std::vector<vk::Framebuffer>	m_TemporaryFramebuffers;
-		
+
 		ImageHandle						m_DepthImage;
 
-        /**
-         * recreates the swapchain
-         * @param[in] width new window width
-         * @param[in] height new window hight
-         */
-        static void recreateSwapchain(int width, int height);
+        std::function<void(int, int)> e_resizeHandle;
+
+        static std::vector<vk::ImageView> createImageViews( Context &context, SwapChain& swapChain);
 
     public:
         /**
@@ -230,14 +225,12 @@ namespace vkcv
 		 * @brief render a beautiful triangle
 		*/
 		void renderMesh(
-			const PassHandle						renderpassHandle, 
-			const PipelineHandle					pipelineHandle,
-			const uint32_t							width,
-			const uint32_t							height,
+			const PassHandle						&renderpassHandle,
+			const PipelineHandle					&pipelineHandle,
 			const size_t							pushConstantSize, 
 			const void*								pushConstantData, 
 			const std::vector<VertexBufferBinding>	&vertexBufferBindings, 
-			const BufferHandle						indexBuffer, 
+			const BufferHandle						&indexBuffer,
 			const size_t							indexCount,
 			const vkcv::ResourcesHandle				resourceHandle,
 			const size_t							resourceDescriptorSetIndex);
diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp
index 1087d6364f6f811b741904d4e2b31fcfeb450901..53f7b783051307c7d327f20f389d7bef0fb9a16c 100644
--- a/include/vkcv/SwapChain.hpp
+++ b/include/vkcv/SwapChain.hpp
@@ -3,15 +3,32 @@
 #include "Context.hpp"
 #include "vkcv/Window.hpp"
 
-namespace vkcv {
+#include <atomic>
+
+namespace vkcv
+{
     class SwapChain final {
     private:
 
-        vk::SurfaceKHR m_surface;
-        vk::SwapchainKHR m_swapchain;
-        vk::SurfaceFormatKHR m_format;
+        struct Surface
+        {
+            vk::SurfaceKHR handle;
+            std::vector<vk::SurfaceFormatKHR> formats;
+            vk::SurfaceCapabilitiesKHR capabilities;
+            std::vector<vk::PresentModeKHR> presentModes;
+        };
+        
+        Surface m_Surface;
 
-		uint32_t m_ImageCount;
+        vk::SwapchainKHR m_Swapchain;
+        vk::Format m_SwapchainFormat;
+        vk::ColorSpaceKHR m_SwapchainColorSpace;
+        vk::PresentModeKHR m_SwapchainPresentMode;
+		uint32_t m_SwapchainImageCount;
+	
+		vk::Extent2D m_Extent;
+	
+		std::atomic<bool> m_RecreationRequired;
 
         /**
          * Constructor of a SwapChain object
@@ -21,11 +38,17 @@ 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);
+         // TODO:
+        SwapChain(const Surface &surface,
+                  vk::SwapchainKHR swapchain,
+                  vk::Format format,
+                  vk::ColorSpaceKHR colorSpace,
+                  vk::PresentModeKHR presentMode,
+                  uint32_t imageCount,
+				  vk::Extent2D extent) noexcept;
 
     public:
-        SwapChain(const SwapChain &other) = default;
-        SwapChain(SwapChain &&other) = default;
+    	SwapChain(const SwapChain& other);
 
         /**
          * @return The swapchain linked with the #SwapChain class
@@ -39,13 +62,14 @@ namespace vkcv {
          * @return current surface
          */
         [[nodiscard]]
-        vk::SurfaceKHR getSurface();
+        vk::SurfaceKHR getSurface() const;
+
         /**
-         * gets the current surface format
-         * @return gets the surface format
+         * gets the chosen swapchain format
+         * @return gets the chosen swapchain format
          */
         [[nodiscard]]
-        vk::SurfaceFormatKHR getSurfaceFormat();
+        vk::Format getSwapchainFormat() const;
 
         /**
          * creates a swap chain object out of the given window and the given context
@@ -53,7 +77,7 @@ namespace vkcv {
          * @param context of the application
          * @return returns an object of swapChain
          */
-        static SwapChain create(const Window &window, const Context &context, const vk::SurfaceKHR surface);
+        static SwapChain create(const Window &window, const Context &context);
 
         /**
          * Destructor of SwapChain
@@ -64,6 +88,34 @@ namespace vkcv {
 		 * @return number of images in swapchain
 		*/
 		uint32_t getImageCount();
-    };
+		
+		/**
+		 * TODO
+		 *
+		 * @return
+		 */
+		bool shouldUpdateSwapchain() const;
 
+		/**
+		 * TODO
+		 *
+		 * context
+		 * window
+		 */
+		void updateSwapchain(const Context &context, const Window &window);
+		
+		/**
+		 *
+		 */
+        void recreateSwapchain();
+	
+        /**
+         * TODO
+         *
+         * @return
+         */
+        [[nodiscard]]
+		const vk::Extent2D& getExtent() const;
+    
+    };
 }
diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp
index 7428c7c73eb481f7352821faed36257211dfd5bf..f71671c935a0a5e17bb517c726d75ffff2973532 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -17,7 +17,6 @@ namespace vkcv {
     private:
         GLFWwindow *m_window;
 
-
         /**
          *
          * @param GLFWwindow of the class
diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp
index 7e177b9a2fbde0890e0c8ea6a1d9a19d6e277c7c..ff8fda811eaad7a99dbb940601f9e5904025255e 100644
--- a/modules/camera/include/vkcv/camera/Camera.hpp
+++ b/modules/camera/include/vkcv/camera/Camera.hpp
@@ -63,7 +63,7 @@ namespace vkcv {
         
         void changeFov(double fov);
 
-        void updateRatio(float ratio);
+        void updateRatio(int width, int height);
 
         float getRatio() const;
 
diff --git a/modules/camera/include/vkcv/camera/CameraManager.hpp b/modules/camera/include/vkcv/camera/CameraManager.hpp
index 9511b752e972afb1e10f41a118433a4e8933fd65..4e52eccea25e8544a9a5cc89d0dc74ddd0e023c6 100644
--- a/modules/camera/include/vkcv/camera/CameraManager.hpp
+++ b/modules/camera/include/vkcv/camera/CameraManager.hpp
@@ -9,10 +9,11 @@ namespace vkcv{
 
     class CameraManager{
     private:
-        std::function<void(int, int, int, int)> m_keyHandle;
-        std::function<void(double, double)> m_mouseMoveHandle;
-        std::function<void(double, double)> m_mouseScrollHandle;
-        std::function<void(int, int, int)> m_mouseButtonHandle;
+        std::function<void(int, int, int, int)> e_keyHandle;
+        std::function<void(double, double)> e_mouseMoveHandle;
+        std::function<void(double, double)> e_mouseScrollHandle;
+        std::function<void(int, int, int)> e_mouseButtonHandle;
+        std::function<void(int, int)> e_resizeHandle;
 
         Window &m_window;
         Camera m_camera;
@@ -29,6 +30,7 @@ namespace vkcv{
         void scrollCallback( double offsetX, double offsetY);
         void mouseMoveCallback( double offsetX, double offsetY);
         void mouseButtonCallback(int button, int action, int mods);
+        void resizeCallback(int width, int height);
 
     public:
         CameraManager(Window &window, float width, float height, glm::vec3 up = glm::vec3(0.0f,-1.0f,0.0f), glm::vec3 position = glm::vec3(0.0f,0.0f,0.0f));
diff --git a/modules/camera/src/vkcv/camera/Camera.cpp b/modules/camera/src/vkcv/camera/Camera.cpp
index bc8a8498e67a6bd751f5a6ed1d4c4fba0279a68d..b1d7381e3d548c9edf5d41e8d084c7edb1d02647 100644
--- a/modules/camera/src/vkcv/camera/Camera.cpp
+++ b/modules/camera/src/vkcv/camera/Camera.cpp
@@ -82,8 +82,10 @@ namespace vkcv {
         setFov(fov);
     }
 
-    void Camera::updateRatio( float ratio){
-        m_ratio = ratio;
+    void Camera::updateRatio( int width, int height){
+        m_width = width;
+        m_height = height;
+        m_ratio = static_cast<float>(width)/glm::max(height, 1);
         setPerspective( m_fov, m_ratio, m_near, m_far);
     }
 
diff --git a/modules/camera/src/vkcv/camera/CameraManager.cpp b/modules/camera/src/vkcv/camera/CameraManager.cpp
index 18f499a2b34b64c1442c5d9e267d6476b8d69199..2631890d646fbf27a4fbb14cfeef706678d8918c 100644
--- a/modules/camera/src/vkcv/camera/CameraManager.cpp
+++ b/modules/camera/src/vkcv/camera/CameraManager.cpp
@@ -15,10 +15,11 @@ namespace vkcv{
     }
 
     void CameraManager::bindCamera(){
-        m_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
-        m_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
-        m_mouseScrollHandle =  m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
-        m_mouseButtonHandle = m_window.e_mouseButton.add([&] (int button, int action, int mods) {this->mouseButtonCallback( button,  action,  mods);});
+        e_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
+        e_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
+        e_mouseScrollHandle =  m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
+        e_mouseButtonHandle = m_window.e_mouseButton.add([&] (int button, int action, int mods) {this->mouseButtonCallback( button,  action,  mods);});
+        e_resizeHandle = m_window.e_resize.add([&] (int width, int height) {this->resizeCallback( width, height);});
     }
 
     void CameraManager::mouseButtonCallback(int button, int action, int mods){
@@ -75,6 +76,11 @@ namespace vkcv{
                 break;
         }
     }
+
+    void CameraManager::resizeCallback(int width, int height){
+            m_camera.updateRatio(width, height);
+    }
+
     Camera &CameraManager::getCamera(){
         return m_camera;
     }
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 306aa524262325b993ade46eaba4b8d989400c51..01d8b74fe39a15459169926645f429805299a786 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -8,16 +8,14 @@
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Mesh";
 
-	const int windowWidth = 800;
-	const int windowHeight = 600;
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
-		false
+        800,
+        600,
+		true
 	);
 
-	vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
+	vkcv::CameraManager cameraManager(window, static_cast<float>(window.getWidth()), static_cast<float>(window.getHeight()));
 
 	window.initEvents();
 
@@ -43,7 +41,7 @@ int main(int argc, const char** argv) {
 		return 1;
 	}
 
-	assert(mesh.vertexGroups.size() > 0);
+	assert(!mesh.vertexGroups.empty());
 	auto vertexBuffer = core.createBuffer<uint8_t>(
 			vkcv::BufferType::VERTEX,
 			mesh.vertexGroups[0].vertexBuffer.data.size(),
@@ -112,9 +110,9 @@ int main(int argc, const char** argv) {
 	//end of exemplary code
 
 	const vkcv::PipelineConfig trianglePipelineDefinition(
-		triangleShaderProgram, 
-		windowWidth,
-		windowHeight,
+		triangleShaderProgram,
+        UINT32_MAX,
+        UINT32_MAX,
 		trianglePass,
 		mesh.vertexGroups[0].vertexBuffer.attributes,
 		{ core.getDescriptorSetLayout(set, 0) });
@@ -148,8 +146,12 @@ int main(int argc, const char** argv) {
 
 	auto start = std::chrono::system_clock::now();
 	while (window.isWindowOpen()) {
+        vkcv::Window::pollEvents();
+
+        if(window.getHeight() == 0 || window.getWidth() == 0)
+            continue;
+
 		core.beginFrame();
-		window.pollEvents();
 		auto end = std::chrono::system_clock::now();
 		auto deltatime = end - start;
 		start = end;
@@ -159,8 +161,6 @@ int main(int argc, const char** argv) {
 		core.renderMesh(
 			trianglePass,
 			trianglePipeline,
-			windowWidth,
-			windowHeight,
 			sizeof(mvp),
 			&mvp,
 			vertexBufferBindings,
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 2c071b727f7e41e7eb4dee17a2da3302f615ffa0..397498e60375ee34497b60fef7d27cbb2c0c7989 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -147,8 +147,6 @@ int main(int argc, const char** argv) {
 	    core.renderMesh(
 			trianglePass,
 			trianglePipeline,
-			windowWidth,
-			windowHeight,
 			sizeof(mvp),
 			&mvp,
 			vertexBufferBindings,
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index bd3ec34a1f017fd42639358a977a0ead9666d307..27e84ee5cdb062adc0e9f96cdfa7e761e6f24279 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -13,7 +13,6 @@
 #include "SamplerManager.hpp"
 #include "ImageManager.hpp"
 #include "DescriptorManager.hpp"
-#include "Surface.hpp"
 #include "ImageLayoutTransitions.hpp"
 
 namespace vkcv
@@ -32,40 +31,11 @@ namespace vkcv
         		instanceExtensions,
         		deviceExtensions
 		);
-	
-		const vk::SurfaceKHR surface = createSurface(
-				window.getWindow(),
-				context.getInstance(),
-				context.getPhysicalDevice()
-		);
 
-        SwapChain swapChain = SwapChain::create(window, context, surface);
+        SwapChain swapChain = SwapChain::create(window, context);
 
-        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();
         
@@ -74,10 +44,6 @@ namespace vkcv
 		const auto						commandResources		= createCommandResources(context.getDevice(), queueFamilySet);
 		const auto						defaultSyncResources	= createSyncResources(context.getDevice());
 
-        window.e_resize.add([&](int width, int height){
-            recreateSwapchain(width,height);
-        });
-
         return Core(std::move(context) , window, swapChain, imageViews, commandResources, defaultSyncResources);
     }
 
@@ -86,7 +52,7 @@ namespace vkcv
         return m_Context;
     }
 
-	Core::Core(Context &&context, Window &window , SwapChain swapChain,  std::vector<vk::ImageView> imageViews,
+	Core::Core(Context &&context, Window &window, const SwapChain& swapChain,  std::vector<vk::ImageView> imageViews,
 		const CommandResources& commandResources, const SyncResources& syncResources) noexcept :
             m_Context(std::move(context)),
             m_window(window),
@@ -105,6 +71,10 @@ namespace vkcv
     	m_BufferManager->init();
     	
     	m_ImageManager->m_core = this;
+
+        e_resizeHandle = window.e_resize.add( [&](int width, int height) {
+        	m_swapchain.recreateSwapchain();
+        });
 	}
 
 	Core::~Core() noexcept {
@@ -115,7 +85,6 @@ namespace vkcv
 
 		destroyCommandResources(m_Context.getDevice(), m_CommandResources);
 		destroySyncResources(m_Context.getDevice(), m_SyncResources);
-		destroyTemporaryFramebuffers();
 
 		m_Context.m_Device.destroySwapchainKHR(m_swapchain.getSwapchain());
 		m_Context.m_Instance.destroySurfaceKHR(m_swapchain.getSurface());
@@ -144,6 +113,7 @@ namespace vkcv
 		);
 		
 		if (acquireResult != vk::Result::eSuccess) {
+			std::cerr << vk::to_string(acquireResult) << std::endl;
 			return Result::ERROR;
 		}
 		
@@ -151,37 +121,33 @@ namespace vkcv
 		return Result::SUCCESS;
 	}
 
-	void Core::destroyTemporaryFramebuffers() {
-		for (const vk::Framebuffer f : m_TemporaryFramebuffers) {
-			m_Context.getDevice().destroyFramebuffer(f);
-		}
-		m_TemporaryFramebuffers.clear();
-	}
-
 	void Core::beginFrame() {
+		if (m_swapchain.shouldUpdateSwapchain()) {
+			m_Context.getDevice().waitIdle();
+			
+			for (auto image : m_swapchainImageViews)
+				m_Context.m_Device.destroyImageView(image);
+			
+			m_swapchain.updateSwapchain(m_Context, m_window);
+			m_swapchainImageViews = createImageViews(m_Context, m_swapchain);
+		}
+		
     	if (acquireSwapchainImage() != Result::SUCCESS) {
-    		return;
+    		std::cerr << "Acquire failed!" << std::endl;
+    		
+    		m_currentSwapchainImageIndex = std::numeric_limits<uint32_t>::max();
     	}
-		m_Context.getDevice().waitIdle();	// FIMXE: this is a sin against graphics programming, but its getting late - Alex
-		destroyTemporaryFramebuffers();
-	}
-	
-	vk::Framebuffer createFramebuffer(const vk::Device device, const vk::RenderPass& renderpass,
-									  const int width, const int height, const std::vector<vk::ImageView>& attachments) {
-		const vk::FramebufferCreateFlags flags = {};
-		const vk::FramebufferCreateInfo createInfo(flags, renderpass, attachments.size(), attachments.data(), width, height, 1);
-		return device.createFramebuffer(createInfo);
+		
+		m_Context.getDevice().waitIdle(); // TODO: this is a sin against graphics programming, but its getting late - Alex
 	}
 
 	void Core::renderMesh(
-		const PassHandle						renderpassHandle, 
-		const PipelineHandle					pipelineHandle, 
-		const uint32_t 							width,
-		const uint32_t							height,
-		const size_t							pushConstantSize, 
+		const PassHandle						&renderpassHandle,
+		const PipelineHandle					&pipelineHandle,
+		const size_t							pushConstantSize,
 		const void								*pushConstantData,
 		const std::vector<VertexBufferBinding>& vertexBufferBindings, 
-		const BufferHandle						indexBuffer, 
+		const BufferHandle						&indexBuffer,
 		const size_t							indexCount,
 		const vkcv::ResourcesHandle				resourceHandle,
 		const size_t							resourceDescriptorSetIndex
@@ -190,6 +156,11 @@ namespace vkcv
 		if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) {
 			return;
 		}
+		
+		const vk::Extent2D& extent = m_swapchain.getExtent();
+		
+		const uint32_t width = extent.width;
+		const uint32_t height = extent.height;
 
 		const vk::RenderPass renderpass = m_PassManager->getVkPass(renderpassHandle);
 		const PassConfig passConfig = m_PassManager->getPassConfig(renderpassHandle);
@@ -212,6 +183,7 @@ namespace vkcv
 		const vk::ImageView imageView	= m_swapchainImageViews[m_currentSwapchainImageIndex];
 		const vk::Pipeline pipeline		= m_PipelineManager->getVkPipeline(pipelineHandle);
         const vk::PipelineLayout pipelineLayout = m_PipelineManager->getVkPipelineLayout(pipelineHandle);
+        const vkcv::PipelineConfig pipelineConfig = m_PipelineManager->getPipelineConfig(pipelineHandle);
 		const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height));
 		const vk::Buffer vulkanIndexBuffer	= m_BufferManager->getBuffer(indexBuffer);
 
@@ -222,15 +194,25 @@ namespace vkcv
 			attachments.push_back(m_ImageManager->getVulkanImageView(m_DepthImage));
 		}
 		
-		const vk::Framebuffer framebuffer = createFramebuffer(
-				m_Context.getDevice(),
-				renderpass,
-				width,
-				height,
-				attachments
-		);
-		
-		m_TemporaryFramebuffers.push_back(framebuffer);
+		vk::Framebuffer framebuffer = nullptr;
+        const vk::FramebufferCreateInfo createInfo({},
+                                                   renderpass,
+                                                   static_cast<uint32_t>(attachments.size()),
+                                                   attachments.data(),
+                                                   width,
+                                                   height,
+                                                   1);
+        if(m_Context.m_Device.createFramebuffer(&createInfo, nullptr, &framebuffer) != vk::Result::eSuccess)
+        {
+            std::cout << "FAILED TO CREATE TEMPORARY FRAMEBUFFER!" << std::endl;
+            return;
+        }
+
+        vk::Viewport dynamicViewport(0.0f, 0.0f,
+                                     static_cast<float>(width), static_cast<float>(height),
+                                     0.0f, 1.0f);
+
+        vk::Rect2D dynamicScissor({0, 0}, {width, height});
 
 		auto &bufferManager = m_BufferManager;
 
@@ -238,48 +220,61 @@ namespace vkcv
 		submitInfo.queueType = QueueType::Graphics;
 		submitInfo.signalSemaphores = { m_SyncResources.renderFinished };
 
-		submitCommands(submitInfo, [&](const vk::CommandBuffer& cmdBuffer) {
-			std::vector<vk::ClearValue> clearValues;
-			
-			for (const auto& attachment : passConfig.attachments) {
-				if (attachment.load_operation == AttachmentOperation::CLEAR) {
-					float clear = 0.0f;
-					
-					if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) {
-						clear = 1.0f;
-					}
-					
-					clearValues.emplace_back(std::array<float, 4>{
-							clear,
-							clear,
-							clear,
-							1.f
-					});
-				}
-			}
-
-			const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, clearValues.size(), clearValues.data());
-			const vk::SubpassContents subpassContents = {};
-			cmdBuffer.beginRenderPass(beginInfo, subpassContents, {});
-
-			cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {});
+		auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) {
+            std::vector<vk::ClearValue> clearValues;
+
+            for (const auto& attachment : passConfig.attachments) {
+                if (attachment.load_operation == AttachmentOperation::CLEAR) {
+                    float clear = 0.0f;
+
+                    if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) {
+                        clear = 1.0f;
+                    }
+
+                    clearValues.emplace_back(std::array<float, 4>{
+                            clear,
+                            clear,
+                            clear,
+                            1.f
+                    });
+                }
+            }
+
+            const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, clearValues.size(), clearValues.data());
+            const vk::SubpassContents subpassContents = {};
+            cmdBuffer.beginRenderPass(beginInfo, subpassContents, {});
+
+            cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {});
+
+            if(pipelineConfig.m_Height == UINT32_MAX && pipelineConfig.m_Width == UINT32_MAX)
+            {
+                cmdBuffer.setViewport(0, 1, &dynamicViewport);
+                cmdBuffer.setScissor(0, 1, &dynamicScissor);
+            }
+
+            for (uint32_t i = 0; i < vertexBufferBindings.size(); i++) {
+                const auto &vertexBinding = vertexBufferBindings[i];
+                const auto vertexBuffer = bufferManager->getBuffer(vertexBinding.buffer);
+                cmdBuffer.bindVertexBuffers(i, (vertexBuffer), (vertexBinding.offset));
+            }
+
+            if (resourceHandle) {
+                const vk::DescriptorSet descriptorSet = m_DescriptorManager->getDescriptorSet(resourceHandle, resourceDescriptorSetIndex);
+                cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr);
+            }
+
+            cmdBuffer.bindIndexBuffer(vulkanIndexBuffer, 0, vk::IndexType::eUint16);	//FIXME: choose proper size
+            cmdBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData);
+            cmdBuffer.drawIndexed(indexCount, 1, 0, 0, {});
+            cmdBuffer.endRenderPass();
+        };
+
+        auto finishFunction = [&]()
+        {
+            m_Context.m_Device.destroy(framebuffer);
+        };
 
-			for (uint32_t i = 0; i < vertexBufferBindings.size(); i++) {
-				const auto &vertexBinding = vertexBufferBindings[i];
-				const auto vertexBuffer = bufferManager->getBuffer(vertexBinding.buffer);
-				cmdBuffer.bindVertexBuffers(i, (vertexBuffer), (vertexBinding.offset));
-			}
-			
-			if (resourceHandle) {
-				const vk::DescriptorSet descriptorSet = m_DescriptorManager->getDescriptorSet(resourceHandle, resourceDescriptorSetIndex);
-				cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr);
-			}
-			
-			cmdBuffer.bindIndexBuffer(vulkanIndexBuffer, 0, vk::IndexType::eUint16);	//FIXME: choose proper size
-			cmdBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData);
-			cmdBuffer.drawIndexed(indexCount, 1, 0, 0, {});
-			cmdBuffer.endRenderPass();
-		}, nullptr);
+		submitCommands(submitInfo, submitFunction, finishFunction);
 	}
 
 	void Core::endFrame() {
@@ -288,8 +283,7 @@ namespace vkcv
 		}
   
 		const auto swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
-		const vk::Image presentImage = swapchainImages[m_currentSwapchainImageIndex];
-		
+
 		const auto& queueManager = m_Context.getQueueManager();
 		std::array<vk::Semaphore, 2> waitSemaphores{ 
 			m_SyncResources.renderFinished, 
@@ -309,13 +303,8 @@ namespace vkcv
 	}
 
 	vk::Format Core::getSwapchainImageFormat() {
-		return m_swapchain.getSurfaceFormat().format;
+		return m_swapchain.getSwapchainFormat();
 	}
-
-    void Core::recreateSwapchain(int width, int height) {
-        /* boilerplate for #34 */
-        std::cout << "Resized to : " << width << " , " << height << std::endl;
-    }
 	
 	void Core::submitCommands(const SubmitInfo &submitInfo, const RecordCommandFunction& record, const FinishCommandFunction& finish)
 	{
@@ -369,4 +358,33 @@ namespace vkcv
 	vk::DescriptorSetLayout Core::getDescriptorSetLayout(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.getSwapchainFormat(),
+                    componentMapping,
+                    subResourceRange
+            );
+
+            imageViews.push_back(context.getDevice().createImageView(imageViewCreateInfo));
+        }
+        return imageViews;
+    }
 }
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index 1b866c05d4a12c9bf28d08178438cb3a1ff70a3c..16b08b7a5127769a19b7e0abe47b61f58406bafe 100644
--- a/src/vkcv/PipelineManager.cpp
+++ b/src/vkcv/PipelineManager.cpp
@@ -5,7 +5,8 @@ namespace vkcv
 
     PipelineManager::PipelineManager(vk::Device device) noexcept :
     m_Device{device},
-    m_Pipelines{}
+    m_Pipelines{},
+    m_Configs{}
     {}
 
     PipelineManager::~PipelineManager() noexcept
@@ -94,8 +95,8 @@ namespace vkcv
 			//FIXME: hoping that order is the same and compatible: add explicit mapping and validation
 			const VertexAttribute attribute = config.m_vertexAttributes[i];
 
-            vertexAttributeDescriptions.push_back({location, binding, vertexFormatToVulkanFormat(attachment.format), 0});
-			vertexBindingDescriptions.push_back(vk::VertexInputBindingDescription(
+            vertexAttributeDescriptions.emplace_back(location, binding, vertexFormatToVulkanFormat(attachment.format), 0);
+			vertexBindingDescriptions.emplace_back(vk::VertexInputBindingDescription(
 				binding,
 				attribute.stride + getFormatSize(attachment.format),
 				vk::VertexInputRate::eVertex));
@@ -211,8 +212,19 @@ namespace vkcv
 				break;
 			}
 		}
-	
-		// graphics pipeline create
+
+		std::vector<vk::DynamicState> dynamicStates = {};
+		if(config.m_Width == UINT32_MAX && config.m_Height == UINT32_MAX)
+        {
+		    dynamicStates.push_back(vk::DynamicState::eViewport);
+		    dynamicStates.push_back(vk::DynamicState::eScissor);
+        }
+
+        vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo({},
+                                                            static_cast<uint32_t>(dynamicStates.size()),
+                                                            dynamicStates.data());
+
+        // graphics pipeline create
         std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = { pipelineVertexShaderStageInfo, pipelineFragmentShaderStageInfo };
         const vk::GraphicsPipelineCreateInfo graphicsPipelineCreateInfo(
                 {},
@@ -226,7 +238,7 @@ namespace vkcv
                 &pipelineMultisampleStateCreateInfo,
 				p_depthStencilCreateInfo,
                 &pipelineColorBlendStateCreateInfo,
-                nullptr,
+                &dynamicStateCreateInfo,
                 vkPipelineLayout,
                 pass,
                 0,
@@ -247,6 +259,7 @@ namespace vkcv
         
         const uint64_t id = m_Pipelines.size();
         m_Pipelines.push_back({ vkPipeline, vkPipelineLayout });
+        m_Configs.push_back(config);
         return PipelineHandle(id, [&](uint64_t id) { destroyPipelineById(id); });
     }
 
@@ -293,5 +306,11 @@ namespace vkcv
 			pipeline.m_layout = nullptr;
 		}
     }
-    
+
+    const PipelineConfig &PipelineManager::getPipelineConfig(const PipelineHandle &handle) const
+    {
+        const uint64_t id = handle.getId();
+        return m_Configs.at(id);
+    }
+
 }
\ No newline at end of file
diff --git a/src/vkcv/PipelineManager.hpp b/src/vkcv/PipelineManager.hpp
index 950df0be2d8edf3037c93e8522215bfa740d033d..e243151f7248c07fa0287bb2eaf698e5080f7f61 100644
--- a/src/vkcv/PipelineManager.hpp
+++ b/src/vkcv/PipelineManager.hpp
@@ -18,6 +18,7 @@ namespace vkcv
     	
         vk::Device m_Device;
         std::vector<Pipeline> m_Pipelines;
+        std::vector<PipelineConfig> m_Configs;
         
         void destroyPipelineById(uint64_t id);
         
@@ -36,7 +37,11 @@ namespace vkcv
 
         [[nodiscard]]
         vk::Pipeline getVkPipeline(const PipelineHandle &handle) const;
+
         [[nodiscard]]
         vk::PipelineLayout getVkPipelineLayout(const PipelineHandle &handle) const;
+
+        [[nodiscard]]
+        const PipelineConfig &getPipelineConfig(const PipelineHandle &handle) const;
     };
 }
diff --git a/src/vkcv/Surface.cpp b/src/vkcv/Surface.cpp
deleted file mode 100644
index 29b6c646dc212cba2cc31f32dca5c4fcc023cd03..0000000000000000000000000000000000000000
--- a/src/vkcv/Surface.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "Surface.hpp"
-
-#define GLFW_INCLUDE_VULKAN
-#include <GLFW/glfw3.h>
-
-namespace vkcv {
-	/**
-	* creates surface and checks availability
-	* @param window current window for the surface
-	* @param instance Vulkan-Instance
-	* @param physicalDevice Vulkan-PhysicalDevice
-	* @return created surface
-	*/
-	vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice) {
-		//create surface
-		VkSurfaceKHR surface;
-		if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
-			throw std::runtime_error("failed to create a window surface!");
-		}
-		vk::Bool32 surfaceSupport = false;
-		if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
-			throw std::runtime_error("surface is not supported by the device!");
-		}
-
-		return vk::SurfaceKHR(surface);
-	}
-}
diff --git a/src/vkcv/Surface.hpp b/src/vkcv/Surface.hpp
deleted file mode 100644
index 74aafeba821334767ac5e13cd33e1d9674e12f5b..0000000000000000000000000000000000000000
--- a/src/vkcv/Surface.hpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-#include <vulkan/vulkan.hpp>
-
-struct GLFWwindow;
-
-namespace vkcv {	
-	vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice);
-}
\ No newline at end of file
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index 3483ae37e718453a99d56d31e025433acb7f4422..39c310de60db2c3678749f142c926a26ac127b58 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -1,29 +1,70 @@
 #include <vkcv/SwapChain.hpp>
+#include <utility>
 
-namespace vkcv {
+#define GLFW_INCLUDE_VULKAN
+#include <GLFW/glfw3.h>
 
-    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)
+namespace vkcv
+{
+    /**
+    * creates surface and checks availability
+    * @param window current window for the surface
+    * @param instance Vulkan-Instance
+    * @param physicalDevice Vulkan-PhysicalDevice
+    * @return created surface
+    */
+    vk::SurfaceKHR createSurface(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice) {
+        //create surface
+        VkSurfaceKHR surface;
+        if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
+            throw std::runtime_error("failed to create a window surface!");
+        }
+        vk::Bool32 surfaceSupport = false;
+        if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
+            throw std::runtime_error("surface is not supported by the device!");
+        }
+
+        return vk::SurfaceKHR(surface);
+    }
+
+    SwapChain::SwapChain(const Surface &surface,
+                         vk::SwapchainKHR swapchain,
+                         vk::Format format,
+                         vk::ColorSpaceKHR colorSpace,
+                         vk::PresentModeKHR presentMode,
+                         uint32_t imageCount,
+						 vk::Extent2D extent) noexcept :
+    m_Surface(surface),
+    m_Swapchain(swapchain),
+    m_SwapchainFormat(format),
+    m_SwapchainColorSpace(colorSpace),
+    m_SwapchainPresentMode(presentMode),
+    m_SwapchainImageCount(imageCount),
+	m_Extent(extent),
+    m_RecreationRequired(false)
     {}
+    
+    SwapChain::SwapChain(const SwapChain &other) :
+			m_Surface(other.m_Surface),
+			m_Swapchain(other.m_Swapchain),
+			m_SwapchainFormat(other.m_SwapchainFormat),
+			m_SwapchainColorSpace(other.m_SwapchainColorSpace),
+			m_SwapchainPresentMode(other.m_SwapchainPresentMode),
+			m_SwapchainImageCount(other.m_SwapchainImageCount),
+			m_Extent(other.m_Extent),
+			m_RecreationRequired(other.m_RecreationRequired.load())
+	{}
 
     const vk::SwapchainKHR& SwapChain::getSwapchain() const {
-        return m_swapchain;
+        return m_Swapchain;
     }
 
-    /**
-     * gets surface of the swapchain
-     * @return current surface
-     */
-    vk::SurfaceKHR SwapChain::getSurface() {
-        return m_surface;
+    vk::SurfaceKHR SwapChain::getSurface() const {
+        return m_Surface.handle;
     }
 
-    /**
-     * gets the surface of the swapchain
-     * @return chosen format
-     */
-    vk::SurfaceFormatKHR SwapChain::getSurfaceFormat(){
-        return m_format;
+    vk::Format SwapChain::getSwapchainFormat() const{
+        return m_SwapchainFormat;
     }
 
     /**
@@ -33,7 +74,7 @@ namespace vkcv {
      * @param window of the current application
      * @return chosen Extent for the surface
      */
-    vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window){
+    vk::Extent2D chooseExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window){
         vk::SurfaceCapabilitiesKHR surfaceCapabilities;
         if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){
             throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface.");
@@ -43,15 +84,10 @@ namespace vkcv {
                 static_cast<uint32_t>(window.getWidth()),
                 static_cast<uint32_t>(window.getHeight())
         };
+        
         extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width));
         extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height));
 
-        if (extent2D.width > surfaceCapabilities.maxImageExtent.width ||
-            extent2D.width < surfaceCapabilities.minImageExtent.width ||
-            extent2D.height > surfaceCapabilities.maxImageExtent.height ||
-            extent2D.height < surfaceCapabilities.minImageExtent.height) {
-            std::printf("Surface size not matching. Resizing to allowed value.");
-        }
         return extent2D;
     }
 
@@ -61,7 +97,7 @@ namespace vkcv {
      * @param surface of the swapchain
      * @return available Format
      */
-    vk::SurfaceFormatKHR chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
+    vk::SurfaceFormatKHR chooseSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
         uint32_t formatCount;
         physicalDevice.getSurfaceFormatsKHR(surface, &formatCount, nullptr);
         std::vector<vk::SurfaceFormatKHR> availableFormats(formatCount);
@@ -126,23 +162,29 @@ namespace vkcv {
      * @param context that keeps instance, physicalDevice and a device.
      * @return swapchain
      */
-    SwapChain SwapChain::create(const Window &window, const Context &context, const vk::SurfaceKHR surface) {
+    SwapChain SwapChain::create(const Window &window, const Context &context) {
         const vk::Instance& instance = context.getInstance();
         const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
         const vk::Device& device = context.getDevice();
 
-        vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window);
-        vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface);
-        vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface);
-        uint32_t imageCount = chooseImageCount(physicalDevice, surface);
+        Surface surface;
+        surface.handle       = createSurface(window.getWindow(), instance, physicalDevice);
+        surface.formats      = physicalDevice.getSurfaceFormatsKHR(surface.handle);
+        surface.capabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface.handle);
+        surface.presentModes = physicalDevice.getSurfacePresentModesKHR(surface.handle);
+
+        vk::Extent2D chosenExtent = chooseExtent(physicalDevice, surface.handle, window);
+        vk::SurfaceFormatKHR chosenSurfaceFormat = chooseSurfaceFormat(physicalDevice, surface.handle);
+        vk::PresentModeKHR chosenPresentMode = choosePresentMode(physicalDevice, surface.handle);
+        uint32_t chosenImageCount = chooseImageCount(physicalDevice, surface.handle);
 
         vk::SwapchainCreateInfoKHR swapchainCreateInfo(
                 vk::SwapchainCreateFlagsKHR(),  //flags
-                surface,    // surface
-                imageCount,  // minImageCount TODO: how many do we need for our application?? "must be less than or equal to the value returned in maxImageCount" -> 3 for Triple Buffering, else 2 for Double Buffering (should be the standard)
-                surfaceFormat.format,   // imageFormat
-                surfaceFormat.colorSpace,   // imageColorSpace
-                extent2D,   // imageExtent
+                surface.handle,    // surface
+                chosenImageCount,  // minImageCount TODO: how many do we need for our application?? "must be less than or equal to the value returned in maxImageCount" -> 3 for Triple Buffering, else 2 for Double Buffering (should be the standard)
+                chosenSurfaceFormat.format,   // imageFormat
+                chosenSurfaceFormat.colorSpace,   // imageColorSpace
+                chosenExtent,   // imageExtent
                 1,  // imageArrayLayers TODO: should we only allow non-stereoscopic applications? yes -> 1, no -> ? "must be greater than 0, less or equal to maxImageArrayLayers"
                 vk::ImageUsageFlagBits::eColorAttachment,  // imageUsage TODO: what attachments? only color? depth?
                 vk::SharingMode::eExclusive,    // imageSharingMode TODO: which sharing mode? "VK_SHARING_MODE_EXCLUSIV access exclusive to a single queue family, better performance", "VK_SHARING_MODE_CONCURRENT access from multiple queues"
@@ -150,22 +192,71 @@ namespace vkcv {
                 nullptr,    // pQueueFamilyIndices, the pointer to an array of queue family indices having access to the images(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
                 vk::SurfaceTransformFlagBitsKHR::eIdentity, // preTransform, transformations applied onto the image before display
                 vk::CompositeAlphaFlagBitsKHR::eOpaque, // compositeAlpha, TODO: how to handle transparent pixels? do we need transparency? If no -> opaque
-                presentMode,    // presentMode
+                chosenPresentMode,    // presentMode
                 true,   // clipped
                 nullptr // oldSwapchain
         );
 
         vk::SwapchainKHR swapchain = device.createSwapchainKHR(swapchainCreateInfo);
 
-        return SwapChain(surface, swapchain, surfaceFormat, imageCount);
+        return SwapChain(surface,
+                         swapchain,
+                         chosenSurfaceFormat.format,
+                         chosenSurfaceFormat.colorSpace,
+                         chosenPresentMode,
+                         chosenImageCount,
+						 chosenExtent);
+    }
+    
+    bool SwapChain::shouldUpdateSwapchain() const {
+    	return m_RecreationRequired;
+    }
+    
+    void SwapChain::updateSwapchain(const Context &context, const Window &window) {
+    	if (!m_RecreationRequired.exchange(false))
+    		return;
+    	
+		vk::SwapchainKHR oldSwapchain = m_Swapchain;
+		vk::Extent2D extent2D = chooseExtent(context.getPhysicalDevice(), m_Surface.handle, window);
+	
+		vk::SwapchainCreateInfoKHR swapchainCreateInfo(
+				vk::SwapchainCreateFlagsKHR(),
+				m_Surface.handle,
+				m_SwapchainImageCount,
+				m_SwapchainFormat,
+				m_SwapchainColorSpace,
+				extent2D,
+				1,
+				vk::ImageUsageFlagBits::eColorAttachment,
+				vk::SharingMode::eExclusive,
+				0,
+				nullptr,
+				vk::SurfaceTransformFlagBitsKHR::eIdentity,
+				vk::CompositeAlphaFlagBitsKHR::eOpaque,
+				m_SwapchainPresentMode,
+				true,
+				oldSwapchain
+		);
+	
+		m_Swapchain = context.getDevice().createSwapchainKHR(swapchainCreateInfo);
+		context.getDevice().destroySwapchainKHR(oldSwapchain);
+		
+		m_Extent = extent2D;
     }
 
+    void SwapChain::recreateSwapchain() {
+		m_RecreationRequired = true;
+    }
+    
+    const vk::Extent2D& SwapChain::getExtent() const {
+    	return m_Extent;
+    }
 
     SwapChain::~SwapChain() {
         // needs to be destroyed by creator
     }
 
 	uint32_t SwapChain::getImageCount() {
-		return m_ImageCount;
+		return m_SwapchainImageCount;
 	}
 }