diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 2ad76e8f78c5870f6b582a1970caac306026166f..99db6780d6d6752c4b5256a1ad4d7eb9f47bdcdc 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -9,13 +9,10 @@
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Mesh";
 
-	uint32_t windowWidth = 800;
-	uint32_t windowHeight = 600;
-
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
+		800,
+		600,
 		true
 	);
 	
@@ -153,8 +150,15 @@ int main(int argc, const char** argv) {
 	setWrites.samplerWrites			= { vkcv::SamplerDescriptorWrite(1, sampler) };
 
 	core.writeDescriptorSet(descriptorSet, setWrites);
-
-	vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle();
+	
+	auto swapchainExtent = core.getSwapchain().getExtent();
+	
+	vkcv::ImageHandle depthBuffer = core.createImage(
+			vk::Format::eD32Sfloat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false
+	).getHandle();
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 
@@ -181,11 +185,11 @@ int main(int argc, const char** argv) {
 			continue;
 		}
 		
-		if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) {
+		if ((swapchainWidth != swapchainExtent.width) || ((swapchainHeight != swapchainExtent.height))) {
 			depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle();
 			
-			windowWidth = swapchainWidth;
-			windowHeight = swapchainHeight;
+			swapchainExtent.width = swapchainWidth;
+			swapchainExtent.height = swapchainHeight;
 		}
   
 		auto end = std::chrono::system_clock::now();
diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp
index 21f8deacdb3f81fcd29c5f14cbe74485f36d13cd..1fc4e40d9c1b0ccdb6d34c9e52da49c4e759f666 100644
--- a/projects/first_scene/src/main.cpp
+++ b/projects/first_scene/src/main.cpp
@@ -10,13 +10,10 @@
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Scene";
 
-	uint32_t windowWidth = 800;
-	uint32_t windowHeight = 600;
-
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
+		800,
+		600,
 		true
 	);
 
@@ -98,8 +95,14 @@ int main(int argc, const char** argv) {
 		std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
 		return EXIT_FAILURE;
 	}
+	
+	auto swapchainExtent = core.getSwapchain().getExtent();
 
-	vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle();
+	vkcv::ImageHandle depthBuffer = core.createImage(
+			vk::Format::eD32Sfloat,
+			swapchainExtent.width,
+			swapchainExtent.height
+	).getHandle();
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 	
@@ -115,11 +118,11 @@ int main(int argc, const char** argv) {
 			continue;
 		}
 		
