diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 4f9468a2a738502d8459e4e136f566fa507d8b6e..af186fe222fc17ac7bc676e4f2c9ed8f82e04c00 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -62,9 +62,6 @@ namespace vkcv
         Context m_Context;
 
         SwapChain                       m_swapchain;
-        std::vector<vk::ImageView>      m_swapchainImageViews;
-        std::vector<vk::Image>          m_swapchainImages;
-		std::vector<vk::ImageLayout>    m_swapchainImageLayouts;
         const Window&                   m_window;
 
         std::unique_ptr<PassManager>            m_PassManager;
@@ -81,9 +78,7 @@ namespace vkcv
 
         std::function<void(int, int)> e_resizeHandle;
 
-        static std::vector<vk::ImageView> createImageViews( Context &context, SwapChain& swapChain);
-
-		void recordSwapchainImageLayoutTransition(vk::CommandBuffer cmdBuffer, vk::ImageLayout newLayout);
+        static std::vector<vk::ImageView> createSwapchainImageViews( Context &context, SwapChain& swapChain);
 
     public:
         /**
diff --git a/projects/voxelization/resources/shaders/gammaCorrection.comp b/projects/voxelization/resources/shaders/gammaCorrection.comp
new file mode 100644
index 0000000000000000000000000000000000000000..b9886ef275bb37caf1089d4362d45d6d56a5a060
--- /dev/null
+++ b/projects/voxelization/resources/shaders/gammaCorrection.comp
@@ -0,0 +1,16 @@
+#version 440
+
+layout(set=0, binding=0, r8) uniform image2D sceneImage;
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+void main(){
+
+    if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(sceneImage)))){
+        return;
+    }
+    ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
+    vec3 linearColor = imageLoad(sceneImage, uv).rgb;
+    vec3 gammaCorrected = pow(linearColor, vec3(1.f / 2.2f));
+    imageStore(sceneImage, uv, vec4(gammaCorrected, 0.f));
+}
\ No newline at end of file
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index fd2a0bc687c5c38eae47fc0538af309c66884ac3..f832dd3d023f1daf66b5090d30b5986e56f16688 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -357,6 +357,16 @@ int main(int argc, const char** argv) {
 	resetVoxelWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, voxelImage.getHandle()) };
 	core.writeDescriptorSet(resetVoxelDescriptorSet, resetVoxelWrites);
 
+	// gamma correction compute shader
+	vkcv::ShaderProgram gammaCorrectionProgram;
+	compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/gammaCorrection.comp", 
+		[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+		gammaCorrectionProgram.addShader(shaderStage, path);
+	});
+	vkcv::DescriptorSetHandle gammaCorrectionDescriptorSet = core.createDescriptorSet(gammaCorrectionProgram.getReflectedDescriptors()[0]);
+	vkcv::PipelineHandle gammaCorrectionPipeline = core.createComputePipeline(gammaCorrectionProgram, 
+		{ core.getDescriptorSet(gammaCorrectionDescriptorSet).layout });
+
 	// prepare descriptor sets for drawcalls
 	std::vector<vkcv::Image> sceneImages;
 	std::vector<vkcv::DescriptorSetHandle> descriptorSets;
@@ -418,7 +428,12 @@ int main(int argc, const char** argv) {
 
 		auto end = std::chrono::system_clock::now();
 		auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
-		
+
+		// update descriptor sets which use swapchain image
+		vkcv::DescriptorWrites gammaCorrectionDescriptorWrites;
+		gammaCorrectionDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, swapchainInput) };
+		core.writeDescriptorSet(gammaCorrectionDescriptorSet, gammaCorrectionDescriptorWrites);
+
 		start = end;
 		cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
 
@@ -559,6 +574,22 @@ int main(int argc, const char** argv) {
 				renderTargets);
 		}
 
+		const uint32_t gammaCorrectionLocalGroupSize = 8;
+		const uint32_t gammaCorrectionDispatchCount[3] = {
+			glm::ceil(windowWidth / float(gammaCorrectionLocalGroupSize)),
+			glm::ceil(windowHeight / float(gammaCorrectionLocalGroupSize)),
+			1
+		};
+
+		core.prepareImageForStorage(cmdStream, swapchainInput);
+
+		core.recordComputeDispatchToCmdStream(
+			cmdStream, 
+			gammaCorrectionPipeline, 
+			gammaCorrectionDispatchCount,
+			{ vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gammaCorrectionDescriptorSet).vulkanHandle) },
+			vkcv::PushConstantData(nullptr, 0));
+
 		// present and end
 		core.prepareSwapchainImageForPresent(cmdStream);
 		core.submitCommandStream(cmdStream);
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index e76a4111678ee5e9d506708a845c2a134d668d3a..1531bc2b77fb24db407e1f31d3bac200fe4c1bd3 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -37,8 +37,7 @@ namespace vkcv
 
         SwapChain swapChain = SwapChain::create(window, context);
 
-        std::vector<vk::ImageView> imageViews;
-        imageViews = createImageViews( context, swapChain);
+		 std::vector<vk::ImageView> swapchainImageViews = createSwapchainImageViews( context, swapChain);
 
         const auto& queueManager = context.getQueueManager();
         
@@ -47,7 +46,7 @@ namespace vkcv
 		const auto						commandResources		= createCommandResources(context.getDevice(), queueFamilySet);
 		const auto						defaultSyncResources	= createSyncResources(context.getDevice());
 
-        return Core(std::move(context) , window, swapChain, imageViews, commandResources, defaultSyncResources);
+        return Core(std::move(context) , window, swapChain, swapchainImageViews, commandResources, defaultSyncResources);
     }
 
     const Context &Core::getContext() const
@@ -55,12 +54,11 @@ namespace vkcv
         return m_Context;
     }
 
-    Core::Core(Context &&context, Window &window, const SwapChain& swapChain,  std::vector<vk::ImageView> imageViews,
+    Core::Core(Context &&context, Window &window, const SwapChain& swapChain,  std::vector<vk::ImageView> swapchainImageViews,
         const CommandResources& commandResources, const SyncResources& syncResources) noexcept :
             m_Context(std::move(context)),
             m_window(window),
             m_swapchain(swapChain),
-            m_swapchainImageViews(imageViews),
             m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
             m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
             m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)),
@@ -81,15 +79,17 @@ namespace vkcv
 			m_swapchain.signalSwapchainRecreation();
 		});
 
-		m_swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
-		m_swapchainImageLayouts.resize(m_swapchainImages.size(), vk::ImageLayout::eUndefined);
+		const auto swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
+		m_ImageManager->setSwapchainImages(
+			swapchainImages, 
+			swapchainImageViews, 
+			swapChain.getExtent().width,
+			swapChain.getExtent().height,
+			swapChain.getSwapchainFormat());
 	}
 
 	Core::~Core() noexcept {
 		m_Context.getDevice().waitIdle();
-		for (auto image : m_swapchainImageViews) {
-			m_Context.m_Device.destroyImageView(image);
-		}
 
 		destroyCommandResources(m_Context.getDevice(), m_CommandResources);
 		destroySyncResources(m_Context.getDevice(), m_SyncResources);
@@ -145,16 +145,12 @@ namespace vkcv
 	bool Core::beginFrame(uint32_t& width, uint32_t& height) {
 		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);
-			m_swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
+			const auto swapchainViews = createSwapchainImageViews(m_Context, m_swapchain);
+			const auto swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain());
 
-			m_swapchainImageLayouts.clear();
-			m_swapchainImageLayouts.resize(m_swapchainImages.size(), vk::ImageLayout::eUndefined);
+			m_ImageManager->setSwapchainImages(swapchainImages, swapchainViews, width, height, m_swapchain.getSwapchainFormat());
 		}
 		
     	if (acquireSwapchainImage() != Result::SUCCESS) {
@@ -170,6 +166,8 @@ namespace vkcv
 		width = extent.width;
 		height = extent.height;
 		
+		m_ImageManager->setCurrentSwapchainImageIndex(m_currentSwapchainImageIndex);
+
 		return (m_currentSwapchainImageIndex != std::numeric_limits<uint32_t>::max());
 	}
 
@@ -212,23 +210,16 @@ namespace vkcv
 		const vk::PipelineLayout pipelineLayout = m_PipelineManager->getVkPipelineLayout(pipelineHandle);
 		const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height));
 
-		const vk::ImageView swapchainImageView = m_swapchainImageViews[m_currentSwapchainImageIndex];
-
 		std::vector<vk::ImageView> attachmentsViews;
 		for (const ImageHandle handle : renderTargets) {
 			vk::ImageView targetHandle;
 			const auto cmdBuffer = m_CommandStreamManager->getStreamCommandBuffer(cmdStreamHandle);
-			if (handle.isSwapchainImage()) {
-				recordSwapchainImageLayoutTransition(cmdBuffer, vk::ImageLayout::eColorAttachmentOptimal);
-				targetHandle = m_swapchainImageViews[m_currentSwapchainImageIndex];
-			}
-			else {
-				targetHandle = m_ImageManager->getVulkanImageView(handle);
-				const bool isDepthImage = isDepthFormat(m_ImageManager->getImageFormat(handle));
-				const vk::ImageLayout targetLayout = 
-					isDepthImage ? vk::ImageLayout::eDepthStencilAttachmentOptimal : vk::ImageLayout::eColorAttachmentOptimal;
-				m_ImageManager->recordImageLayoutTransition(handle, targetLayout, cmdBuffer);
-			}
+
+			targetHandle = m_ImageManager->getVulkanImageView(handle);
+			const bool isDepthImage = isDepthFormat(m_ImageManager->getImageFormat(handle));
+			const vk::ImageLayout targetLayout = 
+				isDepthImage ? vk::ImageLayout::eDepthStencilAttachmentOptimal : vk::ImageLayout::eColorAttachmentOptimal;
+			m_ImageManager->recordImageLayoutTransition(handle, targetLayout, cmdBuffer);
 			attachmentsViews.push_back(targetHandle);
 		}
 		
@@ -458,7 +449,7 @@ namespace vkcv
 		return m_DescriptorManager->getDescriptorSet(handle);
 	}
 
-    std::vector<vk::ImageView> Core::createImageViews( Context &context, SwapChain& swapChain){
+    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() );
@@ -486,20 +477,11 @@ namespace vkcv
         return imageViews;
     }
 
-	void Core::recordSwapchainImageLayoutTransition(vk::CommandBuffer cmdBuffer, vk::ImageLayout newLayout) {
-		auto& imageLayout = m_swapchainImageLayouts[m_currentSwapchainImageIndex];
-		const auto transitionBarrier = createSwapchainImageLayoutTransitionBarrier(
-			m_swapchainImages[m_currentSwapchainImageIndex],
-			imageLayout,
-			newLayout);
-		recordImageBarrier(cmdBuffer, transitionBarrier);
-		imageLayout = newLayout;
-	}
-
-	void Core::prepareSwapchainImageForPresent(const CommandStreamHandle handle) {
-		m_CommandStreamManager->recordCommandsToStream(handle, [&](vk::CommandBuffer cmdBuffer) {
-			recordSwapchainImageLayoutTransition(cmdBuffer, vk::ImageLayout::ePresentSrcKHR);
-		});
+	void Core::prepareSwapchainImageForPresent(const CommandStreamHandle cmdStream) {
+		auto swapchainHandle = ImageHandle::createSwapchainImageHandle();
+		recordCommandsToStream(cmdStream, [swapchainHandle, this](const vk::CommandBuffer cmdBuffer) {
+			m_ImageManager->recordImageLayoutTransition(swapchainHandle, vk::ImageLayout::ePresentSrcKHR, cmdBuffer);
+		}, nullptr);
 	}
 
 	void Core::prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image) {
diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp
index 2f713bbd07688fa63d80f3d9e11b614f1d15da39..fff98dc5b56d0ad085c6ebc68acf7230223d9cd1 100644
--- a/src/vkcv/ImageManager.cpp
+++ b/src/vkcv/ImageManager.cpp
@@ -69,6 +69,8 @@ namespace vkcv {
 		for (uint64_t id = 0; id < m_images.size(); id++) {
 			destroyImageById(id);
 		}
+		for (const auto swapchainImage : m_swapchainImages)
+			m_core->getContext().getDevice().destroy(swapchainImage.m_view);
 	}
 	
 	bool isDepthImageFormat(vk::Format format) {
@@ -210,8 +212,12 @@ namespace vkcv {
 	}
 	
 	vk::Image ImageManager::getVulkanImage(const ImageHandle &handle) const {
+
+		if (handle.isSwapchainImage()) {
+			m_swapchainImages[m_currentSwapchainInputImage].m_handle;
+		}
+
 		const uint64_t id = handle.getId();
-		
 		if (id >= m_images.size()) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return nullptr;
@@ -223,8 +229,13 @@ namespace vkcv {
 	}
 	
 	vk::DeviceMemory ImageManager::getVulkanDeviceMemory(const ImageHandle &handle) const {
+
+		if (handle.isSwapchainImage()) {
+			vkcv_log(LogLevel::ERROR, "Swapchain image has no memory");
+			return nullptr;
+		}
+
 		const uint64_t id = handle.getId();
-		
 		if (id >= m_images.size()) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return nullptr;
@@ -236,27 +247,31 @@ namespace vkcv {
 	}
 	
 	vk::ImageView ImageManager::getVulkanImageView(const ImageHandle &handle) const {
-		const uint64_t id = handle.getId();
 		
+		if (handle.isSwapchainImage()) {
+			return m_swapchainImages[m_currentSwapchainInputImage].m_view;
+		}
+
+		const uint64_t id = handle.getId();
 		if (id >= m_images.size()) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return nullptr;
 		}
 		
-		auto& image = m_images[id];
-		
-		return image.m_view;
+		return m_images[id].m_view;
 	}
 	
 	void ImageManager::switchImageLayoutImmediate(const ImageHandle& handle, vk::ImageLayout newLayout) {
-		const uint64_t id = handle.getId();
+		uint64_t id = handle.getId();
 		
-		if (id >= m_images.size()) {
+		const bool isSwapchainImage = handle.isSwapchainImage();
+
+		if (id >= m_images.size() && !isSwapchainImage) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return;
 		}
 		
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		const auto transitionBarrier = createImageLayoutTransitionBarrier(image, newLayout);
 		
 		SubmitInfo submitInfo;
@@ -285,13 +300,14 @@ namespace vkcv {
 		vk::CommandBuffer cmdBuffer) {
 
 		const uint64_t id = handle.getId();
+		const bool isSwapchainImage = handle.isSwapchainImage();
 
-		if (id >= m_images.size()) {
+		if (id >= m_images.size() && !isSwapchainImage) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return;
 		}
 
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		const auto transitionBarrier = createImageLayoutTransitionBarrier(image, newLayout);
 		recordImageBarrier(cmdBuffer, transitionBarrier);
 		image.m_layout = newLayout;
@@ -302,13 +318,14 @@ namespace vkcv {
 		vk::CommandBuffer cmdBuffer) {
 
 		const uint64_t id = handle.getId();
+		const bool isSwapchainImage = handle.isSwapchainImage();
 
-		if (id >= m_images.size()) {
+		if (id >= m_images.size() && !isSwapchainImage) {
 			std::cerr << "Error: ImageManager::recordImageMemoryBarrier invalid handle" << std::endl;
 			return;
 		}
 
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		const auto transitionBarrier = createImageLayoutTransitionBarrier(image, image.m_layout);
 		recordImageBarrier(cmdBuffer, transitionBarrier);
 	}
@@ -329,6 +346,11 @@ namespace vkcv {
 	{
 		const uint64_t id = handle.getId();
 		
+		if (handle.isSwapchainImage()) {
+			vkcv_log(LogLevel::ERROR, "Swapchain image cannot be filled");
+			return;
+		}
+
 		if (id >= m_images.size()) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return;
@@ -402,39 +424,42 @@ namespace vkcv {
 	
 	uint32_t ImageManager::getImageWidth(const ImageHandle &handle) const {
 		const uint64_t id = handle.getId();
-		
-		if (id >= m_images.size()) {
+		const bool isSwapchainImage = handle.isSwapchainImage();
+
+		if (id >= m_images.size() && !isSwapchainImage) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return 0;
 		}
 		
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		
 		return image.m_width;
 	}
 	
 	uint32_t ImageManager::getImageHeight(const ImageHandle &handle) const {
 		const uint64_t id = handle.getId();
+		const bool isSwapchainImage = handle.isSwapchainImage();
 		
-		if (id >= m_images.size()) {
+		if (id >= m_images.size() && !isSwapchainImage) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return 0;
 		}
 		
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		
 		return image.m_height;
 	}
 	
 	uint32_t ImageManager::getImageDepth(const ImageHandle &handle) const {
 		const uint64_t id = handle.getId();
-		
-		if (id >= m_images.size()) {
+		const bool isSwapchainImage = handle.isSwapchainImage();
+
+		if (id >= m_images.size() && !isSwapchainImage) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return 0;
 		}
 		
-		auto& image = m_images[id];
+		auto& image = isSwapchainImage ? m_swapchainImages[m_currentSwapchainInputImage] : m_images[id];
 		
 		return image.m_depth;
 	}
@@ -469,13 +494,32 @@ namespace vkcv {
 	vk::Format ImageManager::getImageFormat(const ImageHandle& handle) const {
 
 		const uint64_t id = handle.getId();
+		const bool isSwapchainFormat = handle.isSwapchainImage();
 
-		if (id >= m_images.size()) {
+		if (id >= m_images.size() && !isSwapchainFormat) {
 			vkcv_log(LogLevel::ERROR, "Invalid handle");
 			return vk::Format::eUndefined;
 		}
 
-		return m_images[id].m_format;
+		return isSwapchainFormat ? m_swapchainImages[m_currentSwapchainInputImage].m_format : m_images[id].m_format;
+	}
+
+	void ImageManager::setCurrentSwapchainImageIndex(int index) {
+		m_currentSwapchainInputImage = index;
+	}
+
+	void ImageManager::setSwapchainImages(const std::vector<vk::Image>& images, std::vector<vk::ImageView> views, 
+		uint32_t width, uint32_t height, vk::Format format) {
+
+		// destroy old views
+		for (auto image : m_swapchainImages)
+			m_core->getContext().getDevice().destroyImageView(image.m_view);
+
+		assert(images.size() == views.size());
+		m_swapchainImages.clear();
+		for (int i = 0; i < images.size(); i++) {
+			m_swapchainImages.push_back(Image(images[i], nullptr, views[i], width, height, 1, format, 1, 1));
+		}
 	}
 
 }
\ No newline at end of file
diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp
index 6b3bea33f902db94567cdefa3d3c90ea78054876..7bb4cc7ef7951a8677c19f589bd7948dbcedb25d 100644
--- a/src/vkcv/ImageManager.hpp
+++ b/src/vkcv/ImageManager.hpp
@@ -41,6 +41,8 @@ namespace vkcv {
 				vk::Format          format,
 				uint32_t            layers,
 				uint32_t            levels);
+
+			Image();
 		};
 	private:
 		
@@ -48,6 +50,8 @@ namespace vkcv {
 		BufferManager& m_bufferManager;
 		
 		std::vector<Image> m_images;
+		std::vector<Image> m_swapchainImages;
+		int m_currentSwapchainInputImage;
 		
 		ImageManager(BufferManager& bufferManager) noexcept;
 		
@@ -103,5 +107,10 @@ namespace vkcv {
 		
 		[[nodiscard]]
 		vk::Format getImageFormat(const ImageHandle& handle) const;
+
+		void setCurrentSwapchainImageIndex(int index);
+		void setSwapchainImages(const std::vector<vk::Image>& images, std::vector<vk::ImageView> views,
+			uint32_t width, uint32_t height, vk::Format format);
+
 	};
 }
\ No newline at end of file
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index b787536b66cfd802dfd435a773a584c875eeb391..a6e1f2a141be71f7f296ad66a5a64341f370b379 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -186,7 +186,7 @@ namespace vkcv
                 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::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage,  // 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"
                 0,  // queueFamilyIndexCount, the number of queue families having access to the image(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
                 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
@@ -227,7 +227,7 @@ namespace vkcv
 				m_SwapchainColorSpace,
 				extent2D,
 				1,
-				vk::ImageUsageFlagBits::eColorAttachment,
+				vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage,
 				vk::SharingMode::eExclusive,
 				0,
 				nullptr,