diff --git a/.gitignore b/.gitignore
index 7ee4ff1903e902c4715c6e2b0c3e784ed5755aaf..76a0fa8e507371af6821b220a402666e79c340a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,8 @@ cmake-build-release/
 
 # GUI configuration files
 imgui.ini
+
+# Generated source and header files for shaders
+*.hxx
+*.cxx
+
diff --git a/config/Libraries.cmake b/config/Libraries.cmake
index b0684091d59b659c712aeacecd91e200351e0117..88e94f8dcd7d02eccca3b5f4ca384f2536bb4e5a 100644
--- a/config/Libraries.cmake
+++ b/config/Libraries.cmake
@@ -34,6 +34,9 @@ endif ()
 # fix dependencies for different Linux distros (looking at you Ubuntu)
 include(${vkcv_config_ext}/CheckLibraries.cmake)
 
+# add custom function to include a file like a shader as string
+include(${vkcv_config_ext}/IncludeShader.cmake)
+
 # cleanup of compiler definitions aka preprocessor variables
 if (vkcv_definitions)
     list(REMOVE_DUPLICATES vkcv_definitions)
diff --git a/config/Sources.cmake b/config/Sources.cmake
index 7ae106e2538c66179ab1ed50408551c43b785bc3..41cd0c20f2106dc02700d9b23227f3e6c34a057a 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -6,6 +6,9 @@ set(vkcv_sources
 
 		${vkcv_include}/vkcv/Core.hpp
 		${vkcv_source}/vkcv/Core.cpp
+		
+		${vkcv_include}/vkcv/File.hpp
+		${vkcv_source}/vkcv/File.cpp
 
 		${vkcv_include}/vkcv/PassConfig.hpp
 		${vkcv_source}/vkcv/PassConfig.cpp
diff --git a/config/ext/IncludeShader.cmake b/config/ext/IncludeShader.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2b2e7f96b57974c2b409bfd60b40ab883d50a71b
--- /dev/null
+++ b/config/ext/IncludeShader.cmake
@@ -0,0 +1,41 @@
+
+function(include_shader shader include_dir source_dir)
+	get_filename_component(filename ${shader} NAME)
+	file(SIZE ${shader} filesize)
+	
+	string(TOUPPER ${filename} varname)
+	string(REPLACE "." "_" varname ${varname})
+	
+	set(shader_header "")
+	string(APPEND shader_header "#pragma once\n")
+	string(APPEND shader_header "extern unsigned char ${varname} [${filesize}]\;\n")
+	string(APPEND shader_header "extern unsigned int ${varname}_LEN\;\n")
+	string(APPEND shader_header "const std::string ${varname}_SHADER (reinterpret_cast<const char*>(${varname}), ${varname}_LEN)\;")
+	
+	set(shader_source "")
+	string(APPEND shader_source "unsigned char ${varname}[] = {")
+	
+	math(EXPR max_fileoffset "${filesize} - 1" OUTPUT_FORMAT DECIMAL)
+	
+	foreach(fileoffset RANGE ${max_fileoffset})
+		file(READ ${shader} shader_source_byte OFFSET ${fileoffset} LIMIT 1 HEX)
+		
+		math(EXPR offset_modulo "${fileoffset} % 12" OUTPUT_FORMAT DECIMAL)
+		
+		if (${offset_modulo} EQUAL 0)
+			string(APPEND shader_source "\n  ")
+		endif()
+		
+		if (${fileoffset} LESS ${max_fileoffset})
+			string(APPEND shader_source "0x${shader_source_byte}, ")
+		else()
+			string(APPEND shader_source "0x${shader_source_byte}\n")
+		endif()
+	endforeach()
+	
+	string(APPEND shader_source "}\n")
+	string(APPEND shader_source "unsigned int ${varname}_LEN = ${filesize}\;")
+	
+	file(WRITE ${include_dir}/${filename}.hxx ${shader_header})
+	file(WRITE ${source_dir}/${filename}.cxx ${shader_source})
+endfunction()
diff --git a/include/vkcv/File.hpp b/include/vkcv/File.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3ac44dec36bd08056b73112ab65a74ec38851e6
--- /dev/null
+++ b/include/vkcv/File.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <filesystem>
+
+namespace vkcv {
+	
+	std::filesystem::path generateTemporaryFilePath();
+	
+}
diff --git a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
index 846df8b071ff7831e896fbfe63e4999502afb870..5f177e93214e868275e7c1f9d094041a303adb82 100644
--- a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
+++ b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp
@@ -5,6 +5,7 @@
 #include <glslang/SPIRV/GlslangToSpv.h>
 #include <glslang/StandAlone/DirStackFileIncluder.h>
 
+#include <vkcv/File.hpp>
 #include <vkcv/Logger.hpp>
 
 namespace vkcv::shader {
@@ -263,7 +264,7 @@ namespace vkcv::shader {
 		std::vector<uint32_t> spirv;
 		glslang::GlslangToSpv(*intermediate, spirv);
 		
-		const std::filesystem::path tmp_path (std::tmpnam(nullptr));
+		const std::filesystem::path tmp_path = generateTemporaryFilePath();
 		
 		if (!writeSpirvCode(tmp_path, spirv)) {
 			vkcv_log(LogLevel::ERROR, "Spir-V could not be written to disk");
diff --git a/modules/upscaling/CMakeLists.txt b/modules/upscaling/CMakeLists.txt
index 92a4798fbb38a5aee17404dd9e1ce2994a0acab4..f4d34bad781ab1a78b1714e34361613188bd771a 100644
--- a/modules/upscaling/CMakeLists.txt
+++ b/modules/upscaling/CMakeLists.txt
@@ -23,6 +23,9 @@ set(vkcv_upscaling_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_upscaling_lib})
 # Check and load GLSLANG
 include(config/FidelityFX_FSR.cmake)
 
+# link the required libraries to the module
+target_link_libraries(vkcv_upscaling ${vkcv_upscaling_libraries} vkcv vkcv_shader_compiler)
+
 # including headers of dependencies and the VkCV framework
 target_include_directories(vkcv_upscaling SYSTEM BEFORE PRIVATE ${vkcv_upscaling_includes} ${vkcv_include} ${vkcv_shader_compiler_include})
 
diff --git a/modules/upscaling/config/FidelityFX_FSR.cmake b/modules/upscaling/config/FidelityFX_FSR.cmake
index 0d34f9513b18262d0c753559c8b5a57169558754..37a6321c16600f1bc811c6cee7fe6d8cfe8085ca 100644
--- a/modules/upscaling/config/FidelityFX_FSR.cmake
+++ b/modules/upscaling/config/FidelityFX_FSR.cmake
@@ -1,5 +1,8 @@
 
 if (EXISTS "${vkcv_upscaling_lib_path}/FidelityFX-FSR")
+	include_shader(${vkcv_upscaling_lib_path}/FidelityFX-FSR/ffx-fsr/ffx_a.h ${vkcv_upscaling_include} ${vkcv_upscaling_source})
+	include_shader(${vkcv_upscaling_lib_path}/FidelityFX-FSR/ffx-fsr/ffx_fsr1.h ${vkcv_upscaling_include} ${vkcv_upscaling_source})
+	
 	list(APPEND vkcv_upscaling_includes ${vkcv_upscaling_lib}/FidelityFX-FSR/ffx-fsr)
 else()
 	message(WARNING "FidelityFX-FSR is required..! Update the submodules!")
diff --git a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
index e8c236cfe02dd60758380ef4e2cbaed51d198369..cb2dc6c18af4dd90b881a4fcc2d74a3792b6309c 100644
--- a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
+++ b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp
@@ -1,7 +1,16 @@
 #pragma once
 
-namespace vkcv::upscaling {
-
+#include <vkcv/ShaderProgram.hpp>
 
+namespace vkcv::upscaling {
+	
+	class FSRUpscaling {
+	private:
+		ShaderProgram m_program;
+	
+	public:
+		FSRUpscaling();
+		
+	};
 
 }
diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
index ad9dbd3c644c12c995fd42d56bb25d7121171d5c..9434f017a4c94878547a0a2dc48ebb384f5bc9ec 100644
--- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
+++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp
@@ -8,6 +8,23 @@
 #include <ffx_a.h>
 #include <ffx_fsr1.h>
 
+#include "ffx_a.h.hxx"
+#include "ffx_fsr1.h.hxx"
+
+#include <vkcv/shader/GLSLCompiler.hpp>
+
 namespace vkcv::upscaling {
+	
+	static void setupTemporaryShaderDirectory() {
+	
+	}
+	
+	FSRUpscaling::FSRUpscaling() {
+		vkcv::shader::GLSLCompiler compiler;
+		compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"),
+						 [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
+			m_program.addShader(shaderStage, path);
+		});
+	}
 
 }
diff --git a/src/vkcv/File.cpp b/src/vkcv/File.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..52c6d3d309b0f66c897b3f1d4936bfdc485dda74
--- /dev/null
+++ b/src/vkcv/File.cpp
@@ -0,0 +1,28 @@
+
+#include "vkcv/File.hpp"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+namespace vkcv {
+	
+	std::filesystem::path generateTemporaryFilePath() {
+		std::error_code code;
+		auto tmp = std::filesystem::temp_directory_path(code);
+		
+		if (tmp.empty()) {
+			tmp = std::filesystem::current_path();
+		}
+		
+		char name [16] = "vkcv_tmp_XXXXXX";
+		int fd = mkstemp(name);
+		
+		if (fd == -1) {
+			return "";
+		}
+		
+		close(fd);
+		return tmp / name;
+	}
+	
+}