-		if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) {
+		if ((swapchainWidth != swapchainExtent.width) || ((swapchainHeight != swapchainExtent.height))) {
 			depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle();
 			
-			windowWidth = swapchainWidth;
-			windowHeight = swapchainHeight;
+			swapchainExtent.width = swapchainWidth;
+			swapchainExtent.height = swapchainHeight;
 		}
   
 		auto end = std::chrono::system_clock::now();
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index d1d856b8863badef8a1b01f6277979cde019c4e0..1bfb2edca776eafac9a94422f87d0401e698fa82 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -7,13 +7,11 @@
 
 int main(int argc, const char** argv) {
 	const char* applicationName = "First Triangle";
-
-	const int windowWidth = 800;
-	const int windowHeight = 600;
+	
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
+		800,
+		600,
 		false
 	);
 	
@@ -60,11 +58,13 @@ int main(int argc, const char** argv) {
 					 [&triangleShaderProgram](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
 		triangleShaderProgram.addShader(shaderStage, path);
 	});
+	
+	const auto swapchainExtent = core.getSwapchain().getExtent();
 
 	const vkcv::PipelineConfig trianglePipelineDefinition {
 		triangleShaderProgram,
-		(uint32_t)windowWidth,
-		(uint32_t)windowHeight,
+		swapchainExtent.width,
+		swapchainExtent.height,
 		trianglePass,
 		{},
 		{},
diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp
index 15aaf527619b4fb06d89bccc78cffe843cc723b7..1080bc2a61efabac60d67bf65602ea2f12f8b860 100644
--- a/projects/mesh_shader/src/main.cpp
+++ b/projects/mesh_shader/src/main.cpp
@@ -78,12 +78,10 @@ CameraPlanes computeCameraPlanes(const vkcv::camera::Camera& camera) {
 int main(int argc, const char** argv) {
 	const char* applicationName = "Mesh shader";
 
-	const int windowWidth = 1280;
-	const int windowHeight = 720;
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
+		1280,
+		720,
 		false
 	);
 	
@@ -207,10 +205,12 @@ int main(int argc, const char** argv) {
 
 	vkcv::DescriptorSetHandle vertexShaderDescriptorSet = core.createDescriptorSet(bunnyShaderProgram.getReflectedDescriptors()[0]);
 
+	auto swapchainExtent = core.getSwapchain().getExtent();
+	
 	const vkcv::PipelineConfig bunnyPipelineDefinition {
 			bunnyShaderProgram,
-			(uint32_t)windowWidth,
-			(uint32_t)windowHeight,
+			swapchainExtent.width,
+			swapchainExtent.height,
 			renderPass,
 			{ bunnyLayout },
 			{ core.getDescriptorSet(vertexShaderDescriptorSet).layout },
@@ -259,8 +259,8 @@ int main(int argc, const char** argv) {
 
 	const vkcv::PipelineConfig meshShaderPipelineDefinition{
 		meshShaderProgram,
-		(uint32_t)windowWidth,
-		(uint32_t)windowHeight,
+		swapchainExtent.width,
+		swapchainExtent.height,
 		renderPass,
 		{meshShaderLayout},
 		{core.getDescriptorSet(meshShaderDescriptorSet).layout},
@@ -291,7 +291,12 @@ int main(int argc, const char** argv) {
 
     core.writeDescriptorSet( meshShaderDescriptorSet, meshShaderWrites);
 
-    vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle();
+    vkcv::ImageHandle depthBuffer = core.createImage(
+			vk::Format::eD32Sfloat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false
+	).getHandle();
 
     auto start = std::chrono::system_clock::now();
 
diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index 4de016aefd345a4231ea2dae0818b0839b163729..85c5cecccb7f868f2509f781adea39df9b5d737b 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -13,12 +13,10 @@
 int main(int argc, const char **argv) {
     const char *applicationName = "Particlesystem";
 
-    uint32_t windowWidth = 800;
-    uint32_t windowHeight = 600;
     vkcv::Window window = vkcv::Window::create(
             applicationName,
-            windowWidth,
-            windowHeight,
+            800,
+            600,
             true
     );
 
@@ -213,12 +211,23 @@ int main(int argc, const char **argv) {
     cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, -2.0f));
     cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f));
 
-    vkcv::ImageHandle colorBuffer = core.createImage(colorFormat, windowWidth, windowHeight, 1, false, true, true).getHandle();
-    BloomAndFlares bloomAndFlares(&core, colorFormat, windowWidth, windowHeight);
+	auto swapchainExtent = core.getSwapchain().getExtent();
+	
+    vkcv::ImageHandle colorBuffer = core.createImage(
+			colorFormat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false, true, true
+	).getHandle();
+    BloomAndFlares bloomAndFlares(&core, colorFormat, swapchainExtent.width, swapchainExtent.height);
     window.e_resize.add([&](int width, int height) {
-        windowWidth = width;
-        windowHeight = height;
-        colorBuffer = core.createImage(colorFormat, windowWidth, windowHeight, 1, false, true, true).getHandle();
+		swapchainExtent = core.getSwapchain().getExtent();
+        colorBuffer = core.createImage(
+				colorFormat,
+				swapchainExtent.width,
+				swapchainExtent.height,
+				1, false, true, true
+		).getHandle();
         bloomAndFlares.updateImageDimensions(width, height);
     });
 
@@ -300,8 +309,8 @@ int main(int argc, const char **argv) {
         core.writeDescriptorSet(tonemappingDescriptor, tonemappingDescriptorWrites);
 
         uint32_t tonemappingDispatchCount[3];
-        tonemappingDispatchCount[0] = std::ceil(windowWidth / 8.f);
-        tonemappingDispatchCount[1] = std::ceil(windowHeight / 8.f);
+        tonemappingDispatchCount[0] = std::ceil(swapchainExtent.width / 8.f);
+        tonemappingDispatchCount[1] = std::ceil(swapchainExtent.height / 8.f);
         tonemappingDispatchCount[2] = 1;
 
         core.recordComputeDispatchToCmdStream(
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index 3c23c7eabbbdc5d83d37bde79b43a2730b1f28b2..0a9916f15b99882b7a03cff3ed64dc7f4e92c9a6 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -17,21 +17,19 @@
 int main(int argc, const char** argv) {
 	const char* applicationName = "Voxelization";
 
-	uint32_t windowWidth = 1280;
-	uint32_t windowHeight = 720;
 	const vkcv::Multisampling   msaa        = vkcv::Multisampling::MSAA4X;
 	const bool                  usingMsaa   = msaa != vkcv::Multisampling::None;
 	
 	vkcv::Window window = vkcv::Window::create(
 		applicationName,
-		windowWidth,
-		windowHeight,
+		1280,
+		720,
 		true
 	);
 
 	bool     isFullscreen            = false;
-	uint32_t windowedWidthBackup     = windowWidth;
-	uint32_t windowedHeightBackup    = windowHeight;
+	uint32_t windowedWidthBackup     = window.getWidth();
+	uint32_t windowedHeightBackup    = window.getHeight();
 	int      windowedPosXBackup;
 	int      windowedPosYBackup;
     glfwGetWindowPos(window.getWindow(), &windowedPosXBackup, &windowedPosYBackup);
@@ -49,8 +47,8 @@ int main(int argc, const char** argv) {
 					GLFW_DONT_CARE);
 			}
 			else {
-				windowedWidthBackup     = windowWidth;
-				windowedHeightBackup    = windowHeight;
+				windowedWidthBackup     = window.getWidth();
+				windowedHeightBackup    = window.getHeight();
 
 				glfwGetWindowPos(window.getWindow(), &windowedPosXBackup, &windowedPosYBackup);
 
@@ -300,10 +298,12 @@ int main(int argc, const char** argv) {
 	// prepass pipeline
 	vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(std::vector<vkcv::DescriptorBinding>());
 
+	auto swapchainExtent = core.getSwapchain().getExtent();
+	
 	vkcv::PipelineConfig prepassPipelineConfig{
 		depthPrepassShader,
-		windowWidth,
-		windowHeight,
+		swapchainExtent.width,
+		swapchainExtent.height,
 		prepassPass,
 		vertexLayout,
 		{ 
@@ -320,8 +320,8 @@ int main(int argc, const char** argv) {
 	// forward pipeline
 	vkcv::PipelineConfig forwardPipelineConfig {
 		forwardProgram,
-		windowWidth,
-		windowHeight,
+		swapchainExtent.width,
+		swapchainExtent.height,
 		forwardPass,
 		vertexLayout,
 		{	
@@ -375,8 +375,8 @@ int main(int argc, const char** argv) {
 
 	vkcv::PipelineConfig skyPipeConfig;
 	skyPipeConfig.m_ShaderProgram       = skyShader;
-	skyPipeConfig.m_Width               = windowWidth;
-	skyPipeConfig.m_Height              = windowHeight;
+	skyPipeConfig.m_Width               = swapchainExtent.width;
+	skyPipeConfig.m_Height              = swapchainExtent.height;
 	skyPipeConfig.m_PassHandle          = skyPass;
 	skyPipeConfig.m_VertexLayout        = vkcv::VertexLayout();
 	skyPipeConfig.m_DescriptorLayouts   = {};
@@ -387,21 +387,47 @@ int main(int argc, const char** argv) {
 	vkcv::PipelineHandle skyPipe = core.createGraphicsPipeline(skyPipeConfig);
 
 	// render targets
-	vkcv::ImageHandle depthBuffer           = core.createImage(depthBufferFormat, windowWidth, windowHeight, 1, false, false, false, msaa).getHandle();
+	vkcv::ImageHandle depthBuffer           = core.createImage(
+			depthBufferFormat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false, false, false, msaa
+	).getHandle();
 
     const bool colorBufferRequiresStorage   = !usingMsaa;
-	vkcv::ImageHandle colorBuffer           = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, colorBufferRequiresStorage, true, msaa).getHandle();
+	vkcv::ImageHandle colorBuffer           = core.createImage(
+			colorBufferFormat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false, colorBufferRequiresStorage, true, msaa
+	).getHandle();
 
 	vkcv::ImageHandle resolvedColorBuffer;
 	if (usingMsaa) {
-		resolvedColorBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, true, true).getHandle();
+		resolvedColorBuffer = core.createImage(
+				colorBufferFormat,
+				swapchainExtent.width,
+				swapchainExtent.height,
+				1, false, true, true
+		).getHandle();
 	}
 	else {
 		resolvedColorBuffer = colorBuffer;
 	}
 	
-	vkcv::ImageHandle swapBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, true).getHandle();
-	vkcv::ImageHandle swapBuffer2 = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, true).getHandle();
+	vkcv::ImageHandle swapBuffer = core.createImage(
+			colorBufferFormat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false, true
+	).getHandle();
+	
+	vkcv::ImageHandle swapBuffer2 = core.createImage(
+			colorBufferFormat,
+			swapchainExtent.width,
+			swapchainExtent.height,
+			1, false, true
+	).getHandle();
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
 
@@ -513,11 +539,11 @@ int main(int argc, const char** argv) {
 		voxelSampler,
 		msaa);
 
-	BloomAndFlares bloomFlares(&core, colorBufferFormat, windowWidth, windowHeight);
+	BloomAndFlares bloomFlares(&core, colorBufferFormat, swapchainExtent.width, swapchainExtent.height);
 
 	window.e_key.add([&](int key, int scancode, int action, int mods) {
 		if (key == GLFW_KEY_R && action == GLFW_PRESS) {
-			bloomFlares = BloomAndFlares(&core, colorBufferFormat, windowWidth, windowHeight);
+			bloomFlares = BloomAndFlares(&core, colorBufferFormat, swapchainExtent.width, swapchainExtent.height);
 		}
 	});
 
@@ -547,7 +573,7 @@ int main(int argc, const char** argv) {
 	core.writeDescriptorSet(forwardShadingDescriptorSet, forwardDescriptorWrites);
 
 	vkcv::upscaling::FSRUpscaling upscaling (core);
-	uint32_t fsrWidth = windowWidth, fsrHeight = windowHeight;
+	uint32_t fsrWidth = swapchainExtent.width, fsrHeight = swapchainExtent.height;
 	
 	vkcv::upscaling::FSRQualityMode fsrMode = vkcv::upscaling::FSRQualityMode::NONE;
 	int fsrModeIndex = static_cast<int>(fsrMode);