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; + } + +}