diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-09-14 20:05:43 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-09-14 20:05:43 +0000 |
| commit | e4741db660acac220bbb5d357baedcf4cf4060ca (patch) | |
| tree | 5857672d2f6f25a763cdae4b179a891f495eb7b7 /Graphics | |
| parent | Fixed UWP build (diff) | |
| download | DiligentCore-e4741db660acac220bbb5d357baedcf4cf4060ca.tar.gz DiligentCore-e4741db660acac220bbb5d357baedcf4cf4060ca.zip | |
Refactoring shader compilation - part II
Diffstat (limited to 'Graphics')
| -rw-r--r-- | Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp | 107 | ||||
| -rw-r--r-- | Graphics/ShaderTools/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | Graphics/ShaderTools/include/GLSLUtils.hpp | 2 | ||||
| -rw-r--r-- | Graphics/ShaderTools/include/HLSLUtils.hpp | 40 | ||||
| -rw-r--r-- | Graphics/ShaderTools/include/ShaderToolsCommon.hpp | 14 | ||||
| -rw-r--r-- | Graphics/ShaderTools/src/DXCompiler.cpp | 69 | ||||
| -rw-r--r-- | Graphics/ShaderTools/src/GLSLUtils.cpp | 24 | ||||
| -rw-r--r-- | Graphics/ShaderTools/src/GLSLangUtils.cpp | 45 | ||||
| -rw-r--r-- | Graphics/ShaderTools/src/HLSLUtils.cpp | 68 | ||||
| -rw-r--r-- | Graphics/ShaderTools/src/ShaderToolsCommon.cpp | 56 |
10 files changed, 217 insertions, 213 deletions
diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp index 2e1bc23f..97691879 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp @@ -39,75 +39,11 @@ #include "RefCntAutoPtr.hpp" #include "ShaderD3DBase.hpp" #include "DXCompiler.hpp" +#include "HLSLUtils.hpp" namespace Diligent { -namespace -{ - -static const Char* g_HLSLDefinitions = { -#include "HLSLDefinitions_inc.fxh" -}; - -static std::vector<D3D_SHADER_MACRO> GetD3DShaderMacros(const ShaderCreateInfo& ShaderCI) -{ - std::vector<D3D_SHADER_MACRO> D3DMacros; - switch (ShaderCI.Desc.ShaderType) - { - case SHADER_TYPE_VERTEX: - D3DMacros.push_back({"VERTEX_SHADER", "1"}); - break; - - case SHADER_TYPE_PIXEL: - D3DMacros.push_back({"FRAGMENT_SHADER", "1"}); - D3DMacros.push_back({"PIXEL_SHADER", "1"}); - break; - - case SHADER_TYPE_GEOMETRY: - D3DMacros.push_back({"GEOMETRY_SHADER", "1"}); - break; - - case SHADER_TYPE_HULL: - D3DMacros.push_back({"TESS_CONTROL_SHADER", "1"}); - D3DMacros.push_back({"HULL_SHADER", "1"}); - break; - - case SHADER_TYPE_DOMAIN: - D3DMacros.push_back({"TESS_EVALUATION_SHADER", "1"}); - D3DMacros.push_back({"DOMAIN_SHADER", "1"}); - break; - - case SHADER_TYPE_COMPUTE: - D3DMacros.push_back({"COMPUTE_SHADER", "1"}); - break; - - case SHADER_TYPE_AMPLIFICATION: - D3DMacros.push_back({"TASK_SHADER", "1"}); - D3DMacros.push_back({"AMPLIFICATION_SHADER", "1"}); - break; - - case SHADER_TYPE_MESH: - D3DMacros.push_back({"MESH_SHADER", "1"}); - break; - - default: UNEXPECTED("Unexpected shader type"); - } - - if (ShaderCI.Macros) - { - for (auto* pCurrMacro = ShaderCI.Macros; pCurrMacro->Name && pCurrMacro->Definition; ++pCurrMacro) - { - D3DMacros.push_back({pCurrMacro->Name, pCurrMacro->Definition}); - } - } - - D3DMacros.push_back({nullptr, nullptr}); - - return D3DMacros; -} - - static HRESULT CompileDxilShader(IDXCompiler* DxCompiler, const char* Source, size_t SourceLength, @@ -118,9 +54,6 @@ static HRESULT CompileDxilShader(IDXCompiler* DxCompiler, { VERIFY_EXPR(DxCompiler != nullptr); - const auto D3DMacros = GetD3DShaderMacros(ShaderCI); - - std::vector<DxcDefine> DxcMacros; std::vector<std::unique_ptr<wchar_t[]>> StringPool; auto UTF8ToUTF16 = [&StringPool](LPCSTR lpUTF8) // @@ -134,14 +67,6 @@ static HRESULT CompileDxilShader(IDXCompiler* DxCompiler, return StringPool.back().get(); }; - for (const auto& Macro : D3DMacros) - { - if (Macro.Name == nullptr || Macro.Definition == nullptr) - break; - - DxcMacros.emplace_back(DxcDefine{UTF8ToUTF16(Macro.Name), UTF8ToUTF16(Macro.Definition)}); - } - const wchar_t* pArgs[] = { L"-Zpc", // Matrices in column-major order @@ -163,8 +88,6 @@ static HRESULT CompileDxilShader(IDXCompiler* DxCompiler, CA.SourceLength = static_cast<Uint32>(SourceLength); CA.EntryPoint = UTF8ToUTF16(ShaderCI.EntryPoint); CA.Profile = UTF8ToUTF16(profile); - CA.pDefines = DxcMacros.data(); - CA.DefinesCount = static_cast<Uint32>(DxcMacros.size()); CA.pArgs = pArgs; CA.ArgsCount = _countof(pArgs); CA.pShaderSourceStreamFactory = ShaderCI.pShaderSourceStreamFactory; @@ -225,8 +148,6 @@ static HRESULT CompileShader(const char* Source, ID3DBlob** ppBlobOut, ID3DBlob** ppCompilerOutput) { - std::vector<D3D_SHADER_MACRO> D3DMacros = GetD3DShaderMacros(ShaderCI); - DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined(DILIGENT_DEBUG) // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders. @@ -241,12 +162,9 @@ static HRESULT CompileShader(const char* Source, #endif D3DIncludeImpl IncludeImpl(ShaderCI.pShaderSourceStreamFactory); - return D3DCompile(Source, SourceLength, NULL, D3DMacros.data(), &IncludeImpl, ShaderCI.EntryPoint, profile, dwShaderFlags, 0, ppBlobOut, ppCompilerOutput); + return D3DCompile(Source, SourceLength, NULL, nullptr, &IncludeImpl, ShaderCI.EntryPoint, profile, dwShaderFlags, 0, ppBlobOut, ppCompilerOutput); } -} // namespace - - ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const ShaderVersion ShaderModel, IDXCompiler* DxCompiler) { if (ShaderCI.Source || ShaderCI.FilePath) @@ -288,26 +206,7 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const ShaderVersi strShaderProfile += "_"; strShaderProfile += std::to_string(ShaderModel.Minor); - String ShaderSource(g_HLSLDefinitions); - if (ShaderCI.Source) - { - DEV_CHECK_ERR(ShaderCI.FilePath == nullptr, "'FilePath' is expected to be null when shader source code is provided"); - ShaderSource.append(ShaderCI.Source); - } - else - { - DEV_CHECK_ERR(ShaderCI.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - ShaderCI.pShaderSourceStreamFactory->CreateInputStream(ShaderCI.FilePath, &pSourceStream); - RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); - if (pSourceStream == nullptr) - LOG_ERROR_AND_THROW("Failed to open shader source file"); - pSourceStream->ReadBlob(pFileData); - // Null terminator is not read from the stream! - auto* FileDataPtr = static_cast<Char*>(pFileData->GetDataPtr()); - auto Size = pFileData->GetSize(); - ShaderSource.append(FileDataPtr, FileDataPtr + Size / sizeof(*FileDataPtr)); - } + String ShaderSource = BuildHLSLSourceString(ShaderCI); DEV_CHECK_ERR(ShaderCI.EntryPoint != nullptr, "Entry point must not be null"); diff --git a/Graphics/ShaderTools/CMakeLists.txt b/Graphics/ShaderTools/CMakeLists.txt index 8ad4b38a..8a23ea6a 100644 --- a/Graphics/ShaderTools/CMakeLists.txt +++ b/Graphics/ShaderTools/CMakeLists.txt @@ -15,6 +15,11 @@ if(VULKAN_SUPPORTED OR GL_SUPPORTED OR GLES_SUPPORTED) list(APPEND INCLUDE include/GLSLUtils.hpp) endif() +if(D3D11_SUPPORTED OR D3D12_SUPPORTED OR VULKAN_SUPPORTED) + list(APPEND SOURCE src/HLSLUtils.cpp) + list(APPEND INCLUDE include/HLSLUtils.hpp) +endif() + if(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS OR PLATFORM_LINUX) set(DXC_SUPPORTED TRUE) endif() diff --git a/Graphics/ShaderTools/include/GLSLUtils.hpp b/Graphics/ShaderTools/include/GLSLUtils.hpp index 115155eb..4c8b92c8 100644 --- a/Graphics/ShaderTools/include/GLSLUtils.hpp +++ b/Graphics/ShaderTools/include/GLSLUtils.hpp @@ -40,7 +40,7 @@ enum TargetGLSLCompiler driver }; -String BuildGLSLSourceString(const ShaderCreateInfo& CreationAttribs, +String BuildGLSLSourceString(const ShaderCreateInfo& ShaderCI, const DeviceCaps& deviceCaps, TargetGLSLCompiler TargetCompiler, const char* ExtraDefinitions = nullptr); diff --git a/Graphics/ShaderTools/include/HLSLUtils.hpp b/Graphics/ShaderTools/include/HLSLUtils.hpp new file mode 100644 index 00000000..8d8774f5 --- /dev/null +++ b/Graphics/ShaderTools/include/HLSLUtils.hpp @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * 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 + +#include "BasicTypes.h" +#include "GraphicsTypes.h" +#include "Shader.h" + +namespace Diligent +{ + +String BuildHLSLSourceString(const ShaderCreateInfo& ShaderCI, + const char* ExtraDefinitions = nullptr); + +} // namespace Diligent diff --git a/Graphics/ShaderTools/include/ShaderToolsCommon.hpp b/Graphics/ShaderTools/include/ShaderToolsCommon.hpp index 4108d319..f75b9fe7 100644 --- a/Graphics/ShaderTools/include/ShaderToolsCommon.hpp +++ b/Graphics/ShaderTools/include/ShaderToolsCommon.hpp @@ -29,6 +29,8 @@ #include "GraphicsTypes.h" #include "Shader.h" +#include "RefCntAutoPtr.hpp" +#include "DataBlob.h" namespace Diligent { @@ -65,4 +67,16 @@ void AppendShaderMacros(std::string& Source, const ShaderMacro* Macros); /// etc. void AppendShaderTypeDefinitions(std::string& Source, SHADER_TYPE Type); + +/// Reads shader source code from a file or uses the one from the shader create info +const char* ReadShaderSourceFile(const char* SourceCode, + IShaderSourceInputStreamFactory* pShaderSourceStreamFactory, + const char* FilePath, + RefCntAutoPtr<IDataBlob>& pFileData, + size_t& SourceCodeLen) noexcept(false); + +/// Appends shader source code to the source string +void AppendShaderSourceCode(std::string& Source, const ShaderCreateInfo& ShaderCI) noexcept(false); + + } // namespace Diligent diff --git a/Graphics/ShaderTools/src/DXCompiler.cpp b/Graphics/ShaderTools/src/DXCompiler.cpp index 322574a2..80235f65 100644 --- a/Graphics/ShaderTools/src/DXCompiler.cpp +++ b/Graphics/ShaderTools/src/DXCompiler.cpp @@ -48,6 +48,8 @@ # include <d3d12shader.h> #endif +#include "HLSLUtils.hpp" + namespace Diligent { @@ -403,67 +405,16 @@ void DXCompilerImpl::GetD3D12ShaderReflection(IDxcBlob* pShaderBy #if VULKAN_SUPPORTED -// Implemented in GLSLSourceBuilder.cpp -const char* GetShaderTypeDefines(SHADER_TYPE Type); - -namespace -{ - -// clang-format off -static const char g_HLSLDefinitions[] = -{ -#include "../../GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh" -}; -// clang-format on - -} // namespace std::vector<uint32_t> DXILtoSPIRV(IDXCompiler* pLibrary, - const ShaderCreateInfo& Attribs, + const ShaderCreateInfo& ShaderCI, const char* ExtraDefinitions, IDataBlob** ppCompilerOutput) noexcept(false) { - RefCntAutoPtr<IDataBlob> pFileData{MakeNewRCObj<DataBlobImpl>()(0)}; - const char* SourceCode = 0; - int SourceCodeLen = 0; - if (Attribs.Source) - { - SourceCode = Attribs.Source; - SourceCodeLen = static_cast<int>(strlen(Attribs.Source)); - } - else - { - VERIFY(Attribs.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - Attribs.pShaderSourceStreamFactory->CreateInputStream(Attribs.FilePath, &pSourceStream); - if (pSourceStream == nullptr) - LOG_ERROR_AND_THROW("Failed to open shader source file"); - - pSourceStream->ReadBlob(pFileData); - SourceCode = reinterpret_cast<char*>(pFileData->GetDataPtr()); - SourceCodeLen = static_cast<int>(pFileData->GetSize()); - } - - std::string Source; - Source.reserve(SourceCodeLen + sizeof(g_HLSLDefinitions)); - - Source.append(g_HLSLDefinitions); - AppendShaderTypeDefinitions(Source, Attribs.Desc.ShaderType); - - if (ExtraDefinitions != nullptr) - Source += ExtraDefinitions; - - if (Attribs.Macros != nullptr) - { - Source += '\n'; - AppendShaderMacros(Source, Attribs.Macros); - } - - Source.append(SourceCode, SourceCodeLen); // validate shader version - ShaderVersion ShaderModel = Attribs.HLSLVersion; + ShaderVersion ShaderModel = ShaderCI.HLSLVersion; ShaderVersion MaxSM = pLibrary->GetMaxShaderModel(); if (ShaderModel.Major < 6 || ShaderModel.Major > MaxSM.Major) @@ -473,7 +424,7 @@ std::vector<uint32_t> DXILtoSPIRV(IDXCompiler* pLibrary, ShaderModel = MaxSM; std::wstring Profile; - switch (Attribs.Desc.ShaderType) + switch (ShaderCI.Desc.ShaderType) { // clang-format off case SHADER_TYPE_VERTEX: Profile = L"vs_"; break; @@ -506,16 +457,18 @@ std::vector<uint32_t> DXILtoSPIRV(IDXCompiler* pLibrary, IDXCompiler::CompileAttribs CA; + auto Source = BuildHLSLSourceString(ShaderCI, ExtraDefinitions); + CA.Source = Source.c_str(); CA.SourceLength = static_cast<Uint32>(Source.length()); - auto wstrEntryPoint = std::wstring{Attribs.EntryPoint, Attribs.EntryPoint + strlen(Attribs.EntryPoint)}; + auto wstrEntryPoint = std::wstring{ShaderCI.EntryPoint, ShaderCI.EntryPoint + strlen(ShaderCI.EntryPoint)}; CA.EntryPoint = wstrEntryPoint.c_str(); CA.Profile = Profile.c_str(); CA.pDefines = nullptr; CA.DefinesCount = 0; CA.pArgs = pArgs; CA.ArgsCount = _countof(pArgs); - CA.pShaderSourceStreamFactory = Attribs.pShaderSourceStreamFactory; + CA.pShaderSourceStreamFactory = ShaderCI.pShaderSourceStreamFactory; CA.ppBlobOut = &compiled; CA.ppCompilerOutput = &errors; @@ -538,11 +491,11 @@ std::vector<uint32_t> DXILtoSPIRV(IDXCompiler* pLibrary, { if (ppCompilerOutput != nullptr) { - LOG_ERROR_AND_THROW("Failed to compile Vulkan shader \"", (Attribs.Desc.Name != nullptr ? Attribs.Desc.Name : ""), "\"."); + LOG_ERROR_AND_THROW("Failed to compile Vulkan shader \"", (ShaderCI.Desc.Name != nullptr ? ShaderCI.Desc.Name : ""), "\"."); } else { - LOG_ERROR_AND_THROW("Failed to compile Vukan shader \"", (Attribs.Desc.Name != nullptr ? Attribs.Desc.Name : ""), "\":\n", (CompilerMsg != nullptr ? std::string(CompilerMsg, CompilerMsgLen) : "<no compiler log available>")); + LOG_ERROR_AND_THROW("Failed to compile Vukan shader \"", (ShaderCI.Desc.Name != nullptr ? ShaderCI.Desc.Name : ""), "\":\n", (CompilerMsg != nullptr ? std::string(CompilerMsg, CompilerMsgLen) : "<no compiler log available>")); } } diff --git a/Graphics/ShaderTools/src/GLSLUtils.cpp b/Graphics/ShaderTools/src/GLSLUtils.cpp index 0d8ef9f4..86451a87 100644 --- a/Graphics/ShaderTools/src/GLSLUtils.cpp +++ b/Graphics/ShaderTools/src/GLSLUtils.cpp @@ -265,26 +265,10 @@ String BuildGLSLSourceString(const ShaderCreateInfo& ShaderCI, AppendShaderMacros(GLSLSource, ShaderCI.Macros); } - RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); + RefCntAutoPtr<IDataBlob> pFileData; + size_t SourceLen = 0; - auto ShaderSource = ShaderCI.Source; - size_t SourceLen = 0; - if (ShaderSource) - { - SourceLen = strlen(ShaderSource); - } - else - { - VERIFY(ShaderCI.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - ShaderCI.pShaderSourceStreamFactory->CreateInputStream(ShaderCI.FilePath, &pSourceStream); - if (pSourceStream == nullptr) - LOG_ERROR_AND_THROW("Failed to open shader source file"); - - pSourceStream->ReadBlob(pFileData); - ShaderSource = reinterpret_cast<char*>(pFileData->GetDataPtr()); - SourceLen = pFileData->GetSize(); - } + const auto* ShaderSource = ReadShaderSourceFile(ShaderCI.Source, ShaderCI.pShaderSourceStreamFactory, ShaderCI.FilePath, pFileData, SourceLen); if (ShaderCI.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL) { @@ -319,7 +303,9 @@ String BuildGLSLSourceString(const ShaderCreateInfo& ShaderCI, #endif } else + { GLSLSource.append(ShaderSource, SourceLen); + } return GLSLSource; } diff --git a/Graphics/ShaderTools/src/GLSLangUtils.cpp b/Graphics/ShaderTools/src/GLSLangUtils.cpp index 98aad2d1..79d5edeb 100644 --- a/Graphics/ShaderTools/src/GLSLangUtils.cpp +++ b/Graphics/ShaderTools/src/GLSLangUtils.cpp @@ -398,7 +398,7 @@ public: m_pInputStreamFactory->CreateInputStream(headerName, &pSourceStream); if (pSourceStream == nullptr) { - LOG_ERROR("Failed to open shader include file \"", headerName, "\". Check that the file exists"); + LOG_ERROR("Failed to open shader include file '", headerName, "'. Check that the file exists"); return nullptr; } @@ -439,64 +439,47 @@ private: std::unordered_map<IncludeResult*, RefCntAutoPtr<IDataBlob>> m_DataBlobs; }; -std::vector<unsigned int> HLSLtoSPIRV(const ShaderCreateInfo& Attribs, +std::vector<unsigned int> HLSLtoSPIRV(const ShaderCreateInfo& ShaderCI, const char* ExtraDefinitions, IDataBlob** ppCompilerOutput) { - EShLanguage ShLang = ShaderTypeToShLanguage(Attribs.Desc.ShaderType); + EShLanguage ShLang = ShaderTypeToShLanguage(ShaderCI.Desc.ShaderType); ::glslang::TShader Shader{ShLang}; EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules | EShMsgReadHlsl | EShMsgHlslLegalization); - VERIFY_EXPR(Attribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL); + VERIFY_EXPR(ShaderCI.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL); Shader.setEnvInput(::glslang::EShSourceHlsl, ShLang, ::glslang::EShClientVulkan, 100); Shader.setEnvClient(::glslang::EShClientVulkan, ::glslang::EShTargetVulkan_1_0); Shader.setEnvTarget(::glslang::EShTargetSpv, ::glslang::EShTargetSpv_1_0); Shader.setHlslIoMapping(true); - Shader.setEntryPoint(Attribs.EntryPoint); + Shader.setEntryPoint(ShaderCI.EntryPoint); Shader.setEnvTargetHlslFunctionality1(); - RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); + RefCntAutoPtr<IDataBlob> pFileData; + size_t SourceCodeLen = 0; - const char* SourceCode = 0; - int SourceCodeLen = 0; - if (Attribs.Source) - { - SourceCode = Attribs.Source; - SourceCodeLen = static_cast<int>(strlen(Attribs.Source)); - } - else - { - VERIFY(Attribs.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - Attribs.pShaderSourceStreamFactory->CreateInputStream(Attribs.FilePath, &pSourceStream); - if (pSourceStream == nullptr) - LOG_ERROR_AND_THROW("Failed to open shader source file"); - - pSourceStream->ReadBlob(pFileData); - SourceCode = reinterpret_cast<char*>(pFileData->GetDataPtr()); - SourceCodeLen = static_cast<int>(pFileData->GetSize()); - } + const char* SourceCode = ReadShaderSourceFile(ShaderCI.Source, ShaderCI.pShaderSourceStreamFactory, ShaderCI.FilePath, pFileData, SourceCodeLen); std::string Defines = g_HLSLDefinitions; - AppendShaderTypeDefinitions(Defines, Attribs.Desc.ShaderType); + AppendShaderTypeDefinitions(Defines, ShaderCI.Desc.ShaderType); if (ExtraDefinitions != nullptr) Defines += ExtraDefinitions; - if (Attribs.Macros != nullptr) + if (ShaderCI.Macros != nullptr) { Defines += '\n'; - AppendShaderMacros(Defines, Attribs.Macros); + AppendShaderMacros(Defines, ShaderCI.Macros); } Shader.setPreamble(Defines.c_str()); const char* ShaderStrings[] = {SourceCode}; - const int ShaderStringLenghts[] = {SourceCodeLen}; - const char* Names[] = {Attribs.FilePath != nullptr ? Attribs.FilePath : ""}; + const int ShaderStringLenghts[] = {static_cast<int>(SourceCodeLen)}; + const char* Names[] = {ShaderCI.FilePath != nullptr ? ShaderCI.FilePath : ""}; Shader.setStringsWithLengthsAndNames(ShaderStrings, ShaderStringLenghts, Names, 1); - IncluderImpl Includer(Attribs.pShaderSourceStreamFactory); + IncluderImpl Includer{ShaderCI.pShaderSourceStreamFactory}; auto SPIRV = CompileShaderInternal(Shader, messages, &Includer, SourceCode, SourceCodeLen, ppCompilerOutput); if (SPIRV.empty()) diff --git a/Graphics/ShaderTools/src/HLSLUtils.cpp b/Graphics/ShaderTools/src/HLSLUtils.cpp new file mode 100644 index 00000000..94ffcd3e --- /dev/null +++ b/Graphics/ShaderTools/src/HLSLUtils.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * 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 <cstring> +#include <sstream> + +#include "HLSLUtils.hpp" +#include "DebugUtilities.hpp" +#include "ShaderToolsCommon.hpp" + +namespace Diligent +{ + +// clang-format off +static const char g_HLSLDefinitions[] = +{ +#include "../../GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh" +}; +// clang-format on + + +String BuildHLSLSourceString(const ShaderCreateInfo& ShaderCI, + const char* ExtraDefinitions) +{ + String HLSLSource; + + HLSLSource.append(g_HLSLDefinitions); + AppendShaderTypeDefinitions(HLSLSource, ShaderCI.Desc.ShaderType); + + if (ExtraDefinitions != nullptr) + HLSLSource += ExtraDefinitions; + + if (ShaderCI.Macros != nullptr) + { + HLSLSource += '\n'; + AppendShaderMacros(HLSLSource, ShaderCI.Macros); + } + + AppendShaderSourceCode(HLSLSource, ShaderCI); + + return HLSLSource; +} + +} // namespace Diligent diff --git a/Graphics/ShaderTools/src/ShaderToolsCommon.cpp b/Graphics/ShaderTools/src/ShaderToolsCommon.cpp index dee4011b..dfb12bec 100644 --- a/Graphics/ShaderTools/src/ShaderToolsCommon.cpp +++ b/Graphics/ShaderTools/src/ShaderToolsCommon.cpp @@ -27,6 +27,7 @@ #include "ShaderToolsCommon.hpp" #include "DebugUtilities.hpp" +#include "DataBlobImpl.hpp" namespace Diligent { @@ -85,4 +86,59 @@ void AppendShaderTypeDefinitions(std::string& Source, SHADER_TYPE Type) AppendShaderMacros(Source, GetShaderTypeMacros(Type)); } + +const char* ReadShaderSourceFile(const char* SourceCode, + IShaderSourceInputStreamFactory* pShaderSourceStreamFactory, + const char* FilePath, + RefCntAutoPtr<IDataBlob>& pFileData, + size_t& SourceCodeLen) noexcept(false) +{ + SourceCodeLen = 0; + if (SourceCode != nullptr) + { + VERIFY(pShaderSourceStreamFactory == nullptr, "pShaderSourceStreamFactory must be null when SourceCode is not null"); + SourceCodeLen = strlen(SourceCode); + } + else + { + if (pShaderSourceStreamFactory != nullptr) + { + if (FilePath != nullptr) + { + RefCntAutoPtr<IFileStream> pSourceStream; + pShaderSourceStreamFactory->CreateInputStream(FilePath, &pSourceStream); + if (pSourceStream == nullptr) + LOG_ERROR_AND_THROW("Failed to load shader source file '", FilePath, '\''); + + pFileData = MakeNewRCObj<DataBlobImpl>{}(0); + pSourceStream->ReadBlob(pFileData); + SourceCode = reinterpret_cast<char*>(pFileData->GetDataPtr()); + SourceCodeLen = pFileData->GetSize(); + } + else + { + UNEXPECTED("FilePath is null"); + } + } + else + { + UNEXPECTED("Input stream factory is null"); + } + } + + return SourceCode; +} + +void AppendShaderSourceCode(std::string& Source, const ShaderCreateInfo& ShaderCI) noexcept(false) +{ + RefCntAutoPtr<IDataBlob> pFileData; + + size_t SourceCodeLen = 0; + + const auto* SourceCode = + ReadShaderSourceFile(ShaderCI.Source, ShaderCI.pShaderSourceStreamFactory, + ShaderCI.FilePath, pFileData, SourceCodeLen); + Source.append(SourceCode, SourceCodeLen); +} + } // namespace Diligent |
