Skip to content

Commit

Permalink
GraphicsTools: added ShaderSourceFactoryUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 6, 2023
1 parent d10f516 commit e9d856b
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Graphics/GraphicsTools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(INTERFACE
interface/ScreenCapture.hpp
interface/ShaderMacroHelper.hpp
interface/StreamingBuffer.hpp
interface/ShaderSourceFactoryUtils.h
interface/TextureUploader.hpp
interface/TextureUploaderBase.hpp
interface/XXH128Hasher.hpp
Expand All @@ -34,6 +35,7 @@ set(SOURCE
src/GraphicsUtilities.cpp
src/ScopedQueryHelper.cpp
src/ScreenCapture.cpp
src/ShaderSourceFactoryUtils.cpp
src/TextureUploader.cpp
src/XXH128Hasher.cpp
src/VertexPool.cpp
Expand Down
107 changes: 107 additions & 0 deletions Graphics/GraphicsTools/interface/ShaderSourceFactoryUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright 2023 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#pragma once

/// \file
/// Defines graphics engine utilities

#include "../../GraphicsEngine/interface/Shader.h"

DILIGENT_BEGIN_NAMESPACE(Diligent)

#include "../../Primitives/interface/DefineGlobalFuncHelperMacros.h"

/// Shader source file substitute info.
struct ShaderSourceFileSubstitueInfo
{
/// Source file name.
const Char* Name DEFAULT_INITIALIZER(nullptr);

/// Substitute file name.
const Char* Substitute DEFAULT_INITIALIZER(nullptr);

#if DILIGENT_CPP_INTERFACE
constexpr ShaderSourceFileSubstitueInfo() noexcept
{}

constexpr ShaderSourceFileSubstitueInfo(const Char* _Name, const Char* _Substitute) noexcept :
Name{_Name},
Substitute{_Substitute}
{}
#endif
};

/// Compound shader source factory create info.
struct CompoundShaderSourceFactoryCreateInfo
{
/// An array of shader source input stream factories.
IShaderSourceInputStreamFactory** ppFactories DEFAULT_INITIALIZER(nullptr);

/// The number of factories in ppFactories array.
Uint32 NumFactories DEFAULT_INITIALIZER(0);

/// An array of shader source file substitutes.
ShaderSourceFileSubstitueInfo* pFileSubstitutes DEFAULT_INITIALIZER(nullptr);

/// The number of file substitutes in pFileSubstitutes array.
Uint32 NumFileSubstitutes DEFAULT_INITIALIZER(0);

#if DILIGENT_CPP_INTERFACE
constexpr CompoundShaderSourceFactoryCreateInfo() noexcept
{}

constexpr CompoundShaderSourceFactoryCreateInfo(IShaderSourceInputStreamFactory** _ppFactories,
Uint32 _NumFactories,
ShaderSourceFileSubstitueInfo* _pFileSubstitutes = nullptr,
Uint32 _NumFileSubstitutes = 0) noexcept :
ppFactories{_ppFactories},
NumFactories{_NumFactories},
pFileSubstitutes{_pFileSubstitutes},
NumFileSubstitutes{_NumFileSubstitutes}
{}
#endif
};
typedef struct CompoundShaderSourceFactoryCreateInfo CompoundShaderSourceFactoryCreateInfo;
// clang-format on

/// Creates a compound shader source factory.
///
/// \param [in] CreateInfo - Compound shader source factory create info, see Diligent::CompoundShaderSourceFactoryCreateInfo.
/// \param [out] ppFactory - Address of the memory location where the pointer to the created factory will be written.
///
/// \remarks Compound shader source stream factory is a wrapper around multiple shader source stream factories.
/// It is used to combine multiple shader source stream factories into a single one. When a source file
/// is requested, the factory will iterate over all factories in the array and return the first one that
/// returns a non-null stream.
///
/// 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);

#include "../../Primitives/interface/UndefGlobalFuncHelperMacros.h"

DILIGENT_END_NAMESPACE // namespace Diligent
124 changes: 124 additions & 0 deletions Graphics/GraphicsTools/src/ShaderSourceFactoryUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright 2023 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#include "ShaderSourceFactoryUtils.h"

#include <vector>
#include <unordered_map>

#include "ObjectBase.hpp"
#include "HashUtils.hpp"
#include "RefCntAutoPtr.hpp"

namespace Diligent
{

class CompoundShaderSourceFactory : public ObjectBase<IShaderSourceInputStreamFactory>
{
public:
using TBase = ObjectBase<IShaderSourceInputStreamFactory>;

static RefCntAutoPtr<IShaderSourceInputStreamFactory> Create(const CompoundShaderSourceFactoryCreateInfo& CreateInfo)
{
return RefCntAutoPtr<IShaderSourceInputStreamFactory>{MakeNewRCObj<CompoundShaderSourceFactory>()(CreateInfo)};
}

CompoundShaderSourceFactory(IReferenceCounters* pRefCounters,
const CompoundShaderSourceFactoryCreateInfo& CI) :
TBase{pRefCounters}
{
if (CI.ppFactories != nullptr)
{
m_pFactories.reserve(CI.NumFactories);
for (Uint32 i = 0; i < CI.NumFactories; ++i)
{
m_pFactories.emplace_back(CI.ppFactories[i]);
}
}

if (CI.pFileSubstitutes != nullptr)
{
for (Uint32 i = 0; i < CI.NumFileSubstitutes; ++i)
{
m_FileSubstituteMap.emplace(HashMapStringKey{CI.pFileSubstitutes[i].Name, true}, CI.pFileSubstitutes[i].Substitute);
}
}
}

IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_IShaderSourceInputStreamFactory, TBase)

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
{
VERIFY_EXPR(ppStream != nullptr && *ppStream == nullptr);
if (!m_FileSubstituteMap.empty())
{
auto it = m_FileSubstituteMap.find(Name);
if (it != m_FileSubstituteMap.end())
Name = it->second.c_str();
}

for (size_t i = 0; i < m_pFactories.size() && *ppStream == nullptr; ++i)
{
if (m_pFactories[i])
m_pFactories[i]->CreateInputStream2(Name, CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_SILENT, ppStream);
}

if (*ppStream == nullptr && (Flags & CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_SILENT) != 0)
{
LOG_ERROR("Failed to create input stream for source file ", Name);
}
}

private:
std::vector<RefCntAutoPtr<IShaderSourceInputStreamFactory>> m_pFactories;

std::unordered_map<HashMapStringKey, std::string> m_FileSubstituteMap;
};

void CreateCompoundShaderSourceFactory(const CompoundShaderSourceFactoryCreateInfo& CreateInfo, IShaderSourceInputStreamFactory** ppFactory)
{
auto pFactory = CompoundShaderSourceFactory::Create(CreateInfo);
pFactory->QueryInterface(IID_IShaderSourceInputStreamFactory, reinterpret_cast<IObject**>(ppFactory));
}

} // namespace Diligent

extern "C"
{
void Diligent_CreateCompoundShaderSourceFactory(const Diligent::CompoundShaderSourceFactoryCreateInfo& CreateInfo,
Diligent::IShaderSourceInputStreamFactory** ppFactory)
{
Diligent::CreateCompoundShaderSourceFactory(CreateInfo, ppFactory);
}
}

0 comments on commit e9d856b

Please sign in to comment.