From fb3a0b0e84415559bb90c7a375c56a34d5e99e3e Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 5 Oct 2023 21:27:27 -0700 Subject: [PATCH] ShaderSourceFactoryUtils: added MemoryShaderSourceFactory --- .../interface/ShaderSourceFactoryUtils.h | 71 +++++++++++++- .../src/ShaderSourceFactoryUtils.cpp | 92 +++++++++++++++++++ 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/Graphics/GraphicsTools/interface/ShaderSourceFactoryUtils.h b/Graphics/GraphicsTools/interface/ShaderSourceFactoryUtils.h index 00e6e3e172..e23ca84113 100644 --- a/Graphics/GraphicsTools/interface/ShaderSourceFactoryUtils.h +++ b/Graphics/GraphicsTools/interface/ShaderSourceFactoryUtils.h @@ -54,6 +54,8 @@ struct ShaderSourceFileSubstitueInfo {} #endif }; +typedef struct ShaderSourceFileSubstitueInfo ShaderSourceFileSubstitueInfo; + /// Compound shader source factory create info. struct CompoundShaderSourceFactoryCreateInfo @@ -86,7 +88,7 @@ struct CompoundShaderSourceFactoryCreateInfo #endif }; typedef struct CompoundShaderSourceFactoryCreateInfo CompoundShaderSourceFactoryCreateInfo; -// clang-format on + /// Creates a compound shader source factory. /// @@ -100,7 +102,72 @@ typedef struct CompoundShaderSourceFactoryCreateInfo CompoundShaderSourceFactory /// /// The factory also allows substituting source file names. This is useful when the same shader source /// is used for multiple shaders, but some of them require a modified version of the source. -void DILIGENT_GLOBAL_FUNCTION(CreateCompoundShaderSourceFactory)(const CompoundShaderSourceFactoryCreateInfo REF CreateInfo, IShaderSourceInputStreamFactory** ppFactory); +void DILIGENT_GLOBAL_FUNCTION(CreateCompoundShaderSourceFactory)(const CompoundShaderSourceFactoryCreateInfo REF CreateInfo, + IShaderSourceInputStreamFactory** ppFactory); + + +/// Shader source file info. +struct MemoryShaderSourceFileInfo +{ + /// File name. + const Char* Name DEFAULT_INITIALIZER(nullptr); + + /// Shader source. + const Char* pData DEFAULT_INITIALIZER(nullptr); + + /// Shader source length. If 0, the length will be calculated automatically + /// assuming that the source is null-terminated. + Uint32 Lenth DEFAULT_INITIALIZER(0); + +#if DILIGENT_CPP_INTERFACE + constexpr MemoryShaderSourceFileInfo() noexcept + {} + + constexpr MemoryShaderSourceFileInfo(const Char* _Name, + const Char* _pData, + Uint32 _Length = 0) noexcept : + Name{_Name}, + pData{_pData}, + Lenth{_Length} + {} +#endif +}; +typedef struct MemoryShaderSourceFileInfo MemoryShaderSourceFileInfo; + + +/// Memory shader source factory create info. +struct MemoryShaderSourceFactoryCreateInfo +{ + /// An array of shader source files. + MemoryShaderSourceFileInfo* pSources DEFAULT_INITIALIZER(nullptr); + + /// The number of files in pSources array. + Uint32 NumSources DEFAULT_INITIALIZER(0); + + /// Whether to copy shader sources. If false, the factory will assume that + /// the source data will remain valid for the lifetime of the factory. + Bool CopySources DEFAULT_INITIALIZER(False); + +#if DILIGENT_CPP_INTERFACE + constexpr MemoryShaderSourceFactoryCreateInfo() noexcept + {} + + constexpr MemoryShaderSourceFactoryCreateInfo(MemoryShaderSourceFileInfo* _pSources, + Uint32 _NumSources) noexcept : + pSources{_pSources}, + NumSources{_NumSources} + {} +#endif +}; +typedef struct MemoryShaderSourceFactoryCreateInfo MemoryShaderSourceFactoryCreateInfo; + +/// Crates a memory shader source factory. +/// +/// \param [in] CreateInfo - Memory shader source factory create info, see Diligent::MemoryShaderSourceFactoryCreateInfo. +/// \param [out] ppFactory - Address of the memory location where the pointer to the created factory will be written. +void DILIGENT_GLOBAL_FUNCTION(CreateMemoryShaderSourceFactory)(const MemoryShaderSourceFactoryCreateInfo REF CreateInfo, + IShaderSourceInputStreamFactory** ppFactory); + #include "../../Primitives/interface/UndefGlobalFuncHelperMacros.h" diff --git a/Graphics/GraphicsTools/src/ShaderSourceFactoryUtils.cpp b/Graphics/GraphicsTools/src/ShaderSourceFactoryUtils.cpp index 58d67583dd..c5fbccc110 100644 --- a/Graphics/GraphicsTools/src/ShaderSourceFactoryUtils.cpp +++ b/Graphics/GraphicsTools/src/ShaderSourceFactoryUtils.cpp @@ -28,10 +28,13 @@ #include #include +#include #include "ObjectBase.hpp" #include "HashUtils.hpp" #include "RefCntAutoPtr.hpp" +#include "StringDataBlobImpl.hpp" +#include "MemoryFileStream.hpp" namespace Diligent { @@ -112,6 +115,89 @@ void CreateCompoundShaderSourceFactory(const CompoundShaderSourceFactoryCreateIn pFactory->QueryInterface(IID_IShaderSourceInputStreamFactory, reinterpret_cast(ppFactory)); } + + + +class MemoryShaderSourceFactory final : public ObjectBase +{ +public: + using TBase = ObjectBase; + + static RefCntAutoPtr Create(const MemoryShaderSourceFactoryCreateInfo& CreateInfo) + { + return RefCntAutoPtr{MakeNewRCObj()(CreateInfo)}; + } + + MemoryShaderSourceFactory(IReferenceCounters* pRefCounters, + const MemoryShaderSourceFactoryCreateInfo& CI) : + TBase{pRefCounters} + { + if (CI.CopySources) + { + m_Sources.resize(CI.NumSources); + for (Uint32 i = 0; i < CI.NumSources; ++i) + { + const auto& Source = CI.pSources[i]; + if (Source.Lenth > 0) + { + m_Sources[i].assign(Source.pData, Source.Lenth); + } + else + { + m_Sources[i] = Source.pData; + } + } + } + + for (Uint32 i = 0; i < CI.NumSources; ++i) + { + const auto& Source = CI.pSources[i]; + m_NameToSourceMap.emplace(HashMapStringKey{Source.Name, true}, CI.CopySources ? m_Sources[i].c_str() : Source.pData); + } + } + + virtual void DILIGENT_CALL_TYPE CreateInputStream(const Char* Name, IFileStream** ppStream) override final + { + CreateInputStream2(Name, CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_NONE, ppStream); + } + + virtual void DILIGENT_CALL_TYPE CreateInputStream2(const Char* Name, + CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS Flags, + IFileStream** ppStream) override final + { + auto SourceIt = m_NameToSourceMap.find(Name); + if (SourceIt != m_NameToSourceMap.end()) + { + RefCntAutoPtr pDataBlob{MakeNewRCObj()(SourceIt->second)}; + RefCntAutoPtr pMemStream{MakeNewRCObj()(pDataBlob)}; + + pMemStream->QueryInterface(IID_FileStream, reinterpret_cast(ppStream)); + } + else + { + *ppStream = nullptr; + if ((Flags & CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_SILENT) == 0) + { + LOG_ERROR("Failed to create input stream for source file ", Name); + } + } + } + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_IShaderSourceInputStreamFactory, TBase) + +private: + std::vector m_Sources; + + std::unordered_map m_NameToSourceMap; +}; + +void CreateMemoryShaderSourceFactory(const MemoryShaderSourceFactoryCreateInfo& CreateInfo, IShaderSourceInputStreamFactory** ppFactory) +{ + auto pFactory = MemoryShaderSourceFactory::Create(CreateInfo); + pFactory->QueryInterface(IID_IShaderSourceInputStreamFactory, reinterpret_cast(ppFactory)); +} + + } // namespace Diligent extern "C" @@ -121,4 +207,10 @@ extern "C" { Diligent::CreateCompoundShaderSourceFactory(CreateInfo, ppFactory); } + + void Diligent_CreateMemoryShaderSourceFactory(const Diligent::MemoryShaderSourceFactoryCreateInfo& CreateInfo, + Diligent::IShaderSourceInputStreamFactory** ppFactory) + { + Diligent::CreateMemoryShaderSourceFactory(CreateInfo, ppFactory); + } }