From b34f66e38dca8a19a0cb5c3f1960fd6b8501525f Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Fri, 4 Jul 2025 13:32:41 +0200 Subject: [PATCH] extract shaders from Lossless.dll --- .gitattributes | 1 - .gitignore | 3 - CMakeLists.txt | 5 +- lsfg-vk-gen/CMakeLists.txt | 74 +++++++++- lsfg-vk-gen/include/context.hpp | 5 +- lsfg-vk-gen/include/core/shadermodule.hpp | 6 +- lsfg-vk-gen/include/pool/extract.hpp | 86 ++++++++++++ lsfg-vk-gen/include/pool/shaderpool.hpp | 48 +++++++ lsfg-vk-gen/include/shaderchains/alpha.hpp | 5 +- lsfg-vk-gen/include/shaderchains/beta.hpp | 5 +- lsfg-vk-gen/include/shaderchains/delta.hpp | 5 +- .../include/shaderchains/downsample.hpp | 5 +- lsfg-vk-gen/include/shaderchains/epsilon.hpp | 5 +- lsfg-vk-gen/include/shaderchains/extract.hpp | 5 +- lsfg-vk-gen/include/shaderchains/gamma.hpp | 5 +- lsfg-vk-gen/include/shaderchains/magic.hpp | 5 +- lsfg-vk-gen/include/shaderchains/merge.hpp | 5 +- lsfg-vk-gen/include/shaderchains/zeta.hpp | 5 +- lsfg-vk-gen/src/context.cpp | 24 ++-- lsfg-vk-gen/src/core/shadermodule.cpp | 18 +-- lsfg-vk-gen/src/lsfg.cpp | 19 ++- lsfg-vk-gen/src/pool/extract.cpp | 127 ++++++++++++++++++ lsfg-vk-gen/src/pool/shaderpool.cpp | 76 +++++++++++ lsfg-vk-gen/src/shaderchains/alpha.cpp | 11 +- lsfg-vk-gen/src/shaderchains/beta.cpp | 13 +- lsfg-vk-gen/src/shaderchains/delta.cpp | 11 +- lsfg-vk-gen/src/shaderchains/downsample.cpp | 5 +- lsfg-vk-gen/src/shaderchains/epsilon.cpp | 11 +- lsfg-vk-gen/src/shaderchains/extract.cpp | 5 +- lsfg-vk-gen/src/shaderchains/gamma.cpp | 15 ++- lsfg-vk-gen/src/shaderchains/magic.cpp | 5 +- lsfg-vk-gen/src/shaderchains/merge.cpp | 5 +- lsfg-vk-gen/src/shaderchains/zeta.cpp | 11 +- src/hooks.cpp | 7 +- 34 files changed, 544 insertions(+), 97 deletions(-) create mode 100644 lsfg-vk-gen/include/pool/extract.hpp create mode 100644 lsfg-vk-gen/include/pool/shaderpool.hpp create mode 100644 lsfg-vk-gen/src/pool/extract.cpp create mode 100644 lsfg-vk-gen/src/pool/shaderpool.cpp diff --git a/.gitattributes b/.gitattributes index 5f24d27..8d476d4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ *.cpp diff=cpp eol=lf *.hpp diff=cpp eol=lf *.md diff=markdown eol=lf -*.cs binary diff --git a/.gitignore b/.gitignore index 483bf36..eb55056 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,3 @@ /.clangd /.cache /.ccls - -# private resources -/rsc diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b21351..8199b0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,6 @@ cmake_minimum_required(VERSION 3.29) set(CMAKE_CXX_COMPILER clang++) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_CLANG_TIDY clang-tidy) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -30,6 +29,8 @@ target_include_directories(lsfg-vk PRIVATE include) target_link_libraries(lsfg-vk PRIVATE lsfg-vk-gen vulkan) +set_target_properties(lsfg-vk + PROPERTIES CXX_CLANG_TIDY clang-tidy) target_compile_options(lsfg-vk PRIVATE -Weverything # disable compat c++ flags @@ -47,4 +48,6 @@ target_compile_options(lsfg-vk PRIVATE -Wno-global-constructors # allow globals # required for vulkan -Wno-cast-function-type-strict + # required for dxvk (yeah don't worry about it) + -Qunused-arguments -Wl,--unresolved-symbols=ignore-all ) diff --git a/lsfg-vk-gen/CMakeLists.txt b/lsfg-vk-gen/CMakeLists.txt index b4a7c95..52ef4dd 100644 --- a/lsfg-vk-gen/CMakeLists.txt +++ b/lsfg-vk-gen/CMakeLists.txt @@ -1,3 +1,68 @@ +# dxvk subproject + +include(ExternalProject) + +ExternalProject_Add(dxvk_git + PREFIX ${CMAKE_BINARY_DIR}/dxvk + GIT_REPOSITORY "https://github.com/doitsujin/dxvk" + GIT_TAG "v2.6.2" + UPDATE_DISCONNECTED true + USES_TERMINAL_CONFIGURE true + USES_TERMINAL_BUILD true + CONFIGURE_COMMAND + cd ${CMAKE_BINARY_DIR}/dxvk/src/dxvk_git && + sed -i s/private:// + src/dxvk/dxvk_device.h && + CFLAGS=-w CXXFLAGS=-w CC=clang CXX=clang++ meson setup + --buildtype "release" + --prefix "${CMAKE_BINARY_DIR}/dxvk/native/usr" + --strip + -Dbuild_id=false + --force-fallback-for=libdisplay-info + --wipe + ${CMAKE_BINARY_DIR}/dxvk/build + BUILD_COMMAND + cd ${CMAKE_BINARY_DIR}/dxvk && + ninja -C build install && # sorry cursed lol + echo "clang -shared -o libdxvkinternals.so $(find build/src/{dxbc,wsi,vulkan,dxvk,dxgi,spirv,util}/*.p -type f -name \\*.o)" > archive.sh && + bash archive.sh + INSTALL_COMMAND "" +) + +add_library(dxvk INTERFACE) +add_dependencies(dxvk dxvk_git) + +target_link_directories(dxvk + INTERFACE ${CMAKE_BINARY_DIR}/dxvk/native/usr/lib + INTERFACE ${CMAKE_BINARY_DIR}/dxvk) +target_include_directories(dxvk SYSTEM + INTERFACE ${CMAKE_BINARY_DIR}/dxvk/native/usr/include/dxvk + INTERFACE ${CMAKE_BINARY_DIR}/dxvk/src/dxvk_git/src + INTERFACE ${CMAKE_BINARY_DIR}/dxvk/src/dxvk_git/include/spirv/include) +target_link_libraries(dxvk INTERFACE + dxvk_d3d11 dxvk_dxgi display-info dxvkinternals) + +# pe-parse subproject + +include(FetchContent) +FetchContent_Declare(peparse_git + GIT_REPOSITORY "https://github.com/trailofbits/pe-parse" + GIT_TAG "v2.1.1" +) +FetchContent_MakeAvailable(peparse_git) + +add_library(peparse INTERFACE) +add_dependencies(peparse peparse_git) + +target_link_directories(peparse + INTERFACE ${peparse_SOURCE_DIR}/pe-parser-library/include) +target_include_directories(peparse SYSTEM + INTERFACE ${peparse_BUILD_DIR}) +target_link_libraries(peparse + INTERFACE pe-parse) + +# main project + project(lsfg-vk-gen VERSION 0.0.1 DESCRIPTION "lsfg-vk-gen: LSFG on Linux through Vulkan (backend)" @@ -5,6 +70,7 @@ project(lsfg-vk-gen file(GLOB BACKEND_SOURCES "src/core/*.cpp" + "src/pool/*.cpp" "src/shaderchains/*.cpp" "src/*.cpp" ) @@ -15,7 +81,9 @@ target_include_directories(lsfg-vk-gen PRIVATE include PUBLIC public) target_link_libraries(lsfg-vk-gen - PUBLIC vulkan) + PUBLIC vulkan peparse crypto dxvk) +set_target_properties(lsfg-vk-gen + PROPERTIES CXX_CLANG_TIDY clang-tidy) target_compile_options(lsfg-vk-gen PRIVATE -Weverything # disable compat c++ flags @@ -33,4 +101,8 @@ target_compile_options(lsfg-vk-gen PRIVATE -Wno-global-constructors # required for vulkan -Wno-cast-function-type-strict + # required for peparse + -Wno-unused-template + # required for dxvk (yeah don't worry about it) + -Qunused-arguments -Wl,--unresolved-symbols=ignore-all ) diff --git a/lsfg-vk-gen/include/context.hpp b/lsfg-vk-gen/include/context.hpp index e511d98..d4120c2 100644 --- a/lsfg-vk-gen/include/context.hpp +++ b/lsfg-vk-gen/include/context.hpp @@ -1,6 +1,7 @@ #ifndef CONTEXT_HPP #define CONTEXT_HPP +#include "pool/shaderpool.hpp" #include "core/commandbuffer.hpp" #include "core/commandpool.hpp" #include "core/descriptorpool.hpp" @@ -29,6 +30,7 @@ namespace LSFG { /// Create a generator instance. /// /// @param device The Vulkan device to use. + /// @param shaderpool The shader pool to use. /// @param width Width of the input images. /// @param height Height of the input images. /// @param in0 File descriptor for the first input image. @@ -37,7 +39,8 @@ namespace LSFG { /// /// @throws LSFG::vulkan_error if the generator fails to initialize. /// - Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, + Context(const Core::Device& device, Pool::ShaderPool& shaderpool, + uint32_t width, uint32_t height, int in0, int in1, const std::vector& outN); /// diff --git a/lsfg-vk-gen/include/core/shadermodule.hpp b/lsfg-vk-gen/include/core/shadermodule.hpp index 81d8c10..d71e7e4 100644 --- a/lsfg-vk-gen/include/core/shadermodule.hpp +++ b/lsfg-vk-gen/include/core/shadermodule.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -25,13 +24,12 @@ namespace LSFG::Core { /// Create the shader module. /// /// @param device Vulkan device - /// @param path Path to the shader file. + /// @param code SPIR-V bytecode for the shader. /// @param descriptorTypes Descriptor types used in the shader. /// - /// @throws std::system_error if the shader file cannot be opened or read. /// @throws LSFG::vulkan_error if object creation fails. /// - ShaderModule(const Core::Device& device, const std::string& path, + ShaderModule(const Core::Device& device, const std::vector& code, const std::vector>& descriptorTypes); /// Get the Vulkan handle. diff --git a/lsfg-vk-gen/include/pool/extract.hpp b/lsfg-vk-gen/include/pool/extract.hpp new file mode 100644 index 0000000..eaa0824 --- /dev/null +++ b/lsfg-vk-gen/include/pool/extract.hpp @@ -0,0 +1,86 @@ +#ifndef RESOURCES_HPP +#define RESOURCES_HPP + +#include +#include + +#include +#include +#include +#include + +namespace LSFG::Pool { + + /// + /// DLL resource extractor class. + /// + class Extractor { + public: + Extractor() noexcept = default; + + /// + /// Create a new extractor. + /// + /// @param path Path to the DLL file. + /// + /// @throws std::runtime_error if the file cannot be parsed. + /// + Extractor(const std::string& path); + + /// + /// Get a resource by its hash. + /// + /// @param hash Hash of the resource. + /// @return Resource data + /// + /// @throws std::runtime_error if the resource is not found. + /// + [[nodiscard]] std::vector getResource(const std::string& hash) const; + + // Trivially copyable, moveable and destructible + Extractor(const Extractor&) = delete; + Extractor& operator=(const Extractor&) = delete; + Extractor(Extractor&&) = default; + Extractor& operator=(Extractor&&) = default; + ~Extractor() = default; + private: + std::unordered_map> resources; + }; + + /// + /// DirectX bytecode translator class. + /// + class Translator { + public: + /// + /// Create a new translator. + /// + /// @throws std::runtime_error if the initialization fails. + /// + Translator(); + + /// + /// Translate DXBC into SPIR-V. + /// + /// @param dxbc Bytecode to translate. + /// @return Translated SPIR-V bytecode. + /// + /// @throws std::runtime_error if the translation fails. + /// + [[nodiscard]] std::vector translate(const std::vector& dxbc) const; + + // Trivially copyable, moveable and destructible + Translator(const Translator&) = delete; + Translator& operator=(const Translator&) = delete; + Translator(Translator&&) = default; + Translator& operator=(Translator&&) = default; + ~Translator() = default; + private: + std::shared_ptr device; + std::shared_ptr context; + }; + +} + + +#endif // RESOURCES_HPP diff --git a/lsfg-vk-gen/include/pool/shaderpool.hpp b/lsfg-vk-gen/include/pool/shaderpool.hpp new file mode 100644 index 0000000..0612829 --- /dev/null +++ b/lsfg-vk-gen/include/pool/shaderpool.hpp @@ -0,0 +1,48 @@ +#ifndef SHADERPOOL_HPP +#define SHADERPOOL_HPP + +#include "core/device.hpp" +#include "core/shadermodule.hpp" + +#include +#include + +namespace LSFG::Pool { + + /// + /// Shader pool for each Vulkan device. + /// + class ShaderPool { + public: + ShaderPool() noexcept = default; + + /// + /// Create the shader pool. + /// + /// @param path Path to the shader dll + /// + /// @throws std::runtime_error if the shader pool cannot be created. + /// + ShaderPool(const std::string& path); + + /// + /// Retrieve a shader module by name or create it. + /// + /// @param device Vulkan device + /// @param name Name of the shader module + /// @param types Descriptor types for the shader module + /// @return Shader module or empty + /// + /// @throws LSFG::vulkan_error if the shader module cannot be created. + /// + Core::ShaderModule getShader( + const Core::Device& device, const std::string& name, + const std::vector>& types); + private: + std::unordered_map> shaderBytecodes; + std::unordered_map shaders; + }; + +} + +#endif // SHADERPOOL_HPP diff --git a/lsfg-vk-gen/include/shaderchains/alpha.hpp b/lsfg-vk-gen/include/shaderchains/alpha.hpp index a38e40a..b40a8ea 100644 --- a/lsfg-vk-gen/include/shaderchains/alpha.hpp +++ b/lsfg-vk-gen/include/shaderchains/alpha.hpp @@ -1,6 +1,7 @@ #ifndef ALPHA_HPP #define ALPHA_HPP +#include "pool/shaderpool.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" #include "core/descriptorset.hpp" @@ -26,12 +27,14 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to allocate in. /// @param inImg The input image to process /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Alpha(const Core::Device& device, const Core::DescriptorPool& pool, + Alpha(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg); /// diff --git a/lsfg-vk-gen/include/shaderchains/beta.hpp b/lsfg-vk-gen/include/shaderchains/beta.hpp index 8b39c85..f39b824 100644 --- a/lsfg-vk-gen/include/shaderchains/beta.hpp +++ b/lsfg-vk-gen/include/shaderchains/beta.hpp @@ -1,6 +1,7 @@ #ifndef BETA_HPP #define BETA_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to allocate in. /// @param inImgs_0 The next input images to process (when fc % 3 == 0) /// @param inImgs_1 The prev input images to process (when fc % 3 == 0) @@ -36,7 +38,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Beta(const Core::Device& device, const Core::DescriptorPool& pool, + Beta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs_0, std::array inImgs_1, std::array inImgs_2, diff --git a/lsfg-vk-gen/include/shaderchains/delta.hpp b/lsfg-vk-gen/include/shaderchains/delta.hpp index 90f7631..42220cc 100644 --- a/lsfg-vk-gen/include/shaderchains/delta.hpp +++ b/lsfg-vk-gen/include/shaderchains/delta.hpp @@ -1,6 +1,7 @@ #ifndef DELTA_HPP #define DELTA_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to allocate in. /// @param inImgs The input images to process. /// @param optImg An optional additional input from the previous pass. @@ -35,7 +37,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Delta(const Core::Device& device, const Core::DescriptorPool& pool, + Delta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs, std::optional optImg, size_t genc); diff --git a/lsfg-vk-gen/include/shaderchains/downsample.hpp b/lsfg-vk-gen/include/shaderchains/downsample.hpp index f136b69..bcf1410 100644 --- a/lsfg-vk-gen/include/shaderchains/downsample.hpp +++ b/lsfg-vk-gen/include/shaderchains/downsample.hpp @@ -1,6 +1,7 @@ #ifndef DOWNSAMPLE_HPP #define DOWNSAMPLE_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -27,6 +28,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to allocate in. /// @param inImg_0 The next full image to downsample (when fc % 2 == 0) /// @param inImg_1 The next full image to downsample (when fc % 2 == 1) @@ -34,7 +36,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Downsample(const Core::Device& device, const Core::DescriptorPool& pool, + Downsample(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg_0, Core::Image inImg_1, size_t genc); diff --git a/lsfg-vk-gen/include/shaderchains/epsilon.hpp b/lsfg-vk-gen/include/shaderchains/epsilon.hpp index 2559726..d1c1c61 100644 --- a/lsfg-vk-gen/include/shaderchains/epsilon.hpp +++ b/lsfg-vk-gen/include/shaderchains/epsilon.hpp @@ -1,6 +1,7 @@ #ifndef EPSILON_HPP #define EPSILON_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to use for descriptor sets. /// @param inImgs1 The first set of input images to process. /// @param inImg2 The second type image to process. @@ -36,7 +38,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, + Epsilon(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, std::optional optImg, diff --git a/lsfg-vk-gen/include/shaderchains/extract.hpp b/lsfg-vk-gen/include/shaderchains/extract.hpp index 92d0bf3..1fdc5ec 100644 --- a/lsfg-vk-gen/include/shaderchains/extract.hpp +++ b/lsfg-vk-gen/include/shaderchains/extract.hpp @@ -1,6 +1,7 @@ #ifndef EXTRACT_HPP #define EXTRACT_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -26,6 +27,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to use for descriptor sets. /// @param inImg1 The first set of input images to process. /// @param inImg2 The second type image to process. @@ -34,7 +36,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Extract(const Core::Device& device, const Core::DescriptorPool& pool, + Extract(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, VkExtent2D outExtent, diff --git a/lsfg-vk-gen/include/shaderchains/gamma.hpp b/lsfg-vk-gen/include/shaderchains/gamma.hpp index 5041e30..8ae424b 100644 --- a/lsfg-vk-gen/include/shaderchains/gamma.hpp +++ b/lsfg-vk-gen/include/shaderchains/gamma.hpp @@ -1,6 +1,7 @@ #ifndef GAMMA_HPP #define GAMMA_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -30,6 +31,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to allocate in. /// @param inImgs1_0 The next input images to process (when fc % 3 == 0). /// @param inImgs1_1 The prev input images to process (when fc % 3 == 0). @@ -42,7 +44,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Gamma(const Core::Device& device, const Core::DescriptorPool& pool, + Gamma(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1_0, std::array inImgs1_1, std::array inImgs1_2, diff --git a/lsfg-vk-gen/include/shaderchains/magic.hpp b/lsfg-vk-gen/include/shaderchains/magic.hpp index 00ecf27..545285a 100644 --- a/lsfg-vk-gen/include/shaderchains/magic.hpp +++ b/lsfg-vk-gen/include/shaderchains/magic.hpp @@ -1,6 +1,7 @@ #ifndef MAGIC_HPP #define MAGIC_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to use for descriptor sets. /// @param inImgs1_0 The next input images to process (when fc % 3 == 0). /// @param inImgs1_1 The prev input images to process (when fc % 3 == 0). @@ -39,7 +41,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Magic(const Core::Device& device, const Core::DescriptorPool& pool, + Magic(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1_0, std::array inImgs1_1, std::array inImgs1_2, diff --git a/lsfg-vk-gen/include/shaderchains/merge.hpp b/lsfg-vk-gen/include/shaderchains/merge.hpp index bdfb5e3..3ef81bc 100644 --- a/lsfg-vk-gen/include/shaderchains/merge.hpp +++ b/lsfg-vk-gen/include/shaderchains/merge.hpp @@ -1,6 +1,7 @@ #ifndef MERGE_HPP #define MERGE_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to use for descriptor sets. /// @param inImg1 The prev full image when fc % 2 == 0 /// @param inImg2 The next full image when fc % 2 == 0 @@ -39,7 +41,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Merge(const Core::Device& device, const Core::DescriptorPool& pool, + Merge(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, Core::Image inImg3, diff --git a/lsfg-vk-gen/include/shaderchains/zeta.hpp b/lsfg-vk-gen/include/shaderchains/zeta.hpp index bf08c30..642a6d9 100644 --- a/lsfg-vk-gen/include/shaderchains/zeta.hpp +++ b/lsfg-vk-gen/include/shaderchains/zeta.hpp @@ -1,6 +1,7 @@ #ifndef ZETA_HPP #define ZETA_HPP +#include "pool/shaderpool.hpp" #include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" @@ -28,6 +29,7 @@ namespace LSFG::Shaderchains { /// Initialize the shaderchain. /// /// @param device The Vulkan device to create the resources on. + /// @param shaderpool The shader pool to use for shader modules. /// @param pool The descriptor pool to use for descriptor sets. /// @param inImgs1 The first set of input images to process. /// @param inImg2 The second type image to process. @@ -36,7 +38,8 @@ namespace LSFG::Shaderchains { /// /// @throws LSFG::vulkan_error if resource creation fails. /// - Zeta(const Core::Device& device, const Core::DescriptorPool& pool, + Zeta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, Core::Image inImg3, diff --git a/lsfg-vk-gen/src/context.cpp b/lsfg-vk-gen/src/context.cpp index 0c9ff67..f7d1f82 100644 --- a/lsfg-vk-gen/src/context.cpp +++ b/lsfg-vk-gen/src/context.cpp @@ -1,6 +1,7 @@ #include "context.hpp" #include "core/fence.hpp" #include "core/semaphore.hpp" +#include "pool/shaderpool.hpp" #include "lsfg.hpp" #include @@ -10,7 +11,8 @@ using namespace LSFG; -Context::Context(const Core::Device& device, uint32_t width, uint32_t height, int in0, int in1, +Context::Context(const Core::Device& device, Pool::ShaderPool& shaderpool, + uint32_t width, uint32_t height, int in0, int in1, const std::vector& outN) { // import images this->inImg_0 = Core::Image(device, { width, height }, @@ -35,18 +37,18 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in } // create shader chains - this->downsampleChain = Shaderchains::Downsample(device, this->descPool, + this->downsampleChain = Shaderchains::Downsample(device, shaderpool, this->descPool, this->inImg_0, this->inImg_1, outN.size()); for (size_t i = 0; i < 7; i++) - this->alphaChains.at(i) = Shaderchains::Alpha(device, this->descPool, + this->alphaChains.at(i) = Shaderchains::Alpha(device, shaderpool, this->descPool, this->downsampleChain.getOutImages().at(i)); - this->betaChain = Shaderchains::Beta(device, this->descPool, + this->betaChain = Shaderchains::Beta(device, shaderpool, this->descPool, this->alphaChains.at(0).getOutImages0(), this->alphaChains.at(0).getOutImages1(), this->alphaChains.at(0).getOutImages2(), outN.size()); for (size_t i = 0; i < 7; i++) { if (i < 4) { - this->gammaChains.at(i) = Shaderchains::Gamma(device, this->descPool, + this->gammaChains.at(i) = Shaderchains::Gamma(device, shaderpool, this->descPool, this->alphaChains.at(6 - i).getOutImages0(), this->alphaChains.at(6 - i).getOutImages1(), this->alphaChains.at(6 - i).getOutImages2(), @@ -59,7 +61,7 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in outN.size() ); } else { - this->magicChains.at(i - 4) = Shaderchains::Magic(device, this->descPool, + this->magicChains.at(i - 4) = Shaderchains::Magic(device, shaderpool, this->descPool, this->alphaChains.at(6 - i).getOutImages0(), this->alphaChains.at(6 - i).getOutImages1(), this->alphaChains.at(6 - i).getOutImages2(), @@ -70,20 +72,20 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()}, outN.size() ); - this->deltaChains.at(i - 4) = Shaderchains::Delta(device, this->descPool, + this->deltaChains.at(i - 4) = Shaderchains::Delta(device, shaderpool, this->descPool, this->magicChains.at(i - 4).getOutImages1(), i == 4 ? std::nullopt : std::optional{this->deltaChains.at(i - 5).getOutImage()}, outN.size() ); - this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(device, this->descPool, + this->epsilonChains.at(i - 4) = Shaderchains::Epsilon(device, shaderpool, this->descPool, this->magicChains.at(i - 4).getOutImages2(), this->betaChain.getOutImages().at(6 - i), i == 4 ? std::nullopt : std::optional{this->epsilonChains.at(i - 5).getOutImage()}, outN.size() ); - this->zetaChains.at(i - 4) = Shaderchains::Zeta(device, this->descPool, + this->zetaChains.at(i - 4) = Shaderchains::Zeta(device, shaderpool, this->descPool, this->magicChains.at(i - 4).getOutImages3(), i == 4 ? this->gammaChains.at(i - 1).getOutImage1() : this->zetaChains.at(i - 5).getOutImage(), @@ -92,7 +94,7 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in ); if (i >= 6) continue; // no extract for i >= 6 - this->extractChains.at(i - 4) = Shaderchains::Extract(device, this->descPool, + this->extractChains.at(i - 4) = Shaderchains::Extract(device, shaderpool, this->descPool, this->zetaChains.at(i - 4).getOutImage(), this->epsilonChains.at(i - 4).getOutImage(), this->alphaChains.at(6 - i - 1).getOutImages0().at(0).getExtent(), @@ -100,7 +102,7 @@ Context::Context(const Core::Device& device, uint32_t width, uint32_t height, in ); } } - this->mergeChain = Shaderchains::Merge(device, this->descPool, + this->mergeChain = Shaderchains::Merge(device, shaderpool, this->descPool, this->inImg_1, this->inImg_0, this->zetaChains.at(2).getOutImage(), diff --git a/lsfg-vk-gen/src/core/shadermodule.cpp b/lsfg-vk-gen/src/core/shadermodule.cpp index 3c8e98f..df9c2dd 100644 --- a/lsfg-vk-gen/src/core/shadermodule.cpp +++ b/lsfg-vk-gen/src/core/shadermodule.cpp @@ -1,26 +1,10 @@ #include "core/shadermodule.hpp" #include "lsfg.hpp" -#include - using namespace LSFG::Core; -ShaderModule::ShaderModule(const Core::Device& device, const std::string& path, +ShaderModule::ShaderModule(const Core::Device& device, const std::vector& code, const std::vector>& descriptorTypes) { - // read shader bytecode - std::ifstream file(path, std::ios::ate | std::ios::binary); - if (!file) - throw std::system_error(errno, std::generic_category(), "Failed to open shader file: " + path); - - const std::streamsize size = file.tellg(); - std::vector code(static_cast(size)); - - file.seekg(0, std::ios::beg); - if (!file.read(reinterpret_cast(code.data()), size)) - throw std::system_error(errno, std::generic_category(), "Failed to read shader file: " + path); - - file.close(); - // create shader module const uint8_t* data_ptr = code.data(); const VkShaderModuleCreateInfo createInfo{ diff --git a/lsfg-vk-gen/src/lsfg.cpp b/lsfg-vk-gen/src/lsfg.cpp index 816c4ff..f3fcab9 100644 --- a/lsfg-vk-gen/src/lsfg.cpp +++ b/lsfg-vk-gen/src/lsfg.cpp @@ -2,10 +2,13 @@ #include "core/device.hpp" #include "core/instance.hpp" #include "context.hpp" +#include "pool/shaderpool.hpp" #include "utils.hpp" +#include #include #include +#include #include using namespace LSFG; @@ -13,6 +16,7 @@ using namespace LSFG; namespace { std::optional instance; std::optional device; + std::optional pool; std::unordered_map contexts; } @@ -20,8 +24,12 @@ void LSFG::initialize() { if (instance.has_value() || device.has_value()) return; + char* dllPath = getenv("LSFG_DLL_PATH"); + const std::string dllPathStr = dllPath ? std::string(dllPath) : "Lossless.dll"; + instance.emplace(); device.emplace(*instance); + pool.emplace(dllPathStr); Globals::initializeGlobals(*device); @@ -30,16 +38,16 @@ void LSFG::initialize() { int32_t LSFG::createContext(uint32_t width, uint32_t height, int in0, int in1, const std::vector& outN) { - if (!instance.has_value() || !device.has_value()) + if (!instance.has_value() || !device.has_value() || !pool.has_value()) throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED, "LSFG not initialized"); auto id = std::rand(); - contexts.emplace(id, Context(*device, width, height, in0, in1, outN)); + contexts.emplace(id, Context(*device, *pool, width, height, in0, in1, outN)); return id; } void LSFG::presentContext(int32_t id, int inSem, const std::vector& outSem) { - if (!instance.has_value() || !device.has_value()) + if (!instance.has_value() || !device.has_value() || !pool.has_value()) throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED, "LSFG not initialized"); auto it = contexts.find(id); @@ -51,7 +59,7 @@ void LSFG::presentContext(int32_t id, int inSem, const std::vector& outSem) } void LSFG::deleteContext(int32_t id) { - if (!instance.has_value() || !device.has_value()) + if (!instance.has_value() || !device.has_value() || !pool.has_value()) throw LSFG::vulkan_error(VK_ERROR_INITIALIZATION_FAILED, "LSFG not initialized"); auto it = contexts.find(id); @@ -63,12 +71,13 @@ void LSFG::deleteContext(int32_t id) { } void LSFG::finalize() { - if (!instance.has_value() || !device.has_value()) + if (!instance.has_value() || !device.has_value() || !pool.has_value()) return; Globals::uninitializeGlobals(); vkDeviceWaitIdle(device->handle()); + pool.reset(); device.reset(); instance.reset(); } diff --git a/lsfg-vk-gen/src/pool/extract.cpp b/lsfg-vk-gen/src/pool/extract.cpp new file mode 100644 index 0000000..2fa5698 --- /dev/null +++ b/lsfg-vk-gen/src/pool/extract.cpp @@ -0,0 +1,127 @@ +#include "pool/extract.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace LSFG::Pool; + +namespace { + + using ResourceMap = std::unordered_map>; + + /// Callback function for each resource. + int on_resource(void* data, const peparse::resource& res) { + if (res.type != peparse::RT_RCDATA || res.buf == nullptr || res.buf->bufLen <= 0) + return 0; + + // hash the resource data + std::array hash{}; + SHA256(res.buf->buf, res.buf->bufLen, hash.data()); + + std::array base64{}; + const int base64_len = EVP_EncodeBlock(base64.data(), hash.data(), hash.size()); + const std::string hash_str(reinterpret_cast(base64.data()), + static_cast(base64_len)); + + // store the resource + std::vector resource_data(res.buf->bufLen); + std::copy_n(res.buf->buf, res.buf->bufLen, resource_data.data()); + + auto* map = reinterpret_cast(data); + (*map)[hash_str] = resource_data; + + return 0; + } + +} + +Extractor::Extractor(const std::string& path) { + peparse::parsed_pe* pe = peparse::ParsePEFromFile(path.c_str()); + if (!pe) + throw std::runtime_error("Unable to parse PE file: " + path); + + peparse::IterRsrc(pe, on_resource, &this->resources); + peparse::DestructParsedPE(pe); +} + +std::vector Extractor::getResource(const std::string& hash) const { + auto it = this->resources.find(hash); + if (it != this->resources.end()) + return it->second; + throw std::runtime_error("Resource not found: " + hash); +} + +Translator::Translator() { + setenv("DXVK_WSI_DRIVER", "SDL3", 0); + setenv("DXVK_LOG_LEVEL", "error", 0); + setenv("DXVK_LOG_PATH", "none", 0); + + // create d3d11 device + ID3D11Device* device{}; + ID3D11DeviceContext* context{}; + const D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1; + D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE, + nullptr, + 0, + &featureLevel, 1, + D3D11_SDK_VERSION, + &device, nullptr, &context + ); + if (!device || !context) + throw std::runtime_error("Failed to create D3D11 device"); + + // store device in shared ptr + this->device = std::shared_ptr( + new ID3D11Device*(device), + [](ID3D11Device** dev) { + (*dev)->Release(); + } + ); + this->context = std::shared_ptr( + new ID3D11DeviceContext*(context), + [](ID3D11DeviceContext** ctx) { + (*ctx)->Release(); + } + ); +} + +std::vector Translator::translate(const std::vector& dxbc) const { + // create compute shader and pipeline + ID3D11ComputeShader* shader = nullptr; + (*this->device)->CreateComputeShader(dxbc.data(), dxbc.size(), nullptr, &shader); + if (!shader) + throw std::runtime_error("Failed to create compute shader from DXBC"); + + auto* dxvk_shader = reinterpret_cast(shader); + auto* dxvk_device = reinterpret_cast(*this->device); + + auto* pipeline = dxvk_device->GetDXVKDevice()->m_objects.pipelineManager().createComputePipeline({ + .cs = dxvk_shader->GetCommonShader()->GetShader() + }); + + // extract spir-v from d3d11 shader + auto code = dxvk_shader->GetCommonShader()->GetShader()->getCode( + pipeline->getBindings(), dxvk::DxvkShaderModuleCreateInfo()); + std::vector spirv(code.size()); + std::copy_n(reinterpret_cast(code.data()), + code.size(), spirv.data()); + + // cleanup-ish (i think the pipeline will linger) + shader->Release(); + return spirv; +} diff --git a/lsfg-vk-gen/src/pool/shaderpool.cpp b/lsfg-vk-gen/src/pool/shaderpool.cpp new file mode 100644 index 0000000..292ed23 --- /dev/null +++ b/lsfg-vk-gen/src/pool/shaderpool.cpp @@ -0,0 +1,76 @@ +#include "pool/shaderpool.hpp" + +#include "pool/extract.hpp" + +using namespace LSFG; +using namespace LSFG::Pool; + +const std::unordered_map SHADERS = { + { "alpha/0.spv", "lilEUr7nBgA8P6VSqCms09t9b+DZH6dVlcefVuFHlc8=" }, + { "alpha/1.spv", "2TRNidol3BNs/aeLl2/Om7z8bAlpehkOPVtmMao1q84=" }, + { "alpha/2.spv", "tP6qIJZhd4pGr1pop1e9ztW1gwp97ufQa2GaBZBYZJE=" }, + { "alpha/3.spv", "gA4ZejNp+RwtqjtTzGdGf5D/CjSGlwFB2nOgDAIv91k=" }, + { "beta/0.spv", "uQ/xsBMKRuJhbxstBukWMhXYuppPAYygxkb/3kNu4vI=" }, + { "beta/1.spv", "BUbrL9fZREXLlg1lmlTYD6n8DwpzHkho5bI3RLbfNJg=" }, + { "beta/2.spv", "bz0lxQjMYp6HLqw12X3jfV7H0SOZKrqUhgtw17WgTx4=" }, + { "beta/3.spv", "JA5/8p7yiiiCxmuiTsOR9Fb/z1qp8KlyU2wo9Wfpbcc=" }, + { "beta/4.spv", "/I+iYEwzOFylXZJWWNQ/oUT6SeLVnpotNXGV8y/FUVk=" }, + { "delta/0.spv", "gtBWy1WtP8NO+Z1sSPMgOJ75NaPEKvthc7imNGzJkGI=" }, + { "delta/1.spv", "JiqZZIoHay/uS1ptzlz3EWKUPct/jQHoFtN0qlEtVUU=" }, + { "delta/2.spv", "zkBa37GvAG8izeIv4o/3OowpxiobfOdNmPyVWl2BSWY=" }, + { "delta/3.spv", "neIMl/PCPonXqjtZykMb9tR4yW7JkZfMTqZPGOmJQUg=" }, + { "downsample.spv", "F9BppS+ytDjO3aoMEY7deMzLaSUhX8EuI+eH8654Fpw=" }, + { "epsilon/0.spv", "YHECg9LrgTCM8lABFOXkC5qTKoHsIMWnZ6ST3dexD08=" }, + { "epsilon/1.spv", "Uv7CfTi6x69c9Exuc16UqA7fvLTUGicHZVi5jhHKo0w=" }, + { "epsilon/2.spv", "0vmxxGRa6gbl5dqmKTBO9x/ZM2oEUJ5JtGfqcHhvouQ=" }, + { "epsilon/3.spv", "Sa/gkbCCDyCyUh8BSOa882t4qDc51oeP6+Kj3O3EaxM=" }, + { "extract.spv", "xKUdoEwFJDsc/kX/aY1FyzlMlOaJX4iHQLlthe2MvBs=" }, + { "gamma/0.spv", "AJuuF/X9NnypgBd89GbXMKcXC2meysYayiZQZwu3WhU=" }, + { "gamma/1.spv", "LLr/3D+whLd6XuKkBS7rlaNN+r8qB/Khr4ii+M7KSxY=" }, + { "gamma/2.spv", "KjHXdawBR8AMK7Kud/vXJmJTddXFKppREEpsykjwZDc=" }, + { "gamma/3.spv", "zAnAC73i76AJjv0o1To3bBu2jnIWXzX3NlSMvU3Lgxw=" }, + { "gamma/4.spv", "ivQ7ltprazBOXb46yxul9HJ5ByJk2LbG034cC6NkEpk=" }, + { "gamma/5.spv", "lHYgyCpWnMIB74HL22BKQyoqUGvUjgR79W4vXFXzXe4=" }, + { "magic.spv", "ZdoTjEhrlbAxq0MtaJyk6jQ5+hrySEsnvn+jseukAuI=" }, + { "merge.spv", "dnluf4IHKNaqz6WvH7qodn+fZ56ORx+w3MUOwH7huok=" }, + { "zeta/0.spv", "LLr/3D+whLd6XuKkBS7rlaNN+r8qB/Khr4ii+M7KSxY=" }, + { "zeta/1.spv", "KjHXdawBR8AMK7Kud/vXJmJTddXFKppREEpsykjwZDc=" }, + { "zeta/2.spv", "zAnAC73i76AJjv0o1To3bBu2jnIWXzX3NlSMvU3Lgxw=" }, + { "zeta/3.spv", "ivQ7ltprazBOXb46yxul9HJ5ByJk2LbG034cC6NkEpk=" }, + { "zeta/4.spv", "lHYgyCpWnMIB74HL22BKQyoqUGvUjgR79W4vXFXzXe4=" } +}; + +ShaderPool::ShaderPool(const std::string& path) { + const Extractor extractor(path); + const Translator translator; + + for (const auto& [name, hash] : SHADERS) { + auto data = extractor.getResource(hash); + if (data.empty()) + throw std::runtime_error("Shader code is empty: " + name); + + auto code = translator.translate(data); + if (code.empty()) + throw std::runtime_error("Shader code translation failed: " + name); + + shaderBytecodes[name] = std::move(code); + } +} + +Core::ShaderModule ShaderPool::getShader( + const Core::Device& device, const std::string& name, + const std::vector>& types) { + auto it = shaders.find(name); + if (it != shaders.end()) + return it->second; + + // create the shader module + auto cit = shaderBytecodes.find(name); + if (cit == shaderBytecodes.end()) + throw std::runtime_error("Shader code translation failed: " + name); + auto code = cit->second; + + Core::ShaderModule shader(device, code, types); + shaders[name] = shader; + return shader; +} diff --git a/lsfg-vk-gen/src/shaderchains/alpha.cpp b/lsfg-vk-gen/src/shaderchains/alpha.cpp index 52c55aa..8f525ca 100644 --- a/lsfg-vk-gen/src/shaderchains/alpha.cpp +++ b/lsfg-vk-gen/src/shaderchains/alpha.cpp @@ -3,23 +3,24 @@ using namespace LSFG::Shaderchains; -Alpha::Alpha(const Core::Device& device, const Core::DescriptorPool& pool, +Alpha::Alpha(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg) : inImg(std::move(inImg)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/alpha/0.spv", + shaderpool.getShader(device, "alpha/0.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/alpha/1.spv", + shaderpool.getShader(device, "alpha/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/alpha/2.spv", + shaderpool.getShader(device, "alpha/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/alpha/3.spv", + shaderpool.getShader(device, "alpha/3.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }) diff --git a/lsfg-vk-gen/src/shaderchains/beta.cpp b/lsfg-vk-gen/src/shaderchains/beta.cpp index 19f0cef..23346de 100644 --- a/lsfg-vk-gen/src/shaderchains/beta.cpp +++ b/lsfg-vk-gen/src/shaderchains/beta.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Beta::Beta(const Core::Device& device, const Core::DescriptorPool& pool, +Beta::Beta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs_0, std::array inImgs_1, std::array inImgs_2, @@ -12,23 +13,23 @@ Beta::Beta(const Core::Device& device, const Core::DescriptorPool& pool, inImgs_1(std::move(inImgs_1)), inImgs_2(std::move(inImgs_2)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/beta/0.spv", + shaderpool.getShader(device, "beta/0.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 8+4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/beta/1.spv", + shaderpool.getShader(device, "beta/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/beta/2.spv", + shaderpool.getShader(device, "beta/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/beta/3.spv", + shaderpool.getShader(device, "beta/3.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/beta/4.spv", + shaderpool.getShader(device, "beta/4.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/delta.cpp b/lsfg-vk-gen/src/shaderchains/delta.cpp index 7503729..63e463e 100644 --- a/lsfg-vk-gen/src/shaderchains/delta.cpp +++ b/lsfg-vk-gen/src/shaderchains/delta.cpp @@ -3,26 +3,27 @@ using namespace LSFG::Shaderchains; -Delta::Delta(const Core::Device& device, const Core::DescriptorPool& pool, +Delta::Delta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs, std::optional optImg, size_t genc) : inImgs(std::move(inImgs)), optImg(std::move(optImg)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/delta/0.spv", + shaderpool.getShader(device, "delta/0.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/delta/1.spv", + shaderpool.getShader(device, "delta/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/delta/2.spv", + shaderpool.getShader(device, "delta/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/delta/3.spv", + shaderpool.getShader(device, "delta/3.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/downsample.cpp b/lsfg-vk-gen/src/shaderchains/downsample.cpp index f06dd59..c7e4ef2 100644 --- a/lsfg-vk-gen/src/shaderchains/downsample.cpp +++ b/lsfg-vk-gen/src/shaderchains/downsample.cpp @@ -3,12 +3,13 @@ using namespace LSFG::Shaderchains; -Downsample::Downsample(const Core::Device& device, const Core::DescriptorPool& pool, +Downsample::Downsample(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg_0, Core::Image inImg_1, size_t genc) : inImg_0(std::move(inImg_0)), inImg_1(std::move(inImg_1)) { - this->shaderModule = Core::ShaderModule(device, "rsc/shaders/downsample.spv", + this->shaderModule = shaderpool.getShader(device, "downsample.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/epsilon.cpp b/lsfg-vk-gen/src/shaderchains/epsilon.cpp index 2093623..931596c 100644 --- a/lsfg-vk-gen/src/shaderchains/epsilon.cpp +++ b/lsfg-vk-gen/src/shaderchains/epsilon.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Epsilon::Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, +Epsilon::Epsilon(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, std::optional optImg, @@ -12,19 +13,19 @@ Epsilon::Epsilon(const Core::Device& device, const Core::DescriptorPool& pool, inImg2(std::move(inImg2)), optImg(std::move(optImg)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/epsilon/0.spv", + shaderpool.getShader(device, "epsilon/0.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/epsilon/1.spv", + shaderpool.getShader(device, "epsilon/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/epsilon/2.spv", + shaderpool.getShader(device, "epsilon/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/epsilon/3.spv", + shaderpool.getShader(device, "epsilon/3.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/extract.cpp b/lsfg-vk-gen/src/shaderchains/extract.cpp index 4f63223..8526f8d 100644 --- a/lsfg-vk-gen/src/shaderchains/extract.cpp +++ b/lsfg-vk-gen/src/shaderchains/extract.cpp @@ -3,14 +3,15 @@ using namespace LSFG::Shaderchains; -Extract::Extract(const Core::Device& device, const Core::DescriptorPool& pool, +Extract::Extract(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, VkExtent2D outExtent, size_t genc) : inImg1(std::move(inImg1)), inImg2(std::move(inImg2)) { - this->shaderModule = Core::ShaderModule(device, "rsc/shaders/extract.spv", + this->shaderModule = shaderpool.getShader(device, "extract.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/gamma.cpp b/lsfg-vk-gen/src/shaderchains/gamma.cpp index f469a9c..f7e746a 100644 --- a/lsfg-vk-gen/src/shaderchains/gamma.cpp +++ b/lsfg-vk-gen/src/shaderchains/gamma.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, +Gamma::Gamma(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1_0, std::array inImgs1_1, std::array inImgs1_2, @@ -18,29 +19,29 @@ Gamma::Gamma(const Core::Device& device, const Core::DescriptorPool& pool, inImg2(std::move(inImg2)), optImg2(std::move(optImg2)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/gamma/0.spv", + shaderpool.getShader(device, "gamma/0.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 10, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } }), - Core::ShaderModule(device, "rsc/shaders/gamma/1.spv", + shaderpool.getShader(device, "gamma/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/gamma/2.spv", + shaderpool.getShader(device, "gamma/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/gamma/3.spv", + shaderpool.getShader(device, "gamma/3.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/gamma/4.spv", + shaderpool.getShader(device, "gamma/4.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } }), - Core::ShaderModule(device, "rsc/shaders/gamma/5.spv", + shaderpool.getShader(device, "gamma/5.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/magic.cpp b/lsfg-vk-gen/src/shaderchains/magic.cpp index 6a89f09..a4e8d4b 100644 --- a/lsfg-vk-gen/src/shaderchains/magic.cpp +++ b/lsfg-vk-gen/src/shaderchains/magic.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Magic::Magic(const Core::Device& device, const Core::DescriptorPool& pool, +Magic::Magic(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1_0, std::array inImgs1_1, std::array inImgs1_2, @@ -16,7 +17,7 @@ Magic::Magic(const Core::Device& device, const Core::DescriptorPool& pool, inImgs1_2(std::move(inImgs1_2)), inImg2(std::move(inImg2)), inImg3(std::move(inImg3)), optImg(std::move(optImg)) { - this->shaderModule = Core::ShaderModule(device, "rsc/shaders/magic.spv", + this->shaderModule = shaderpool.getShader(device, "magic.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4+4+2+1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 3+3+2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/merge.cpp b/lsfg-vk-gen/src/shaderchains/merge.cpp index bd2cb92..e9866d2 100644 --- a/lsfg-vk-gen/src/shaderchains/merge.cpp +++ b/lsfg-vk-gen/src/shaderchains/merge.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Merge::Merge(const Core::Device& device, const Core::DescriptorPool& pool, +Merge::Merge(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, Core::Image inImg1, Core::Image inImg2, Core::Image inImg3, @@ -16,7 +17,7 @@ Merge::Merge(const Core::Device& device, const Core::DescriptorPool& pool, inImg3(std::move(inImg3)), inImg4(std::move(inImg4)), inImg5(std::move(inImg5)) { - this->shaderModule = Core::ShaderModule(device, "rsc/shaders/merge.spv", + this->shaderModule = shaderpool.getShader(device, "merge.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 5, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/lsfg-vk-gen/src/shaderchains/zeta.cpp b/lsfg-vk-gen/src/shaderchains/zeta.cpp index b5b3c99..1824bb4 100644 --- a/lsfg-vk-gen/src/shaderchains/zeta.cpp +++ b/lsfg-vk-gen/src/shaderchains/zeta.cpp @@ -3,7 +3,8 @@ using namespace LSFG::Shaderchains; -Zeta::Zeta(const Core::Device& device, const Core::DescriptorPool& pool, +Zeta::Zeta(const Core::Device& device, Pool::ShaderPool& shaderpool, + const Core::DescriptorPool& pool, std::array inImgs1, Core::Image inImg2, Core::Image inImg3, @@ -12,19 +13,19 @@ Zeta::Zeta(const Core::Device& device, const Core::DescriptorPool& pool, inImg2(std::move(inImg2)), inImg3(std::move(inImg3)) { this->shaderModules = {{ - Core::ShaderModule(device, "rsc/shaders/zeta/0.spv", + shaderpool.getShader(device, "zeta/0.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/zeta/1.spv", + shaderpool.getShader(device, "zeta/1.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/zeta/2.spv", + shaderpool.getShader(device, "zeta/2.spv", { { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, { 4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE } }), - Core::ShaderModule(device, "rsc/shaders/zeta/3.spv", + shaderpool.getShader(device, "zeta/3.spv", { { 2, VK_DESCRIPTOR_TYPE_SAMPLER }, { 6, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE }, diff --git a/src/hooks.cpp b/src/hooks.cpp index 3154b2f..f7530c0 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -21,7 +21,9 @@ namespace { const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { // create lsfg + Loader::DL::disableHooks(); LSFG::initialize(); + Loader::DL::enableHooks(); // add extensions auto extensions = Utils::addExtensions(pCreateInfo->ppEnabledExtensionNames, @@ -70,13 +72,13 @@ namespace { // store device info try { const char* frameGen = std::getenv("LSFG_MULTIPLIER"); - if (!frameGen) frameGen = "1"; + if (!frameGen) frameGen = "2"; devices.emplace(*pDevice, DeviceInfo { .device = *pDevice, .physicalDevice = physicalDevice, .queue = Utils::findQueue(*pDevice, physicalDevice, &createInfo, VK_QUEUE_GRAPHICS_BIT), - .frameGen = std::stoul(frameGen) + .frameGen = std::max(1, std::stoul(frameGen) - 1) }); } catch (const std::exception& e) { Log::error("Failed to create device info: {}", e.what()); @@ -133,6 +135,7 @@ namespace { )); swapchainToDeviceTable.emplace(*pSwapchain, device); + Log::debug("Created swapchain with {} images", imageCount); } catch (const LSFG::vulkan_error& e) { Log::error("Encountered Vulkan error {:x} while creating swapchain: {}", static_cast(e.error()), e.what());