diff --git a/config/Libraries.cmake b/config/Libraries.cmake
index fb4677e6e13698dcae87657290463253f40d1c1e..f78ca1f5df4ef40683b7948473dbc6a506f67cd1 100644
--- a/config/Libraries.cmake
+++ b/config/Libraries.cmake
@@ -10,11 +10,12 @@ if(NOT WIN32)
 	
 	if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
 		list(APPEND vkcv_flags -Xpreprocessor)
+	else()
+		# optimization for loading times
+		list(APPEND vkcv_flags -fopenmp)
 	endif()
 	
-	# optimization for loading times
 	list(APPEND vkcv_flags -pthread)
-	list(APPEND vkcv_flags -fopenmp)
 endif()
 
 # add custom functions to check for git submodules
diff --git a/include/vkcv/Downsampler.hpp b/include/vkcv/Downsampler.hpp
index 1617c721fa0976711f9e553ae3214222999c516c..82416fd2c957f58de8e7ba9092dfc3d9d677e56a 100644
--- a/include/vkcv/Downsampler.hpp
+++ b/include/vkcv/Downsampler.hpp
@@ -24,7 +24,7 @@ namespace vkcv {
 		 */
 		explicit Downsampler(Core &core);
 
-		~Downsampler() = default;
+		virtual ~Downsampler() = default;
 
 		/**
 		 * @brief Record the commands of the given downsampler instance to
diff --git a/modules/upscaling/CMakeLists.txt b/modules/upscaling/CMakeLists.txt
index 4578f97fd654a5cad0e66549fbc944ab16051b11..0a5ee06dd695a3f3596c238bc0ef4383c011cf24 100644
--- a/modules/upscaling/CMakeLists.txt
+++ b/modules/upscaling/CMakeLists.txt
@@ -38,6 +38,9 @@ include(config/FidelityFX_FSR2.cmake)
 # Check and load NVIDIAImageScaling
 include(config/NVIDIAImageScaling.cmake)
 
+# Add compile definitions depending on the build context of the module
+add_compile_definitions(${vkcv_upscaling_definitions})
+
 # adding source files to the project
 add_library(vkcv_upscaling ${vkcv_build_attribute} ${vkcv_upscaling_sources})
 
diff --git a/modules/upscaling/config/FidelityFX_FSR2.cmake b/modules/upscaling/config/FidelityFX_FSR2.cmake
index 3dbc43e6721ae139f9ceb76c9f05b6fbce010fba..95cf8a74282e794e93f41f96f02b046496bdf521 100644
--- a/modules/upscaling/config/FidelityFX_FSR2.cmake
+++ b/modules/upscaling/config/FidelityFX_FSR2.cmake
@@ -1,14 +1,30 @@
 
-use_git_submodule("${vkcv_upscaling_lib_path}/FidelityFX-FSR2" ffx_fsr2_status)
+set(vkcv_upscaling_fsr2_override ON)
 
-if (${ffx_fsr2_status})
-	set(FFX_FSR2_API_DX12 OFF CACHE INTERNAL "")
-	set(FFX_FSR2_API_VK ON CACHE INTERNAL "")
+if (WIN32)
+	set(vkcv_upscaling_fsr2_override OFF)
+else()
+	find_program(wine_program "wine")
 	
-	add_subdirectory(${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api)
-	
-	list(APPEND vkcv_upscaling_libraries ${FFX_FSR2_API} ${FFX_FSR2_API_VK})
+	if (EXISTS ${xxd_program})
+		set(vkcv_upscaling_fsr2_override OFF)
+	endif()
+endif()
+
+if (vkcv_upscaling_fsr2_override)
+	list(APPEND vkcv_upscaling_definitions VKCV_OVERRIDE_FSR2_WITH_FSR1=1)
+else()
+	use_git_submodule("${vkcv_upscaling_lib_path}/FidelityFX-FSR2" ffx_fsr2_status)
 	
-	list(APPEND vkcv_upscaling_includes ${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api)
-	list(APPEND vkcv_upscaling_includes ${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api/vk)
-endif ()
+	if (${ffx_fsr2_status})
+		set(FFX_FSR2_API_DX12 OFF CACHE INTERNAL "")
+		set(FFX_FSR2_API_VK ON CACHE INTERNAL "")
+		
+		add_subdirectory(${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api)
+		
+		list(APPEND vkcv_upscaling_libraries ${FFX_FSR2_API} ${FFX_FSR2_API_VK})
+		
+		list(APPEND vkcv_upscaling_includes ${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api)
+		list(APPEND vkcv_upscaling_includes ${vkcv_upscaling_lib}/FidelityFX-FSR2/src/ffx-fsr2-api/vk)
+	endif ()
+endif()
\ No newline at end of file
diff --git a/modules/upscaling/include/vkcv/upscaling/FSR2Upscaling.hpp b/modules/upscaling/include/vkcv/upscaling/FSR2Upscaling.hpp
index 95dbd9a804ab6ec6a0232cafac7bc43dcf8b5d6d..447f16ed6bc3f84862c252db2103c7734659b5d2 100644
--- a/modules/upscaling/include/vkcv/upscaling/FSR2Upscaling.hpp
+++ b/modules/upscaling/include/vkcv/upscaling/FSR2Upscaling.hpp
@@ -2,10 +2,15 @@
 
 #include "Upscaling.hpp"
 
+#include <memory>
 #include <vector>
 
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+#include "FSRUpscaling.hpp"
+#else
 struct FfxFsr2ContextDescription;
 struct FfxFsr2Context;
+#endif
 
 namespace vkcv::upscaling {
 
@@ -78,6 +83,9 @@ namespace vkcv::upscaling {
      */
 	class FSR2Upscaling : public Upscaling {
 	private:
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+		std::unique_ptr<FSRUpscaling> m_fsr1;
+#else
 		std::vector<char> m_scratchBuffer;
 		
 		std::unique_ptr<FfxFsr2ContextDescription> m_description;
@@ -118,6 +126,7 @@ namespace vkcv::upscaling {
 							   uint32_t renderHeight);
 		
 		void destroyFSR2Context();
+#endif
 		
 	public:
 		/**
diff --git a/modules/upscaling/src/vkcv/upscaling/FSR2Upscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSR2Upscaling.cpp
index 5c85b566be530c989dc8ad4dce967275bff64802..e523a11db3512f30ab1f7df421da9b7838a1ea5b 100644
--- a/modules/upscaling/src/vkcv/upscaling/FSR2Upscaling.cpp
+++ b/modules/upscaling/src/vkcv/upscaling/FSR2Upscaling.cpp
@@ -3,6 +3,7 @@
 
 #include <cmath>
 
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 #ifndef _MSVC_LANG
 #define FFX_GCC
 #endif
@@ -13,6 +14,7 @@
 #ifdef FFX_GCC
 #undef FFX_GCC
 #endif
+#endif
 
 namespace vkcv::upscaling {
 	
@@ -63,6 +65,7 @@ namespace vkcv::upscaling {
 		}
 	}
 	
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 	void FSR2Upscaling::createFSR2Context(uint32_t displayWidth,
 									 uint32_t displayHeight,
 									 uint32_t renderWidth,
@@ -149,20 +152,29 @@ namespace vkcv::upscaling {
 		m_scratchBuffer.clear();
 		m_description->callbacks.scratchBuffer = nullptr;
 	}
+#else
+	FSR2Upscaling::FSR2Upscaling(vkcv::Core &core) :
+	Upscaling(core), m_fsr1(new FSRUpscaling(m_core)) {}
+	
+	FSR2Upscaling::~FSR2Upscaling() {}
+#endif
 	
 	void FSR2Upscaling::update(float deltaTime, bool reset) {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		if (reset) {
 			m_frameIndex = 0;
 		}
 		
 		m_frameDeltaTime = deltaTime;
 		m_reset = reset;
+#endif
 	}
 	
 	void FSR2Upscaling::calcJitterOffset(uint32_t renderWidth,
 										 uint32_t renderHeight,
 										 float &jitterOffsetX,
 										 float &jitterOffsetY) const {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		const int32_t phaseCount = ffxFsr2GetJitterPhaseCount(
 				static_cast<int32_t>(renderWidth),
 				static_cast<int32_t>(renderHeight)
@@ -179,23 +191,34 @@ namespace vkcv::upscaling {
 		
 		jitterOffsetX *= +2.0f / renderWidth;
 		jitterOffsetY *= -2.0f / renderHeight;
+#else
+		jitterOffsetX = 0.0f;
+		jitterOffsetY = 0.0f;
+#endif
 	}
 	
 	void FSR2Upscaling::bindDepthBuffer(const ImageHandle &depthInput) {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		m_depth = depthInput;
+#endif
 	}
 	
 	void FSR2Upscaling::bindVelocityBuffer(const ImageHandle &velocityInput) {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		m_velocity = velocityInput;
+#endif
 	}
 	
 	void FSR2Upscaling::recordUpscaling(const CommandStreamHandle &cmdStream,
 										const ImageHandle &colorInput,
 										const ImageHandle &output) {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		m_core.recordBeginDebugLabel(cmdStream, "vkcv::upscaling::FSR2Upscaling", {
 				1.0f, 0.05f, 0.05f, 1.0f
 		});
 		
+		m_core.prepareImageForSampling(cmdStream, output);
+		
 		FfxFsr2DispatchDescription dispatch;
 		memset(&dispatch, 0, sizeof(dispatch));
 		
@@ -328,28 +351,49 @@ namespace vkcv::upscaling {
 		
 		m_core.updateImageLayoutManual(output, vk::ImageLayout::eGeneral);
 		m_core.recordEndDebugLabel(cmdStream);
+#else
+		m_fsr1->recordUpscaling(cmdStream, colorInput, output);
+#endif
 	}
 	
 	void FSR2Upscaling::setCamera(float near, float far, float fov) {
+#ifndef VKCV_OVERRIDE_FSR2_WITH_FSR1
 		m_near = near;
 		m_far = far;
 		m_fov = fov;
+#endif
 	}
 	
 	bool FSR2Upscaling::isHdrEnabled() const {
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+		return m_fsr1->isHdrEnabled();
+#else
 		return m_hdr;
+#endif
 	}
 	
 	void FSR2Upscaling::setHdrEnabled(bool enabled) {
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+		m_fsr1->setHdrEnabled(true);
+#else
 		m_hdr = enabled;
+#endif
 	}
 	
 	float FSR2Upscaling::getSharpness() const {
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+		return m_fsr1->getSharpness();
+#else
 		return m_sharpness;
+#endif
 	}
 	
 	void FSR2Upscaling::setSharpness(float sharpness) {
+#ifdef VKCV_OVERRIDE_FSR2_WITH_FSR1
+		m_fsr1->setSharpness(sharpness);
+#else
 		m_sharpness = (sharpness < 0.0f ? 0.0f : (sharpness > 1.0f ? 1.0f : sharpness));
+#endif
 	}
 	
 }
\ No newline at end of file
diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp
index f871338af2670087eaf851901790631a4711f680..18a6b9ad5d807758c5123d45bf9408364f89fa6d 100644
--- a/projects/indirect_dispatch/src/App.cpp
+++ b/projects/indirect_dispatch/src/App.cpp
@@ -384,11 +384,10 @@ void App::run() {
 		
 		// upscaling
 		m_core.prepareImageForSampling(cmdStream, m_renderTargets.colorBuffer);
+		m_core.prepareImageForStorage(cmdStream, m_renderTargets.finalBuffer);
 		
 		switch (upscalingMode) {
 			case 0:
-				m_core.prepareImageForStorage(cmdStream, m_renderTargets.finalBuffer);
-				
 				fsr1.recordUpscaling(
 						cmdStream,
 						m_renderTargets.colorBuffer,
@@ -399,8 +398,6 @@ void App::run() {
 				m_core.prepareImageForSampling(cmdStream, m_renderTargets.depthBuffer);
 				m_core.prepareImageForSampling(cmdStream, m_renderTargets.motionBuffer);
 				
-				m_core.prepareImageForSampling(cmdStream, m_renderTargets.finalBuffer);
-				
 				fsr2.recordUpscaling(
 						cmdStream,
 						m_renderTargets.colorBuffer,
@@ -408,8 +405,6 @@ void App::run() {
 				);
 				break;
 			case 2:
-				m_core.prepareImageForStorage(cmdStream, m_renderTargets.finalBuffer);
-				
 				nis.recordUpscaling(
 						cmdStream,
 						m_renderTargets.colorBuffer,
@@ -417,8 +412,6 @@ void App::run() {
 				);
 				break;
 			case 3:
-				m_core.prepareImageForStorage(cmdStream, m_renderTargets.finalBuffer);
-				
 				bilinear.recordUpscaling(
 						cmdStream,
 						m_renderTargets.colorBuffer,
diff --git a/src/vkcv/Handles.cpp b/src/vkcv/Handles.cpp
index ef90ffd9a928fa348847bdc07acf25b58d4b6ac0..64ab3080f5e6a649fa4fb0d8f772872713cb0140 100644
--- a/src/vkcv/Handles.cpp
+++ b/src/vkcv/Handles.cpp
@@ -30,6 +30,7 @@ namespace vkcv {
 	Handle::Handle(Handle &&other) noexcept :
 		m_id(other.m_id), m_rc(other.m_rc), m_destroy(other.m_destroy) {
 		other.m_rc = nullptr;
+		other.m_destroy = nullptr;
 	}
 
 	Handle &Handle::operator=(const Handle &other) {
@@ -54,6 +55,7 @@ namespace vkcv {
 		m_destroy = other.m_destroy;
 
 		other.m_rc = nullptr;
+		other.m_destroy = nullptr;
 
 		return *this;
 	}