From b283695e1c194668b95a3ce51a1fa56b0df561d7 Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Wed, 25 Mar 2026 22:47:50 +0100 Subject: [PATCH] chore: dynamically enable shader compilation if available --- .../IW4/Techset/PixelShaderCompilerIW4.cpp | 94 ++---- .../IW4/Techset/VertexShaderCompilerIW4.cpp | 94 ++---- src/ObjCompiling/Shader/D3DShaderCompiler.cpp | 302 ++++++++++++++++++ src/ObjCompiling/Shader/D3DShaderCompiler.h | 23 ++ .../Techset/ShaderIncludeHandler.cpp | 59 ---- .../Techset/ShaderIncludeHandler.h | 27 -- .../Asset/AssetCreatorCollection.cpp | 12 + 7 files changed, 381 insertions(+), 230 deletions(-) create mode 100644 src/ObjCompiling/Shader/D3DShaderCompiler.cpp create mode 100644 src/ObjCompiling/Shader/D3DShaderCompiler.h delete mode 100644 src/ObjCompiling/Techset/ShaderIncludeHandler.cpp delete mode 100644 src/ObjCompiling/Techset/ShaderIncludeHandler.h diff --git a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp index e59ade53..670790f7 100644 --- a/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp +++ b/src/ObjCompiling/Game/IW4/Techset/PixelShaderCompilerIW4.cpp @@ -1,20 +1,13 @@ #include "PixelShaderCompilerIW4.h" #include "Game/IW4/IW4.h" -#include "Shader/ShaderCommon.h" -#include "Techset/ShaderIncludeHandler.h" +#include "Shader/D3DShaderCompiler.h" #include "Utils/Logging/Log.h" #include #include #include -#ifdef _WIN32 -#include - -#pragma comment(lib, "d3dcompiler.lib") -#endif - using namespace IW4; namespace @@ -30,74 +23,28 @@ namespace AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override { -#ifdef _WIN32 - const auto fileName = shader::GetSourceFileNameForShaderAssetName(assetName); - auto file = m_search_path.Open(fileName); - if (!file.IsOpen() || file.m_length <= 0) - return AssetCreationResult::NoAction(); + auto result = shader::CompileShader(assetName, "PSMain", "ps_3_0", false, m_search_path, m_memory); - if (std::cmp_greater(file.m_length, techset::ShaderIncludeHandler::MAX_SHADER_SIZE)) + if (result.has_value()) { - con::error("Invalid shader source \"{}\": File too big: {}", assetName, file.m_length); - return AssetCreationResult::Failure(); + 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))); } - const auto shaderSize = static_cast(file.m_length); - const auto shaderData = std::make_unique(shaderSize); - file.m_stream->read(shaderData.get(), shaderSize); - file.m_stream.reset(); - - constexpr unsigned shaderFlags = D3DCOMPILE_OPTIMIZATION_LEVEL1 -#ifdef _DEBUG - | D3DCOMPILE_DEBUG -#endif - ; - - techset::ShaderIncludeHandler shaderIncluder(m_search_path); - - ID3DBlob* shaderBlob = nullptr; - ID3DBlob* errorBlob = nullptr; - const auto errorCode = D3DCompile( - shaderData.get(), shaderSize, assetName.c_str(), nullptr, &shaderIncluder, "PSMain", "ps_3_0", shaderFlags, 0u, &shaderBlob, &errorBlob); - - if (FAILED(errorCode)) - { - con::error("Invalid pixel shader \"{}\": Compilation error", assetName); - - if (errorBlob) - { - std::cerr << " " << static_cast(errorBlob->GetBufferPointer()) << "\n"; - errorBlob->Release(); - } - - if (shaderBlob) - shaderBlob->Release(); - - return AssetCreationResult::Failure(); - } - - con::info("Compiled pixel shader \"{}\"", assetName); - - const auto shaderBlobSize = static_cast(shaderBlob->GetBufferSize()); - assert(shaderBlobSize % sizeof(uint32_t) == 0); - - auto* pixelShader = m_memory.Alloc(); - pixelShader->name = m_memory.Dup(assetName.c_str()); - pixelShader->prog.loadDef.programSize = static_cast(shaderBlobSize / sizeof(uint32_t)); - pixelShader->prog.loadDef.loadForRenderer = 0; - pixelShader->prog.ps = nullptr; - - auto* assetShaderBuffer = m_memory.Alloc(shaderBlobSize); - memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize); - pixelShader->prog.loadDef.program = reinterpret_cast(assetShaderBuffer); - - shaderBlob->Release(); - - return AssetCreationResult::Success(context.AddAsset(AssetRegistration(assetName, pixelShader))); -#else - // Shader compilation is only support with Windows - return AssetCreationResult::NoAction(); -#endif + con::error("Failed to compile pixel shader \"{}\": {}", assetName, result.error()); + return AssetCreationResult::Failure(); } void FinalizeZone(AssetCreationContext& context) override {} @@ -112,6 +59,9 @@ 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/VertexShaderCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp index be8181aa..58db1ae4 100644 --- a/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp +++ b/src/ObjCompiling/Game/IW4/Techset/VertexShaderCompilerIW4.cpp @@ -1,20 +1,13 @@ #include "VertexShaderCompilerIW4.h" #include "Game/IW4/IW4.h" -#include "Shader/ShaderCommon.h" -#include "Techset/ShaderIncludeHandler.h" +#include "Shader/D3DShaderCompiler.h" #include "Utils/Logging/Log.h" #include #include #include -#ifdef _WIN32 -#include - -#pragma comment(lib, "d3dcompiler.lib") -#endif - using namespace IW4; namespace @@ -30,74 +23,28 @@ namespace AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override { -#ifdef _WIN32 - const auto fileName = shader::GetSourceFileNameForShaderAssetName(assetName); - auto file = m_search_path.Open(fileName); - if (!file.IsOpen() || file.m_length <= 0) - return AssetCreationResult::NoAction(); + auto result = shader::CompileShader(assetName, "VSMain", "vs_3_0", false, m_search_path, m_memory); - if (std::cmp_greater(file.m_length, techset::ShaderIncludeHandler::MAX_SHADER_SIZE)) + if (result.has_value()) { - con::error("Invalid shader source \"{}\": File too big: {}", assetName, file.m_length); - return AssetCreationResult::Failure(); + 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))); } - const auto shaderSize = static_cast(file.m_length); - const auto shaderData = std::make_unique(shaderSize); - file.m_stream->read(shaderData.get(), shaderSize); - file.m_stream.reset(); - - constexpr unsigned shaderFlags = D3DCOMPILE_OPTIMIZATION_LEVEL1 -#ifdef _DEBUG - | D3DCOMPILE_DEBUG -#endif - ; - - techset::ShaderIncludeHandler shaderIncluder(m_search_path); - - ID3DBlob* shaderBlob = nullptr; - ID3DBlob* errorBlob = nullptr; - const auto errorCode = D3DCompile( - shaderData.get(), shaderSize, assetName.c_str(), nullptr, &shaderIncluder, "VSMain", "vs_3_0", shaderFlags, 0u, &shaderBlob, &errorBlob); - - if (FAILED(errorCode)) - { - con::error("Invalid vertex shader \"{}\": Compilation error", assetName); - - if (errorBlob) - { - std::cerr << " " << static_cast(errorBlob->GetBufferPointer()) << "\n"; - errorBlob->Release(); - } - - if (shaderBlob) - shaderBlob->Release(); - - return AssetCreationResult::Failure(); - } - - con::info("Compiled vertex shader \"{}\"", assetName); - - const auto shaderBlobSize = static_cast(shaderBlob->GetBufferSize()); - assert(shaderBlobSize % sizeof(uint32_t) == 0); - - auto* vertexShader = m_memory.Alloc(); - vertexShader->name = m_memory.Dup(assetName.c_str()); - vertexShader->prog.loadDef.programSize = static_cast(shaderBlobSize / sizeof(uint32_t)); - vertexShader->prog.loadDef.loadForRenderer = 0; - vertexShader->prog.vs = nullptr; - - auto* assetShaderBuffer = m_memory.Alloc(shaderBlobSize); - memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize); - vertexShader->prog.loadDef.program = reinterpret_cast(assetShaderBuffer); - - shaderBlob->Release(); - - return AssetCreationResult::Success(context.AddAsset(AssetRegistration(assetName, vertexShader))); -#else - // Shader compilation is only support with Windows - return AssetCreationResult::NoAction(); -#endif + con::error("Failed to compile vertex shader \"{}\": {}", assetName, result.error()); + return AssetCreationResult::Failure(); } void FinalizeZone(AssetCreationContext& context) override {} @@ -112,6 +59,9 @@ 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/Shader/D3DShaderCompiler.cpp b/src/ObjCompiling/Shader/D3DShaderCompiler.cpp new file mode 100644 index 00000000..9e6e623b --- /dev/null +++ b/src/ObjCompiling/Shader/D3DShaderCompiler.cpp @@ -0,0 +1,302 @@ +#include "D3DShaderCompiler.h" + +#include "Shader/ShaderCommon.h" +#include "Utils/Logging/Log.h" + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +namespace +{ + // The types based on vkd3d which is licensed under the + // GNU Lesser General Public License as published by the Free Software Foundation + // All types are prefixed with OAT_ to not cause conflicts as the original definition may be included + // depending on the platform. + // Types were duplicated to be available on any platform and to not require the corresponding library + // to be installed + + typedef int OAT_HRESULT; +#define OAT_SUCCEEDED(hr) ((OAT_HRESULT)(hr) >= 0) +#define OAT_FAILED(hr) ((OAT_HRESULT)(hr) < 0) + + typedef unsigned int OAT_ULONG; + typedef unsigned long OAT_ULONG_PTR; + typedef OAT_ULONG_PTR OAT_SIZE_T; + +#define OAT_HRESULT_TYPEDEF(x) ((OAT_HRESULT)x) + +#define OAT_S_OK OAT_HRESULT_TYPEDEF(0) +#define OAT_S_FALSE OAT_HRESULT_TYPEDEF(1) + +#define OAT_E_FAIL OAT_HRESULT_TYPEDEF(0x80004005) + +#define OAT_D3DCOMPILE_DEBUG 0x00000001 +#define OAT_D3DCOMPILE_SKIP_VALIDATION 0x00000002 +#define OAT_D3DCOMPILE_SKIP_OPTIMIZATION 0x00000004 +#define OAT_D3DCOMPILE_PACK_MATRIX_ROW_MAJOR 0x00000008 +#define OAT_D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR 0x00000010 +#define OAT_D3DCOMPILE_PARTIAL_PRECISION 0x00000020 +#define OAT_D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT 0x00000040 +#define OAT_D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT 0x00000080 +#define OAT_D3DCOMPILE_NO_PRESHADER 0x00000100 +#define OAT_D3DCOMPILE_AVOID_FLOW_CONTROL 0x00000200 +#define OAT_D3DCOMPILE_PREFER_FLOW_CONTROL 0x00000400 +#define OAT_D3DCOMPILE_ENABLE_STRICTNESS 0x00000800 +#define OAT_D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY 0x00001000 +#define OAT_D3DCOMPILE_IEEE_STRICTNESS 0x00002000 +#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL0 0x00004000 +#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL1 0x00000000 +#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL2 0x0000c000 +#define OAT_D3DCOMPILE_OPTIMIZATION_LEVEL3 0x00008000 +#define OAT_D3DCOMPILE_RESERVED16 0x00010000 +#define OAT_D3DCOMPILE_RESERVED17 0x00020000 +#define OAT_D3DCOMPILE_WARNINGS_ARE_ERRORS 0x00040000 +#define OAT_D3DCOMPILE_RESOURCES_MAY_ALIAS 0x00080000 +#define OAT_D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES 0x00100000 +#define OAT_D3DCOMPILE_ALL_RESOURCES_BOUND 0x00200000 +#define OAT_D3DCOMPILE_DEBUG_NAME_FOR_SOURCE 0x00400000 +#define OAT_D3DCOMPILE_DEBUG_NAME_FOR_BINARY 0x00800000 + + enum OAT_D3D_INCLUDE_TYPE : uint32_t + { + OAT_D3D_INCLUDE_LOCAL = 0, + OAT_D3D_INCLUDE_SYSTEM = 1 + }; + + struct OAT_ID3DInclude + { + virtual OAT_HRESULT __stdcall Open( + OAT_D3D_INCLUDE_TYPE includeType, const char* fileName, const void* parentData, const void** data, unsigned int* size) = 0; + virtual OAT_HRESULT __stdcall Close(const void* data) = 0; + }; + + struct OAT_GUID + { + unsigned int Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; + }; + + typedef OAT_GUID OAT_IID; + + struct OAT_IUnknown + { + virtual OAT_HRESULT __stdcall QueryInterface(const OAT_IID& riid, void** object) = 0; + + virtual OAT_ULONG __stdcall AddRef() = 0; + + virtual OAT_ULONG __stdcall Release() = 0; + }; + + struct OAT_ID3DBlob : OAT_IUnknown + { + virtual void* __stdcall GetBufferPointer() = 0; + + virtual OAT_SIZE_T __stdcall GetBufferSize() = 0; + }; + + struct OAT_D3D_SHADER_MACRO + { + const char* Name; + const char* Definition; + }; + + typedef OAT_HRESULT(__stdcall* D3DCompile_t)(const void* data, + OAT_SIZE_T dataSize, + const char* filename, + const OAT_D3D_SHADER_MACRO* defines, + OAT_ID3DInclude* include, + const char* entrypoint, + const char* target, + unsigned int flags, + unsigned int effectFlags, + OAT_ID3DBlob** shader, + OAT_ID3DBlob** errorMessages); + + constexpr size_t MAX_SHADER_SIZE = 0x1900000u; + + class ShaderIncludeHandler : public OAT_ID3DInclude + { + public: + explicit ShaderIncludeHandler(ISearchPath& searchPath) + : m_search_path(searchPath) + { + } + + OAT_HRESULT + __stdcall Open(OAT_D3D_INCLUDE_TYPE includeType, const char* fileName, const void* parentData, const void** data, unsigned int* size) override + { + const auto fullFileName = shader::GetSourceFileNameForShaderAssetName(fileName); + auto file = m_search_path.Open(fullFileName); + if (!file.IsOpen() || file.m_length <= 0) + return OAT_E_FAIL; + + if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE)) + { + con::error("Invalid shader source \"{}\": File too big: {}\n", fileName, file.m_length); + return OAT_E_FAIL; + } + + const auto shaderSize = static_cast(file.m_length); + auto shaderData = std::make_unique(shaderSize); + file.m_stream->read(shaderData.get(), static_cast(shaderSize)); + file.m_stream.reset(); + + *data = shaderData.get(); + *size = static_cast(shaderSize); + + m_file_buffers_in_use.push_back(std::move(shaderData)); + + return OAT_S_OK; + } + + OAT_HRESULT __stdcall Close(const void* data) override + { + for (auto i = m_file_buffers_in_use.begin(); i != m_file_buffers_in_use.end(); ++i) + { + if (i->get() == data) + { + m_file_buffers_in_use.erase(i); + return OAT_S_OK; + } + } + + return OAT_E_FAIL; + } + + private: + ISearchPath& m_search_path; + std::vector> m_file_buffers_in_use; + }; + + bool initialized = false; + bool compilationAvailable = false; + D3DCompile_t d3dCompile = nullptr; + + void PrintInitializationFailedMessage() + { +#ifdef _WIN32 + con::warn("Could not initialize shader compilation. Make sure DirectX is installed on your machine if you want to make use of it."); +#endif + } + + void InitializeShaderCompilation() + { + initialized = true; + +#ifdef _WIN32 + const auto d3dCompiler = LoadLibraryA("D3DCOMPILER_47.dll"); + if (!d3dCompiler) + { + PrintInitializationFailedMessage(); + return; + } + + const auto d3dCompileAddress = GetProcAddress(d3dCompiler, "D3DCompile"); + if (!d3dCompileAddress) + { + PrintInitializationFailedMessage(); + return; + } + + d3dCompile = reinterpret_cast(d3dCompileAddress); + compilationAvailable = true; +#endif + } +} // namespace + +namespace shader +{ + bool ShaderCompilationAvailable() + { + if (!initialized) + InitializeShaderCompilation(); + + return compilationAvailable; + } + + result::Expected, std::string> CompileShader(const std::string& shaderFile, + const std::string& entryPoint, + const std::string& target, + const bool debug, + ISearchPath& searchPath, + MemoryManager& memory) + { + if (!initialized) + InitializeShaderCompilation(); + if (!compilationAvailable) + return result::Unexpected("Shader compilation unavailable"); + + const auto fileName = GetSourceFileNameForShaderAssetName(shaderFile); + auto file = searchPath.Open(fileName); + if (!file.IsOpen() || file.m_length <= 0) + return std::optional(std::nullopt); + + if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE)) + return result::Unexpected(std::format("File too big: {}", file.m_length)); + + const auto shaderSize = file.m_length; + const auto shaderData = std::make_unique(static_cast(shaderSize)); + file.m_stream->read(shaderData.get(), static_cast(shaderSize)); + file.m_stream.reset(); + + unsigned shaderFlags = OAT_D3DCOMPILE_OPTIMIZATION_LEVEL1; + if (debug) + shaderFlags |= OAT_D3DCOMPILE_DEBUG; + + ShaderIncludeHandler shaderIncluder(searchPath); + + OAT_ID3DBlob* shaderBlob = nullptr; + OAT_ID3DBlob* errorBlob = nullptr; + const auto errorCode = d3dCompile(shaderData.get(), + static_cast(shaderSize), + fileName.c_str(), + nullptr, + &shaderIncluder, + entryPoint.c_str(), + target.c_str(), + shaderFlags, + 0u, + &shaderBlob, + &errorBlob); + + if (OAT_FAILED(errorCode)) + { + std::string errorMessage; + + if (errorBlob) + { + errorMessage = std::format("Compilation error: {}", static_cast(errorBlob->GetBufferPointer())); + errorBlob->Release(); + } + else + { + errorMessage = "Unknown compilation error"; + } + + if (shaderBlob) + shaderBlob->Release(); + + return result::Unexpected(std::move(errorMessage)); + } + + const auto shaderBlobSize = static_cast(shaderBlob->GetBufferSize()); + auto* assetShaderBuffer = memory.Alloc(shaderBlobSize); + memcpy(assetShaderBuffer, shaderBlob->GetBufferPointer(), shaderBlobSize); + + shaderBlob->Release(); + + return std::optional(CompiledShader{ + .m_shader_bin = assetShaderBuffer, + .m_shader_size = shaderBlobSize, + }); + } +} // namespace shader diff --git a/src/ObjCompiling/Shader/D3DShaderCompiler.h b/src/ObjCompiling/Shader/D3DShaderCompiler.h new file mode 100644 index 00000000..c281a80e --- /dev/null +++ b/src/ObjCompiling/Shader/D3DShaderCompiler.h @@ -0,0 +1,23 @@ +#pragma once + +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" +#include "Utils/Result.h" + +#include +#include + +namespace shader +{ + class CompiledShader + { + public: + void* m_shader_bin; + size_t m_shader_size; + }; + + bool ShaderCompilationAvailable(); + + result::Expected, std::string> CompileShader( + const std::string& shaderFile, const std::string& entryPoint, const std::string& target, bool debug, ISearchPath& searchPath, MemoryManager& memory); +} // namespace shader diff --git a/src/ObjCompiling/Techset/ShaderIncludeHandler.cpp b/src/ObjCompiling/Techset/ShaderIncludeHandler.cpp deleted file mode 100644 index a2455715..00000000 --- a/src/ObjCompiling/Techset/ShaderIncludeHandler.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "ShaderIncludeHandler.h" - -#include "Shader/ShaderCommon.h" -#include "Utils/Logging/Log.h" - -#include -#include - -#ifdef _WIN32 - -namespace techset -{ - ShaderIncludeHandler::ShaderIncludeHandler(ISearchPath& searchPath) - : m_search_path(searchPath) - { - } - - HRESULT ShaderIncludeHandler::Open(D3D_INCLUDE_TYPE includeType, const LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) - { - const auto fileName = shader::GetSourceFileNameForShaderAssetName(pFileName); - auto file = m_search_path.Open(fileName); - if (!file.IsOpen() || file.m_length <= 0) - return E_FAIL; - - if (std::cmp_greater(file.m_length, MAX_SHADER_SIZE)) - { - con::error("Invalid shader source \"{}\": File too big: {}\n", pFileName, file.m_length); - return E_FAIL; - } - - const auto shaderSize = static_cast(file.m_length); - auto shaderData = std::make_unique(shaderSize); - file.m_stream->read(shaderData.get(), static_cast(shaderSize)); - file.m_stream.reset(); - - *ppData = shaderData.get(); - *pBytes = static_cast(shaderSize); - - m_file_buffers_in_use.push_back(std::move(shaderData)); - - return S_OK; - } - - HRESULT ShaderIncludeHandler::Close(const LPCVOID pData) - { - for (auto i = m_file_buffers_in_use.begin(); i != m_file_buffers_in_use.end(); ++i) - { - if (i->get() == pData) - { - m_file_buffers_in_use.erase(i); - return S_OK; - } - } - - return E_FAIL; - } -} // namespace techset - -#endif diff --git a/src/ObjCompiling/Techset/ShaderIncludeHandler.h b/src/ObjCompiling/Techset/ShaderIncludeHandler.h deleted file mode 100644 index e9558521..00000000 --- a/src/ObjCompiling/Techset/ShaderIncludeHandler.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "SearchPath/ISearchPath.h" - -// Shader compilation only available on Windows -#ifdef _WIN32 -#include - -namespace techset -{ - class ShaderIncludeHandler : public ID3DInclude - { - public: - static constexpr size_t MAX_SHADER_SIZE = 0x1900000u; - - explicit ShaderIncludeHandler(ISearchPath& searchPath); - virtual ~ShaderIncludeHandler() = default; - - HRESULT __declspec(nothrow) __stdcall Open(D3D_INCLUDE_TYPE includeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) override; - HRESULT __declspec(nothrow) __stdcall Close(LPCVOID pData) override; - - private: - ISearchPath& m_search_path; - std::vector> m_file_buffers_in_use; - }; -} // namespace techset -#endif diff --git a/src/ObjLoading/Asset/AssetCreatorCollection.cpp b/src/ObjLoading/Asset/AssetCreatorCollection.cpp index 3edaabaa..d6208bbc 100644 --- a/src/ObjLoading/Asset/AssetCreatorCollection.cpp +++ b/src/ObjLoading/Asset/AssetCreatorCollection.cpp @@ -13,6 +13,9 @@ AssetCreatorCollection::AssetCreatorCollection(const Zone& zone) void AssetCreatorCollection::AddAssetCreator(std::unique_ptr creator) { + if (!creator) + return; + const auto maybeHandlingAssetType = creator->GetHandlingAssetType(); assert(!maybeHandlingAssetType || static_cast(*maybeHandlingAssetType) < m_asset_creators_by_type.size()); if (maybeHandlingAssetType && static_cast(*maybeHandlingAssetType) < m_asset_creators_by_type.size()) @@ -23,6 +26,9 @@ void AssetCreatorCollection::AddAssetCreator(std::unique_ptr crea void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr creator) { + if (!creator) + return; + const auto maybeHandlingSubAssetType = creator->GetHandlingSubAssetType(); assert(!maybeHandlingSubAssetType || static_cast(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size()); if (maybeHandlingSubAssetType && static_cast(*maybeHandlingSubAssetType) < m_sub_asset_creators_by_type.size()) @@ -33,6 +39,9 @@ void AssetCreatorCollection::AddSubAssetCreator(std::unique_ptr postProcessor) { + if (!postProcessor) + return; + const auto handlingAssetType = postProcessor->GetHandlingAssetType(); assert(static_cast(handlingAssetType) < m_asset_post_processors_by_type.size()); if (static_cast(handlingAssetType) < m_asset_post_processors_by_type.size()) @@ -43,6 +52,9 @@ void AssetCreatorCollection::AddAssetPostProcessor(std::unique_ptr defaultAssetCreator) { + if (!defaultAssetCreator) + return; + const auto handlingAssetType = defaultAssetCreator->GetHandlingAssetType(); assert(static_cast(handlingAssetType) < m_default_asset_creators_by_type.size()); assert(!m_default_asset_creators_by_type[handlingAssetType]);