From 1d1b9cc4d18b2b0a1b216410ef4dcea8ea77103f Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Wed, 8 Apr 2026 10:13:30 +0100 Subject: [PATCH] chore: use templating for iw4 shader compilation --- src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp | 4 +- .../IW4/Techset/PixelShaderCompilerIW4.cpp | 67 ----------- .../Game/IW4/Techset/PixelShaderCompilerIW4.h | 11 -- .../IW4/Techset/VertexShaderCompilerIW4.cpp | 67 ----------- .../IW4/Techset/VertexShaderCompilerIW4.h | 11 -- .../Techset/PixelShaderCompiler.cpp.template | 112 ++++++++++++++++++ .../Techset/PixelShaderCompiler.h.template | 41 +++++++ .../Techset/VertexShaderCompiler.cpp.template | 112 ++++++++++++++++++ .../Techset/VertexShaderCompiler.h.template | 41 +++++++ 9 files changed, 308 insertions(+), 158 deletions(-) delete mode 100644 src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp delete mode 100644 src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.h delete mode 100644 src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp delete mode 100644 src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.h create mode 100644 src/ObjCompiling/Techset/PixelShaderCompiler.cpp.template create mode 100644 src/ObjCompiling/Techset/PixelShaderCompiler.h.template create mode 100644 src/ObjCompiling/Techset/VertexShaderCompiler.cpp.template create mode 100644 src/ObjCompiling/Techset/VertexShaderCompiler.h.template diff --git a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp index 95a24fe0..4504d761 100644 --- a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp +++ b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp @@ -1,13 +1,13 @@ #include "ObjCompilerIW4.h" #include "Game/IW4/IW4.h" +#include "Game/IW4/Techset/PixelShaderCompilerIW4.h" #include "Game/IW4/Techset/TechniqueCompilerIW4.h" #include "Game/IW4/Techset/TechsetCompilerIW4.h" #include "Game/IW4/Techset/VertexDeclCompilerIW4.h" +#include "Game/IW4/Techset/VertexShaderCompilerIW4.h" #include "Image/ImageIwdPostProcessor.h" #include "Material/CompilerMaterialIW4.h" -#include "Techset/PixelShaderCompilerIW4.h" -#include "Techset/VertexShaderCompilerIW4.h" #include diff --git a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp deleted file mode 100644 index 670790f7..00000000 --- a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "PixelShaderCompilerIW4.h" - -#include "Game/IW4/IW4.h" -#include "Shader/D3DShaderCompiler.h" -#include "Utils/Logging/Log.h" - -#include -#include -#include - -using namespace IW4; - -namespace -{ - class PixelShaderCompilerIW4 final : public AssetCreator - { - public: - PixelShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) - : m_memory(memory), - m_search_path(searchPath) - { - } - - AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override - { - auto result = shader::CompileShader(assetName, "PSMain", "ps_3_0", false, m_search_path, m_memory); - - if (result.has_value()) - { - const std::optional maybeShader(*std::move(result)); - if (!maybeShader.has_value()) - return AssetCreationResult::NoAction(); - - con::info("Compiled pixel shader \"{}\"", assetName); - - assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0); - - auto* pixelShader = m_memory.Alloc(); - pixelShader->name = m_memory.Dup(assetName.c_str()); - pixelShader->prog.loadDef.program = static_cast(maybeShader->m_shader_bin); - pixelShader->prog.loadDef.programSize = static_cast(maybeShader->m_shader_size / sizeof(uint32_t)); - - return AssetCreationResult::Success(context.AddAsset(AssetRegistration(assetName, pixelShader))); - } - - con::error("Failed to compile pixel shader \"{}\": {}", assetName, result.error()); - return AssetCreationResult::Failure(); - } - - void FinalizeZone(AssetCreationContext& context) override {} - - private: - MemoryManager& m_memory; - ISearchPath& m_search_path; - }; -} // namespace - -namespace techset -{ - std::unique_ptr CreatePixelShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) - { - if (!shader::ShaderCompilationAvailable()) - return nullptr; - - return std::make_unique(memory, searchPath); - } -} // namespace techset diff --git a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.h b/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.h deleted file mode 100644 index 0486277b..00000000 --- a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Asset/IAssetCreator.h" -#include "Utils/MemoryManager.h" - -#include - -namespace techset -{ - std::unique_ptr CreatePixelShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath); -} diff --git a/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp deleted file mode 100644 index 58db1ae4..00000000 --- a/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "VertexShaderCompilerIW4.h" - -#include "Game/IW4/IW4.h" -#include "Shader/D3DShaderCompiler.h" -#include "Utils/Logging/Log.h" - -#include -#include -#include - -using namespace IW4; - -namespace -{ - class VertexShaderCompilerIW4 final : public AssetCreator - { - public: - VertexShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) - : m_memory(memory), - m_search_path(searchPath) - { - } - - AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override - { - auto result = shader::CompileShader(assetName, "VSMain", "vs_3_0", false, m_search_path, m_memory); - - if (result.has_value()) - { - const std::optional maybeShader(*std::move(result)); - if (!maybeShader.has_value()) - return AssetCreationResult::NoAction(); - - con::info("Compiled vertex shader \"{}\"", assetName); - - assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0); - - auto* vertexShader = m_memory.Alloc(); - vertexShader->name = m_memory.Dup(assetName.c_str()); - vertexShader->prog.loadDef.program = static_cast(maybeShader->m_shader_bin); - vertexShader->prog.loadDef.programSize = static_cast(maybeShader->m_shader_size / sizeof(uint32_t)); - - return AssetCreationResult::Success(context.AddAsset(AssetRegistration(assetName, vertexShader))); - } - - con::error("Failed to compile vertex shader \"{}\": {}", assetName, result.error()); - return AssetCreationResult::Failure(); - } - - void FinalizeZone(AssetCreationContext& context) override {} - - private: - MemoryManager& m_memory; - ISearchPath& m_search_path; - }; -} // namespace - -namespace techset -{ - std::unique_ptr CreateVertexShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath) - { - if (!shader::ShaderCompilationAvailable()) - return nullptr; - - return std::make_unique(memory, searchPath); - } -} // namespace techset diff --git a/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.h b/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.h deleted file mode 100644 index c9f5042b..00000000 --- a/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Asset/IAssetCreator.h" -#include "Utils/MemoryManager.h" - -#include - -namespace techset -{ - std::unique_ptr CreateVertexShaderCompilerIW4(MemoryManager& memory, ISearchPath& searchPath); -} diff --git a/src/ObjCompiling/Techset/PixelShaderCompiler.cpp.template b/src/ObjCompiling/Techset/PixelShaderCompiler.cpp.template new file mode 100644 index 00000000..14fc8e6e --- /dev/null +++ b/src/ObjCompiling/Techset/PixelShaderCompiler.cpp.template @@ -0,0 +1,112 @@ +#options GAME(IW4) + +#filename "Game/" + GAME + "/Techset/PixelShaderCompiler" + GAME + ".cpp" + +#set COMPILER_HEADER "\"PixelShaderCompiler" + GAME + ".h\"" +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" + +#if GAME == "IW3" +#define FEATURE_IW3 +#define IS_DX9 +#define IS_SUB_ASSET +#elif GAME == "IW4" +#define FEATURE_IW4 +#define IS_DX9 +#elif GAME == "IW5" +#define FEATURE_IW5 +#define IS_DX9 +#elif GAME == "T5" +#define FEATURE_T5 +#define IS_DX9 +#define IS_SUB_ASSET +#elif GAME == "T6" +#define FEATURE_T6 +#define IS_DX11 +#define IS_SUB_ASSET +#endif + +#include COMPILER_HEADER + +#include GAME_HEADER +#include "Shader/D3DShaderCompiler.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace GAME; + +#set COMPILER_CLASS_NAME "PixelShaderCompiler" + GAME + +#if defined(IS_SUB_ASSET) +#define ABSTRACT_CREATOR_NAME SubAssetCreator +#define OVERRIDDEN_CREATOR_METHOD CreateSubAsset +#define ADD_ASSET_METHOD AddSubAsset +#define ASSET_NAME SubAssetPixelShader +#define INTERFACE_NAME ISubAssetCreator +#else +#define ABSTRACT_CREATOR_NAME AssetCreator +#define OVERRIDDEN_CREATOR_METHOD CreateAsset +#define ADD_ASSET_METHOD AddAsset +#define ASSET_NAME AssetPixelShader +#define INTERFACE_NAME IAssetCreator +#endif + +namespace +{ + class COMPILER_CLASS_NAME final : public ABSTRACT_CREATOR_NAME + { + public: + COMPILER_CLASS_NAME(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult OVERRIDDEN_CREATOR_METHOD(const std::string& assetName, AssetCreationContext& context) override + { + auto result = shader::CompileShader(assetName, "PSMain", "ps_3_0", false, m_search_path, m_memory); + + if (result.has_value()) + { + const std::optional maybeShader(*std::move(result)); + if (!maybeShader.has_value()) + return AssetCreationResult::NoAction(); + + con::info("Compiled pixel shader \"{}\"", assetName); + + assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0); + + auto* pixelShader = m_memory.Alloc(); + pixelShader->name = m_memory.Dup(assetName.c_str()); + pixelShader->prog.loadDef.program = static_cast(maybeShader->m_shader_bin); + pixelShader->prog.loadDef.programSize = static_cast(maybeShader->m_shader_size / sizeof(uint32_t)); + + return AssetCreationResult::Success(context.ADD_ASSET_METHOD(AssetRegistration(assetName, pixelShader))); + } + + con::error("Failed to compile pixel shader \"{}\": {}", assetName, result.error()); + return AssetCreationResult::Failure(); + } + + void FinalizeZone(AssetCreationContext& context) override {} + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +#set CREATE_COMPILER_METHOD "CreatePixelShaderCompiler" + GAME + +namespace techset +{ + std::unique_ptr CREATE_COMPILER_METHOD(MemoryManager& memory, ISearchPath& searchPath) + { + if (!shader::ShaderCompilationAvailable()) + return nullptr; + + return std::make_unique(memory, searchPath); + } +} // namespace techset diff --git a/src/ObjCompiling/Techset/PixelShaderCompiler.h.template b/src/ObjCompiling/Techset/PixelShaderCompiler.h.template new file mode 100644 index 00000000..8c5f1e81 --- /dev/null +++ b/src/ObjCompiling/Techset/PixelShaderCompiler.h.template @@ -0,0 +1,41 @@ +#options GAME(IW4) + +#filename "Game/" + GAME + "/Techset/PixelShaderCompiler" + GAME + ".h" + +#if GAME == "IW3" +#define FEATURE_IW3 +#define IS_SUB_ASSET +#elif GAME == "IW4" +#define FEATURE_IW4 +#elif GAME == "IW5" +#define FEATURE_IW5 +#elif GAME == "T5" +#define FEATURE_T5 +#define IS_SUB_ASSET +#elif GAME == "T6" +#define FEATURE_T6 +#define IS_SUB_ASSET +#endif + +// This file was templated. +// See PixelShaderCompiler.h.template. +// Do not modify, changes will be lost. +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Utils/MemoryManager.h" + +#include + +#set CREATE_COMPILER_METHOD "CreatePixelShaderCompiler" + GAME + +#if defined(IS_SUB_ASSET) +#define INTERFACE_NAME ISubAssetCreator +#else +#define INTERFACE_NAME IAssetCreator +#endif + +namespace techset +{ + std::unique_ptr CREATE_COMPILER_METHOD(MemoryManager& memory, ISearchPath& searchPath); +} diff --git a/src/ObjCompiling/Techset/VertexShaderCompiler.cpp.template b/src/ObjCompiling/Techset/VertexShaderCompiler.cpp.template new file mode 100644 index 00000000..653421a1 --- /dev/null +++ b/src/ObjCompiling/Techset/VertexShaderCompiler.cpp.template @@ -0,0 +1,112 @@ +#options GAME(IW4) + +#filename "Game/" + GAME + "/Techset/VertexShaderCompiler" + GAME + ".cpp" + +#set COMPILER_HEADER "\"VertexShaderCompiler" + GAME + ".h\"" +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" + +#if GAME == "IW3" +#define FEATURE_IW3 +#define IS_DX9 +#define IS_SUB_ASSET +#elif GAME == "IW4" +#define FEATURE_IW4 +#define IS_DX9 +#elif GAME == "IW5" +#define FEATURE_IW5 +#define IS_DX9 +#elif GAME == "T5" +#define FEATURE_T5 +#define IS_DX9 +#define IS_SUB_ASSET +#elif GAME == "T6" +#define FEATURE_T6 +#define IS_DX11 +#define IS_SUB_ASSET +#endif + +#include COMPILER_HEADER + +#include GAME_HEADER +#include "Shader/D3DShaderCompiler.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include + +using namespace GAME; + +#set COMPILER_CLASS_NAME "VertexShaderCompiler" + GAME + +#if defined(IS_SUB_ASSET) +#define ABSTRACT_CREATOR_NAME SubAssetCreator +#define OVERRIDDEN_CREATOR_METHOD CreateSubAsset +#define ADD_ASSET_METHOD AddSubAsset +#define ASSET_NAME SubAssetVertexShader +#define INTERFACE_NAME ISubAssetCreator +#else +#define ABSTRACT_CREATOR_NAME AssetCreator +#define OVERRIDDEN_CREATOR_METHOD CreateAsset +#define ADD_ASSET_METHOD AddAsset +#define ASSET_NAME AssetVertexShader +#define INTERFACE_NAME IAssetCreator +#endif + +namespace +{ + class COMPILER_CLASS_NAME final : public ABSTRACT_CREATOR_NAME + { + public: + COMPILER_CLASS_NAME(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult OVERRIDDEN_CREATOR_METHOD(const std::string& assetName, AssetCreationContext& context) override + { + auto result = shader::CompileShader(assetName, "VSMain", "vs_3_0", false, m_search_path, m_memory); + + if (result.has_value()) + { + const std::optional maybeShader(*std::move(result)); + if (!maybeShader.has_value()) + return AssetCreationResult::NoAction(); + + con::info("Compiled vertex shader \"{}\"", assetName); + + assert(maybeShader->m_shader_size % sizeof(uint32_t) == 0); + + auto* vertexShader = m_memory.Alloc(); + vertexShader->name = m_memory.Dup(assetName.c_str()); + vertexShader->prog.loadDef.program = static_cast(maybeShader->m_shader_bin); + vertexShader->prog.loadDef.programSize = static_cast(maybeShader->m_shader_size / sizeof(uint32_t)); + + return AssetCreationResult::Success(context.ADD_ASSET_METHOD(AssetRegistration(assetName, vertexShader))); + } + + con::error("Failed to compile vertex shader \"{}\": {}", assetName, result.error()); + return AssetCreationResult::Failure(); + } + + void FinalizeZone(AssetCreationContext& context) override {} + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +#set CREATE_COMPILER_METHOD "CreateVertexShaderCompiler" + GAME + +namespace techset +{ + std::unique_ptr CREATE_COMPILER_METHOD(MemoryManager& memory, ISearchPath& searchPath) + { + if (!shader::ShaderCompilationAvailable()) + return nullptr; + + return std::make_unique(memory, searchPath); + } +} // namespace techset diff --git a/src/ObjCompiling/Techset/VertexShaderCompiler.h.template b/src/ObjCompiling/Techset/VertexShaderCompiler.h.template new file mode 100644 index 00000000..f4076334 --- /dev/null +++ b/src/ObjCompiling/Techset/VertexShaderCompiler.h.template @@ -0,0 +1,41 @@ +#options GAME(IW4) + +#filename "Game/" + GAME + "/Techset/VertexShaderCompiler" + GAME + ".h" + +#if GAME == "IW3" +#define FEATURE_IW3 +#define IS_SUB_ASSET +#elif GAME == "IW4" +#define FEATURE_IW4 +#elif GAME == "IW5" +#define FEATURE_IW5 +#elif GAME == "T5" +#define FEATURE_T5 +#define IS_SUB_ASSET +#elif GAME == "T6" +#define FEATURE_T6 +#define IS_SUB_ASSET +#endif + +// This file was templated. +// See VertexShaderCompiler.h.template. +// Do not modify, changes will be lost. +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Utils/MemoryManager.h" + +#include + +#set CREATE_COMPILER_METHOD "CreateVertexShaderCompiler" + GAME + +#if defined(IS_SUB_ASSET) +#define INTERFACE_NAME ISubAssetCreator +#else +#define INTERFACE_NAME IAssetCreator +#endif + +namespace techset +{ + std::unique_ptr CREATE_COMPILER_METHOD(MemoryManager& memory, ISearchPath& searchPath); +}