summaryrefslogtreecommitdiffstats
path: root/Graphics/GLSLTools
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-09-14 05:27:46 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-09-14 05:27:46 +0000
commitd748358793c89dd77a2c5dbbf3ca64050b1d3bb4 (patch)
tree25008f90079aee9988a9e27851a31709df4777fa /Graphics/GLSLTools
parentMinor fix for timer query support detection in OpenGLES (diff)
downloadDiligentCore-d748358793c89dd77a2c5dbbf3ca64050b1d3bb4.tar.gz
DiligentCore-d748358793c89dd77a2c5dbbf3ca64050b1d3bb4.zip
Refactoring shader compilation tools - part I (https://github.com/DiligentGraphics/DiligentCore/issues/160)
Diffstat (limited to 'Graphics/GLSLTools')
-rw-r--r--Graphics/GLSLTools/CMakeLists.txt96
-rw-r--r--Graphics/GLSLTools/include/GLSLSourceBuilder.hpp48
-rw-r--r--Graphics/GLSLTools/include/SPIRVShaderResources.hpp412
-rw-r--r--Graphics/GLSLTools/include/SPIRVUtils.hpp49
-rw-r--r--Graphics/GLSLTools/src/GLSLSourceBuilder.cpp378
-rw-r--r--Graphics/GLSLTools/src/SPIRVShaderResources.cpp763
-rw-r--r--Graphics/GLSLTools/src/SPIRVUtils.cpp558
7 files changed, 0 insertions, 2304 deletions
diff --git a/Graphics/GLSLTools/CMakeLists.txt b/Graphics/GLSLTools/CMakeLists.txt
deleted file mode 100644
index e6977dc8..00000000
--- a/Graphics/GLSLTools/CMakeLists.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-cmake_minimum_required (VERSION 3.6)
-
-project(Diligent-GLSLTools CXX)
-
-set(INCLUDE
- include/GLSLSourceBuilder.hpp
-)
-
-set(SOURCE
- src/GLSLSourceBuilder.cpp
-)
-
-if(VULKAN_SUPPORTED)
- list(APPEND SOURCE
- src/SPIRVShaderResources.cpp
- )
- list(APPEND INCLUDE
- include/SPIRVShaderResources.hpp
- )
-
- if (NOT ${DILIGENT_NO_GLSLANG})
- list(APPEND SOURCE
- src/SPIRVUtils.cpp
- )
- list(APPEND INCLUDE
- include/SPIRVUtils.hpp
- )
- if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- # Disable the following warning:
- # moving a local object in a return statement prevents copy elision [-Wpessimizing-move]
- set_source_files_properties(src/SPIRVUtils.cpp
- PROPERTIES
- COMPILE_FLAGS -Wno-pessimizing-move
- )
- endif()
- endif()
-endif()
-
-add_library(Diligent-GLSLTools STATIC ${SOURCE} ${INCLUDE})
-
-target_include_directories(Diligent-GLSLTools
-PUBLIC
- include
-PRIVATE
- ../GraphicsEngine/include
-)
-
-target_link_libraries(Diligent-GLSLTools
-PRIVATE
- Diligent-BuildSettings
- Diligent-GraphicsAccessories
- Diligent-Common
-PUBLIC
- Diligent-GraphicsEngineInterface
-)
-
-target_compile_definitions(Diligent-GLSLTools PRIVATE DILIGENT_NO_HLSL=$<BOOL:${DILIGENT_NO_HLSL}>)
-if (NOT ${DILIGENT_NO_HLSL})
- target_include_directories(Diligent-GLSLTools PRIVATE ../HLSL2GLSLConverterLib/include)
- target_link_libraries(Diligent-GLSLTools PUBLIC Diligent-HLSL2GLSLConverterLib)
-endif()
-
-if(VULKAN_SUPPORTED)
- target_link_libraries(Diligent-GLSLTools
- PRIVATE
- spirv-cross-core
- )
-
- if (NOT ${DILIGENT_NO_GLSLANG})
- target_link_libraries(Diligent-GLSLTools
- PRIVATE
- glslang
- SPIRV
- SPIRV-Tools-opt
- )
-
- target_include_directories(Diligent-GLSLTools
- PRIVATE
- ../../ThirdParty/glslang
- )
- endif()
-endif()
-
-set_common_target_properties(Diligent-GLSLTools)
-
-source_group("src" FILES ${SOURCE})
-source_group("include" FILES ${INCLUDE})
-source_group("interface" FILES ${INTERFACE})
-
-set_target_properties(Diligent-GLSLTools PROPERTIES
- FOLDER DiligentCore/Graphics
-)
-
-if(DILIGENT_INSTALL_CORE)
- install_core_lib(Diligent-GLSLTools)
-endif()
diff --git a/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp b/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp
deleted file mode 100644
index ffe36a4e..00000000
--- a/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
-{
-
-enum TargetGLSLCompiler
-{
- glslang,
- driver
-};
-
-String BuildGLSLSourceString(const ShaderCreateInfo& CreationAttribs,
- const DeviceCaps& deviceCaps,
- TargetGLSLCompiler TargetCompiler,
- const char* ExtraDefinitions = nullptr);
-
-} // namespace Diligent \ No newline at end of file
diff --git a/Graphics/GLSLTools/include/SPIRVShaderResources.hpp b/Graphics/GLSLTools/include/SPIRVShaderResources.hpp
deleted file mode 100644
index 7a1b93ce..00000000
--- a/Graphics/GLSLTools/include/SPIRVShaderResources.hpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * 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
-
-/// \file
-/// Declaration of Diligent::SPIRVShaderResources class
-
-// SPIRVShaderResources class uses continuous chunk of memory to store all resources, as follows:
-//
-// m_MemoryBuffer m_TotalResources
-// | | |
-// | Uniform Buffers | Storage Buffers | Storage Images | Sampled Images | Atomic Counters | Separate Samplers | Separate Images | Stage Inputs | Resource Names |
-
-#include <memory>
-#include <vector>
-#include <sstream>
-
-#include "Shader.h"
-#include "RenderDevice.h"
-#include "STDAllocator.hpp"
-#include "RefCntAutoPtr.hpp"
-#include "StringPool.hpp"
-
-namespace diligent_spirv_cross
-{
-class Compiler;
-struct Resource;
-} // namespace diligent_spirv_cross
-
-namespace Diligent
-{
-
-// sizeof(SPIRVShaderResourceAttribs) == 24, msvc x64
-struct SPIRVShaderResourceAttribs
-{
- enum ResourceType : Uint8
- {
- UniformBuffer = 0,
- ROStorageBuffer,
- RWStorageBuffer,
- UniformTexelBuffer,
- StorageTexelBuffer,
- StorageImage,
- SampledImage,
- AtomicCounter,
- SeparateImage,
- SeparateSampler,
- InputAttachment,
- NumResourceTypes
- };
-
- // clang-format off
-
- static constexpr const Uint32 InvalidSepSmplrOrImgInd = static_cast<Uint32>(-1);
-
-/* 0 */const char* const Name;
-/* 8 */const Uint16 ArraySize;
-/* 10 */const ResourceType Type;
-/* 11 */ // unused
-private:
- // Defines the mapping between separate samplers and seperate images when HLSL-style
- // combined texture samplers are in use (i.e. texture2D g_Tex + sampler g_Tex_sampler).
-/* 12 */ Uint32 SepSmplrOrImgInd = InvalidSepSmplrOrImgInd;
-public:
- // Offset in SPIRV words (uint32_t) of binding & descriptor set decorations in SPIRV binary
-/* 16 */const uint32_t BindingDecorationOffset;
-/* 20 */const uint32_t DescriptorSetDecorationOffset;
-/* 24 */ // End of structure
-
- // clang-format on
-
- SPIRVShaderResourceAttribs(const diligent_spirv_cross::Compiler& Compiler,
- const diligent_spirv_cross::Resource& Res,
- const char* _Name,
- ResourceType _Type,
- Uint32 _SamplerOrSepImgInd = InvalidSepSmplrOrImgInd) noexcept;
-
- bool IsValidSepSamplerAssigned() const
- {
- VERIFY_EXPR(Type == SeparateImage);
- return SepSmplrOrImgInd != InvalidSepSmplrOrImgInd;
- }
-
- bool IsValidSepImageAssigned() const
- {
- VERIFY_EXPR(Type == SeparateSampler);
- return SepSmplrOrImgInd != InvalidSepSmplrOrImgInd;
- }
-
- Uint32 GetAssignedSepSamplerInd() const
- {
- VERIFY_EXPR(Type == SeparateImage);
- return SepSmplrOrImgInd;
- }
-
- Uint32 GetAssignedSepImageInd() const
- {
- VERIFY_EXPR(Type == SeparateSampler);
- return SepSmplrOrImgInd;
- }
-
- void AssignSeparateSampler(Uint32 SemSamplerInd)
- {
- VERIFY_EXPR(Type == SeparateImage);
- SepSmplrOrImgInd = SemSamplerInd;
- }
-
- void AssignSeparateImage(Uint32 SepImageInd)
- {
- VERIFY_EXPR(Type == SeparateSampler);
- SepSmplrOrImgInd = SepImageInd;
- }
-
- String GetPrintName(Uint32 ArrayInd) const
- {
- VERIFY_EXPR(ArrayInd < ArraySize);
- if (ArraySize > 1)
- {
- std::stringstream ss;
- ss << Name << '[' << ArrayInd << ']';
- return ss.str();
- }
- else
- return Name;
- }
-
- bool IsCompatibleWith(const SPIRVShaderResourceAttribs& Attribs) const
- {
- // clang-format off
- return ArraySize == Attribs.ArraySize &&
- Type == Attribs.Type &&
- SepSmplrOrImgInd == Attribs.SepSmplrOrImgInd;
- // clang-format on
- }
-
- ShaderResourceDesc GetResourceDesc() const;
-};
-static_assert(sizeof(SPIRVShaderResourceAttribs) % sizeof(void*) == 0, "Size of SPIRVShaderResourceAttribs struct must be multiple of sizeof(void*)");
-
-// sizeof(SPIRVShaderResourceAttribs) == 16, msvc x64
-struct SPIRVShaderStageInputAttribs
-{
- // clang-format off
- SPIRVShaderStageInputAttribs(const char* _Semantic, uint32_t _LocationDecorationOffset) :
- Semantic {_Semantic},
- LocationDecorationOffset {_LocationDecorationOffset}
- {}
- // clang-format on
-
- const char* const Semantic;
- const uint32_t LocationDecorationOffset;
-};
-static_assert(sizeof(SPIRVShaderStageInputAttribs) % sizeof(void*) == 0, "Size of SPIRVShaderStageInputAttribs struct must be multiple of sizeof(void*)");
-
-/// Diligent::SPIRVShaderResources class
-class SPIRVShaderResources
-{
-public:
- SPIRVShaderResources(IMemoryAllocator& Allocator,
- IRenderDevice* pRenderDevice,
- std::vector<uint32_t> spirv_binary,
- const ShaderDesc& shaderDesc,
- const char* CombinedSamplerSuffix,
- bool LoadShaderStageInputs,
- std::string& EntryPoint);
-
- // clang-format off
- SPIRVShaderResources (const SPIRVShaderResources&) = delete;
- SPIRVShaderResources ( SPIRVShaderResources&&) = delete;
- SPIRVShaderResources& operator = (const SPIRVShaderResources&) = delete;
- SPIRVShaderResources& operator = ( SPIRVShaderResources&&) = delete;
- // clang-format on
-
- ~SPIRVShaderResources();
-
- // clang-format off
-
- Uint32 GetNumUBs ()const noexcept{ return (m_StorageBufferOffset - 0); }
- Uint32 GetNumSBs ()const noexcept{ return (m_StorageImageOffset - m_StorageBufferOffset); }
- Uint32 GetNumImgs ()const noexcept{ return (m_SampledImageOffset - m_StorageImageOffset); }
- Uint32 GetNumSmpldImgs()const noexcept{ return (m_AtomicCounterOffset - m_SampledImageOffset); }
- Uint32 GetNumACs ()const noexcept{ return (m_SeparateSamplerOffset - m_AtomicCounterOffset); }
- Uint32 GetNumSepSmplrs()const noexcept{ return (m_SeparateImageOffset - m_SeparateSamplerOffset);}
- Uint32 GetNumSepImgs ()const noexcept{ return (m_InputAttachmentOffset - m_SeparateImageOffset); }
- Uint32 GetNumInptAtts ()const noexcept{ return (m_TotalResources - m_InputAttachmentOffset);}
- Uint32 GetTotalResources() const noexcept { return m_TotalResources; }
- Uint32 GetNumShaderStageInputs()const noexcept { return m_NumShaderStageInputs; }
-
- const SPIRVShaderResourceAttribs& GetUB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumUBs(), 0 ); }
- const SPIRVShaderResourceAttribs& GetSB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSBs(), m_StorageBufferOffset ); }
- const SPIRVShaderResourceAttribs& GetImg (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumImgs(), m_StorageImageOffset ); }
- const SPIRVShaderResourceAttribs& GetSmpldImg(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSmpldImgs(), m_SampledImageOffset ); }
- const SPIRVShaderResourceAttribs& GetAC (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumACs(), m_AtomicCounterOffset ); }
- const SPIRVShaderResourceAttribs& GetSepSmplr(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSepSmplrs(), m_SeparateSamplerOffset); }
- const SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSepImgs(), m_SeparateImageOffset ); }
- const SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumInptAtts(), m_InputAttachmentOffset); }
- const SPIRVShaderResourceAttribs& GetResource(Uint32 n)const noexcept{ return GetResAttribs(n, GetTotalResources(), 0 ); }
-
- // clang-format on
-
- const SPIRVShaderStageInputAttribs& GetShaderStageInputAttribs(Uint32 n) const noexcept
- {
- VERIFY(n < m_NumShaderStageInputs, "Shader stage input index (", n, ") is out of range. Total input count: ", m_NumShaderStageInputs);
- auto* ResourceMemoryEnd = reinterpret_cast<const SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get()) + m_TotalResources;
- return reinterpret_cast<const SPIRVShaderStageInputAttribs*>(ResourceMemoryEnd)[n];
- }
-
- const SPIRVShaderResourceAttribs& GetAssignedSepSampler(const SPIRVShaderResourceAttribs& SepImg) const
- {
- VERIFY(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage, "Separate samplers can only be assigned to separate images");
- VERIFY(SepImg.IsValidSepSamplerAssigned(), "This separate image is not assigned a separate sampler");
- return GetSepSmplr(SepImg.GetAssignedSepSamplerInd());
- }
-
- struct ResourceCounters
- {
- Uint32 NumUBs = 0;
- Uint32 NumSBs = 0;
- Uint32 NumImgs = 0;
- Uint32 NumSmpldImgs = 0;
- Uint32 NumACs = 0;
- Uint32 NumSepSmplrs = 0;
- Uint32 NumSepImgs = 0;
- Uint32 NumInptAtts = 0;
- };
-
- SHADER_TYPE GetShaderType() const noexcept { return m_ShaderType; }
-
- // Process only resources listed in AllowedVarTypes
- template <typename THandleUB,
- typename THandleSB,
- typename THandleImg,
- typename THandleSmplImg,
- typename THandleAC,
- typename THandleSepSmpl,
- typename THandleSepImg,
- typename THandleInptAtt>
- void ProcessResources(THandleUB HandleUB,
- THandleSB HandleSB,
- THandleImg HandleImg,
- THandleSmplImg HandleSmplImg,
- THandleAC HandleAC,
- THandleSepSmpl HandleSepSmpl,
- THandleSepImg HandleSepImg,
- THandleInptAtt HandleInptAtt) const
- {
- for (Uint32 n = 0; n < GetNumUBs(); ++n)
- {
- const auto& UB = GetUB(n);
- HandleUB(UB, n);
- }
-
- for (Uint32 n = 0; n < GetNumSBs(); ++n)
- {
- const auto& SB = GetSB(n);
- HandleSB(SB, n);
- }
-
- for (Uint32 n = 0; n < GetNumImgs(); ++n)
- {
- const auto& Img = GetImg(n);
- HandleImg(Img, n);
- }
-
- for (Uint32 n = 0; n < GetNumSmpldImgs(); ++n)
- {
- const auto& SmplImg = GetSmpldImg(n);
- HandleSmplImg(SmplImg, n);
- }
-
- for (Uint32 n = 0; n < GetNumACs(); ++n)
- {
- const auto& AC = GetAC(n);
- HandleAC(AC, n);
- }
-
- for (Uint32 n = 0; n < GetNumSepSmplrs(); ++n)
- {
- const auto& SepSmpl = GetSepSmplr(n);
- HandleSepSmpl(SepSmpl, n);
- }
-
- for (Uint32 n = 0; n < GetNumSepImgs(); ++n)
- {
- const auto& SepImg = GetSepImg(n);
- HandleSepImg(SepImg, n);
- }
-
- for (Uint32 n = 0; n < GetNumInptAtts(); ++n)
- {
- const auto& InptAtt = GetInptAtt(n);
- HandleInptAtt(InptAtt, n);
- }
-
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please handle the new resource type here, if needed");
- }
-
- template <typename THandler>
- void ProcessResources(THandler Handler) const
- {
- for (Uint32 n = 0; n < GetTotalResources(); ++n)
- {
- const auto& Res = GetResource(n);
- Handler(Res, n);
- }
- }
-
- std::string DumpResources();
-
- bool IsCompatibleWith(const SPIRVShaderResources& Resources) const;
-
- // clang-format off
-
- const char* GetCombinedSamplerSuffix() const { return m_CombinedSamplerSuffix; }
- const char* GetShaderName() const { return m_ShaderName; }
- bool IsUsingCombinedSamplers() const { return m_CombinedSamplerSuffix != nullptr; }
-
- // clang-format on
-
- bool IsHLSLSource() const { return m_IsHLSLSource; }
-
-private:
- void Initialize(IMemoryAllocator& Allocator,
- const ResourceCounters& Counters,
- Uint32 NumShaderStageInputs,
- size_t ResourceNamesPoolSize);
-
- SPIRVShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept
- {
- VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Total resource count: ", NumResources);
- VERIFY_EXPR(Offset + n < m_TotalResources);
- return reinterpret_cast<SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
- }
-
- const SPIRVShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept
- {
- VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Total resource count: ", NumResources);
- VERIFY_EXPR(Offset + n < m_TotalResources);
- return reinterpret_cast<SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
- }
-
- // clang-format off
-
- SPIRVShaderResourceAttribs& GetUB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumUBs(), 0 ); }
- SPIRVShaderResourceAttribs& GetSB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSBs(), m_StorageBufferOffset ); }
- SPIRVShaderResourceAttribs& GetImg (Uint32 n)noexcept{ return GetResAttribs(n, GetNumImgs(), m_StorageImageOffset ); }
- SPIRVShaderResourceAttribs& GetSmpldImg(Uint32 n)noexcept{ return GetResAttribs(n, GetNumSmpldImgs(), m_SampledImageOffset ); }
- SPIRVShaderResourceAttribs& GetAC (Uint32 n)noexcept{ return GetResAttribs(n, GetNumACs(), m_AtomicCounterOffset ); }
- SPIRVShaderResourceAttribs& GetSepSmplr(Uint32 n)noexcept{ return GetResAttribs(n, GetNumSepSmplrs(), m_SeparateSamplerOffset); }
- SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSepImgs(), m_SeparateImageOffset ); }
- SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)noexcept{ return GetResAttribs(n, GetNumInptAtts(), m_InputAttachmentOffset); }
- SPIRVShaderResourceAttribs& GetResource(Uint32 n)noexcept{ return GetResAttribs(n, GetTotalResources(), 0 ); }
-
- // clang-format on
-
- SPIRVShaderStageInputAttribs& GetShaderStageInputAttribs(Uint32 n) noexcept
- {
- return const_cast<SPIRVShaderStageInputAttribs&>(const_cast<const SPIRVShaderResources*>(this)->GetShaderStageInputAttribs(n));
- }
-
- // Memory buffer that holds all resources as continuous chunk of memory:
- // | UBs | SBs | StrgImgs | SmplImgs | ACs | SepSamplers | SepImgs | Stage Inputs | Resource Names |
- std::unique_ptr<void, STDDeleterRawMem<void>> m_MemoryBuffer;
-
- StringPool m_ResourceNames;
-
- const char* m_CombinedSamplerSuffix = nullptr;
- const char* m_ShaderName = nullptr;
-
- using OffsetType = Uint16;
- OffsetType m_StorageBufferOffset = 0;
- OffsetType m_StorageImageOffset = 0;
- OffsetType m_SampledImageOffset = 0;
- OffsetType m_AtomicCounterOffset = 0;
- OffsetType m_SeparateSamplerOffset = 0;
- OffsetType m_SeparateImageOffset = 0;
- OffsetType m_InputAttachmentOffset = 0;
- OffsetType m_TotalResources = 0;
- OffsetType m_NumShaderStageInputs = 0;
-
- SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
-
- // Inidicates if the shader was compiled from HLSL source.
- bool m_IsHLSLSource = false;
-};
-
-} // namespace Diligent
diff --git a/Graphics/GLSLTools/include/SPIRVUtils.hpp b/Graphics/GLSLTools/include/SPIRVUtils.hpp
deleted file mode 100644
index 50025303..00000000
--- a/Graphics/GLSLTools/include/SPIRVUtils.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 <vector>
-#include "Shader.h"
-#include "DataBlob.h"
-
-namespace Diligent
-{
-
-void InitializeGlslang();
-void FinalizeGlslang();
-
-std::vector<unsigned int> GLSLtoSPIRV(SHADER_TYPE ShaderType,
- const char* ShaderSource,
- int SourceCodeLen,
- IDataBlob** ppCompilerOutput);
-
-std::vector<unsigned int> HLSLtoSPIRV(const ShaderCreateInfo& Attribs,
- const char* ExtraDefinitions,
- IDataBlob** ppCompilerOutput);
-
-} // namespace Diligent \ No newline at end of file
diff --git a/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp b/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp
deleted file mode 100644
index dfb4d757..00000000
--- a/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * 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 "GLSLSourceBuilder.hpp"
-#include "DebugUtilities.hpp"
-#if !DILIGENT_NO_HLSL
-# include "HLSL2GLSLConverterImpl.hpp"
-#endif
-#include "RefCntAutoPtr.hpp"
-#include "DataBlobImpl.hpp"
-
-namespace Diligent
-{
-
-const char* GetShaderTypeDefines(SHADER_TYPE Type)
-{
- switch (Type)
- {
- case SHADER_TYPE_VERTEX:
- return "#define VERTEX_SHADER 1\n";
-
- case SHADER_TYPE_PIXEL:
- return "#define FRAGMENT_SHADER 1\n"
- "#define PIXEL_SHADER 1\n";
-
- case SHADER_TYPE_GEOMETRY:
- return "#define GEOMETRY_SHADER 1\n";
-
- case SHADER_TYPE_HULL:
- return "#define TESS_CONTROL_SHADER 1\n"
- "#define HULL_SHADER 1\n";
-
- case SHADER_TYPE_DOMAIN:
- return "#define TESS_EVALUATION_SHADER 1\n"
- "#define DOMAIN_SHADER 1\n";
- break;
-
- case SHADER_TYPE_COMPUTE:
- return "#define COMPUTE_SHADER 1\n";
-
- case SHADER_TYPE_AMPLIFICATION:
- return "#define TASK_SHADER 1\n"
- "#define AMPLIFICATION_SHADER 1\n";
-
- case SHADER_TYPE_MESH:
- return "#define MESH_SHADER 1\n";
-
- default:
- UNEXPECTED("Unexpected shader type");
- return nullptr;
- }
-}
-
-String BuildGLSLSourceString(const ShaderCreateInfo& CreationAttribs,
- const DeviceCaps& deviceCaps,
- TargetGLSLCompiler TargetCompiler,
- const char* ExtraDefinitions)
-{
- String GLSLSource;
-
- if (CreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM && CreationAttribs.Macros != nullptr)
- LOG_WARNING_MESSAGE("Shader macros are ignored when compiling GLSL verbatim");
-
- if (CreationAttribs.SourceLanguage != SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM)
- {
- auto ShaderType = CreationAttribs.Desc.ShaderType;
-
-#if PLATFORM_WIN32 || PLATFORM_LINUX
- GLSLSource.append(
- "#version 430 core\n"
- "#define DESKTOP_GL 1\n");
-# if PLATFORM_WIN32
- GLSLSource.append("#define PLATFORM_WIN32 1\n");
-# elif PLATFORM_LINUX
- GLSLSource.append("#define PLATFORM_LINUX 1\n");
-# else
-# error Unexpected platform
-# endif
-#elif PLATFORM_MACOS
- if (TargetCompiler == TargetGLSLCompiler::glslang)
- GLSLSource.append("#version 430 core\n");
- else if (TargetCompiler == TargetGLSLCompiler::driver)
- GLSLSource.append("#version 410 core\n");
- else
- UNEXPECTED("Unexpected target GLSL compiler");
-
- GLSLSource.append(
- "#define DESKTOP_GL 1\n"
- "#define PLATFORM_MACOS 1\n");
-
-#elif PLATFORM_ANDROID || PLATFORM_IOS
- bool IsES30 = false;
- bool IsES31OrAbove = false;
- bool IsES32OrAbove = false;
- if (deviceCaps.DevType == RENDER_DEVICE_TYPE_VULKAN)
- {
- IsES30 = false;
- IsES31OrAbove = true;
- IsES32OrAbove = false;
- GLSLSource.append("#version 310 es\n");
- }
- else if (deviceCaps.DevType == RENDER_DEVICE_TYPE_GLES)
- {
- IsES30 = deviceCaps.MajorVersion == 3 && deviceCaps.MinorVersion == 0;
- IsES31OrAbove = deviceCaps.MajorVersion > 3 || (deviceCaps.MajorVersion == 3 && deviceCaps.MinorVersion >= 1);
- IsES32OrAbove = deviceCaps.MajorVersion > 3 || (deviceCaps.MajorVersion == 3 && deviceCaps.MinorVersion >= 2);
- std::stringstream versionss;
- versionss << "#version " << deviceCaps.MajorVersion << deviceCaps.MinorVersion << "0 es\n";
- GLSLSource.append(versionss.str());
- }
- else
- {
- UNEXPECTED("Unexpected device type");
- }
-
- if (deviceCaps.Features.SeparablePrograms && !IsES31OrAbove)
- GLSLSource.append("#extension GL_EXT_separate_shader_objects : enable\n");
-
- if (deviceCaps.TexCaps.CubemapArraysSupported && !IsES32OrAbove)
- GLSLSource.append("#extension GL_EXT_texture_cube_map_array : enable\n");
-
- if (ShaderType == SHADER_TYPE_GEOMETRY && !IsES32OrAbove)
- GLSLSource.append("#extension GL_EXT_geometry_shader : enable\n");
-
- if ((ShaderType == SHADER_TYPE_HULL || ShaderType == SHADER_TYPE_DOMAIN) && !IsES32OrAbove)
- GLSLSource.append("#extension GL_EXT_tessellation_shader : enable\n");
-
- GLSLSource.append(
- "#ifndef GL_ES\n"
- "# define GL_ES 1\n"
- "#endif\n");
-
-# if PLATFORM_ANDROID
- GLSLSource.append("#define PLATFORM_ANDROID 1\n");
-# elif PLATFORM_IOS
- GLSLSource.append("#define PLATFORM_IOS 1\n");
-# else
-# error "Unexpected platform"
-# endif
-
- GLSLSource.append(
- "precision highp float;\n"
- "precision highp int;\n"
- //"precision highp uint;\n" // This line causes shader compilation error on NVidia!
-
- "precision highp sampler2D;\n"
- "precision highp sampler3D;\n"
- "precision highp samplerCube;\n"
- "precision highp samplerCubeShadow;\n"
-
- "precision highp sampler2DShadow;\n"
- "precision highp sampler2DArray;\n"
- "precision highp sampler2DArrayShadow;\n"
-
- "precision highp isampler2D;\n"
- "precision highp isampler3D;\n"
- "precision highp isamplerCube;\n"
- "precision highp isampler2DArray;\n"
-
- "precision highp usampler2D;\n"
- "precision highp usampler3D;\n"
- "precision highp usamplerCube;\n"
- "precision highp usampler2DArray;\n" // clang-format off
- ); // clang-format on
-
- if (IsES32OrAbove)
- {
- GLSLSource.append(
- "precision highp samplerBuffer;\n"
- "precision highp isamplerBuffer;\n"
- "precision highp usamplerBuffer;\n" // clang-format off
- ); // clang-format on
- }
-
- if (deviceCaps.TexCaps.CubemapArraysSupported)
- {
- GLSLSource.append(
- "precision highp samplerCubeArray;\n"
- "precision highp samplerCubeArrayShadow;\n"
- "precision highp isamplerCubeArray;\n"
- "precision highp usamplerCubeArray;\n" // clang-format off
- ); // clang-format on
- }
-
- if (deviceCaps.TexCaps.Texture2DMSSupported)
- {
- GLSLSource.append(
- "precision highp sampler2DMS;\n"
- "precision highp isampler2DMS;\n"
- "precision highp usampler2DMS;\n" // clang-format off
- ); // clang-format on
- }
-
- if (deviceCaps.Features.ComputeShaders)
- {
- GLSLSource.append(
- "precision highp image2D;\n"
- "precision highp image3D;\n"
- "precision highp imageCube;\n"
- "precision highp image2DArray;\n"
-
- "precision highp iimage2D;\n"
- "precision highp iimage3D;\n"
- "precision highp iimageCube;\n"
- "precision highp iimage2DArray;\n"
-
- "precision highp uimage2D;\n"
- "precision highp uimage3D;\n"
- "precision highp uimageCube;\n"
- "precision highp uimage2DArray;\n" // clang-format off
- ); // clang-format on
- if (IsES32OrAbove)
- {
- GLSLSource.append(
- "precision highp imageBuffer;\n"
- "precision highp iimageBuffer;\n"
- "precision highp uimageBuffer;\n" // clang-format off
- ); // clang-format on
- }
- }
-
- if (IsES30 && deviceCaps.Features.SeparablePrograms && ShaderType == SHADER_TYPE_VERTEX)
- {
- // From https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_separate_shader_objects.gles.txt:
- //
- // When using GLSL ES 3.00 shaders in separable programs, gl_Position and
- // gl_PointSize built-in outputs must be redeclared according to Section 7.5
- // of the OpenGL Shading Language Specification...
- //
- // add to GLSL ES 3.00 new section 7.5, Built-In Redeclaration and
- // Separable Programs:
- //
- // "The following vertex shader outputs may be redeclared at global scope to
- // specify a built-in output interface, with or without special qualifiers:
- //
- // gl_Position
- // gl_PointSize
- //
- // When compiling shaders using either of the above variables, both such
- // variables must be redeclared prior to use. ((Note: This restriction
- // applies only to shaders using version 300 that enable the
- // EXT_separate_shader_objects extension; shaders not enabling the
- // extension do not have this requirement.)) A separable program object
- // will fail to link if any attached shader uses one of the above variables
- // without redeclaration."
- GLSLSource.append("out vec4 gl_Position;\n");
- }
-
-#elif
-# error "Undefined platform"
-#endif
-
- // It would be much more convenient to use row_major matrices.
- // But unfortunatelly on NVIDIA, the following directive
- // layout(std140, row_major) uniform;
- // does not have any effect on matrices that are part of structures
- // So we have to use column-major matrices which are default in both
- // DX and GLSL.
- GLSLSource.append(
- "layout(std140) uniform;\n");
-
- if (ShaderType == SHADER_TYPE_VERTEX && TargetCompiler == TargetGLSLCompiler::glslang)
- {
- // https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt
- GLSLSource.append("#define gl_VertexID gl_VertexIndex\n"
- "#define gl_InstanceID gl_InstanceIndex\n");
- }
-
- if (const auto* ShaderTypeDefine = GetShaderTypeDefines(ShaderType))
- GLSLSource += ShaderTypeDefine;
-
- if (ExtraDefinitions != nullptr)
- {
- GLSLSource.append(ExtraDefinitions);
- }
-
- if (CreationAttribs.Macros != nullptr)
- {
- auto* pMacro = CreationAttribs.Macros;
- while (pMacro->Name != nullptr && pMacro->Definition != nullptr)
- {
- GLSLSource += "#define ";
- GLSLSource += pMacro->Name;
- GLSLSource += ' ';
- GLSLSource += pMacro->Definition;
- GLSLSource += "\n";
- ++pMacro;
- }
- }
- }
-
- RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0));
-
- auto ShaderSource = CreationAttribs.Source;
- size_t SourceLen = 0;
- if (ShaderSource)
- {
- SourceLen = strlen(ShaderSource);
- }
- else
- {
- VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null");
- RefCntAutoPtr<IFileStream> pSourceStream;
- CreationAttribs.pShaderSourceStreamFactory->CreateInputStream(CreationAttribs.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();
- }
-
- if (CreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL)
- {
-#if DILIGENT_NO_HLSL
- LOG_ERROR_AND_THROW("Unable to convert HLSL source to GLSL: HLSL support is disabled");
-#else
- if (!CreationAttribs.UseCombinedTextureSamplers)
- {
- LOG_ERROR_AND_THROW("Combined texture samplers are required to convert HLSL source to GLSL");
- }
- // Convert HLSL to GLSL
- const auto& Converter = HLSL2GLSLConverterImpl::GetInstance();
-
- HLSL2GLSLConverterImpl::ConversionAttribs Attribs;
- Attribs.pSourceStreamFactory = CreationAttribs.pShaderSourceStreamFactory;
- Attribs.ppConversionStream = CreationAttribs.ppConversionStream;
- Attribs.HLSLSource = ShaderSource;
- Attribs.NumSymbols = SourceLen;
- Attribs.EntryPoint = CreationAttribs.EntryPoint;
- Attribs.ShaderType = CreationAttribs.Desc.ShaderType;
- Attribs.IncludeDefinitions = true;
- Attribs.InputFileName = CreationAttribs.FilePath;
- Attribs.SamplerSuffix = CreationAttribs.CombinedSamplerSuffix;
- // Separate shader objects extension also allows input/output layout qualifiers for
- // all shader stages.
- // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_separate_shader_objects.txt
- // (search for "Input Layout Qualifiers" and "Output Layout Qualifiers").
- Attribs.UseInOutLocationQualifiers = deviceCaps.Features.SeparablePrograms;
- auto ConvertedSource = Converter.Convert(Attribs);
-
- GLSLSource.append(ConvertedSource);
-#endif
- }
- else
- GLSLSource.append(ShaderSource, SourceLen);
-
- return GLSLSource;
-}
-
-} // namespace Diligent
diff --git a/Graphics/GLSLTools/src/SPIRVShaderResources.cpp b/Graphics/GLSLTools/src/SPIRVShaderResources.cpp
deleted file mode 100644
index 2ba5d90a..00000000
--- a/Graphics/GLSLTools/src/SPIRVShaderResources.cpp
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * 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 <iomanip>
-#include "SPIRVShaderResources.hpp"
-#include "spirv_parser.hpp"
-#include "spirv_cross.hpp"
-#include "ShaderBase.hpp"
-#include "GraphicsAccessories.hpp"
-#include "StringTools.hpp"
-#include "Align.hpp"
-
-namespace Diligent
-{
-
-template <typename Type>
-Type GetResourceArraySize(const diligent_spirv_cross::Compiler& Compiler,
- const diligent_spirv_cross::Resource& Res)
-{
- const auto& type = Compiler.get_type(Res.type_id);
- uint32_t arrSize = 1;
- if (!type.array.empty())
- {
- // https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide#querying-array-types
- VERIFY(type.array.size() == 1, "Only one-dimensional arrays are currently supported");
- arrSize = type.array[0];
- }
- VERIFY(arrSize <= std::numeric_limits<Type>::max(), "Array size exceeds maximum representable value ", std::numeric_limits<Type>::max());
- return static_cast<Type>(arrSize);
-}
-
-static uint32_t GetDecorationOffset(const diligent_spirv_cross::Compiler& Compiler,
- const diligent_spirv_cross::Resource& Res,
- spv::Decoration Decoration)
-{
- VERIFY(Compiler.has_decoration(Res.id, Decoration), "Resource \'", Res.name, "\' has no requested decoration");
- uint32_t offset = 0;
- auto declared = Compiler.get_binary_offset_for_decoration(Res.id, Decoration, offset);
- VERIFY(declared, "Requested decoration is not declared");
- (void)declared;
- return offset;
-}
-
-SPIRVShaderResourceAttribs::SPIRVShaderResourceAttribs(const diligent_spirv_cross::Compiler& Compiler,
- const diligent_spirv_cross::Resource& Res,
- const char* _Name,
- ResourceType _Type,
- Uint32 _SepSmplrOrImgInd) noexcept :
- // clang-format off
- Name {_Name},
- ArraySize {GetResourceArraySize<decltype(ArraySize)>(Compiler, Res)},
- Type {_Type},
- SepSmplrOrImgInd {_SepSmplrOrImgInd},
- BindingDecorationOffset {GetDecorationOffset(Compiler, Res, spv::Decoration::DecorationBinding)},
- DescriptorSetDecorationOffset {GetDecorationOffset(Compiler, Res, spv::Decoration::DecorationDescriptorSet)}
-// clang-format on
-{
- VERIFY(_SepSmplrOrImgInd == SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd ||
- (_Type == ResourceType::SeparateSampler || _Type == ResourceType::SeparateImage),
- "Only separate images or separate samplers can be assinged valid SepSmplrOrImgInd value");
-}
-
-
-ShaderResourceDesc SPIRVShaderResourceAttribs::GetResourceDesc() const
-{
- ShaderResourceDesc ResourceDesc;
- ResourceDesc.Name = Name;
- ResourceDesc.ArraySize = ArraySize;
-
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please handle the new resource type below");
- switch (Type)
- {
- case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer:
- // Read-only storage buffers map to buffer SRV
- // https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide#read-write-vs-read-only-resources-for-hlsl
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::StorageImage:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_UAV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::SampledImage:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::AtomicCounter:
- LOG_WARNING_MESSAGE("There is no appropriate shader resource type for atomic counter resource '", Name, "'");
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::SeparateImage:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER;
- break;
-
- case SPIRVShaderResourceAttribs::ResourceType::InputAttachment:
- ResourceDesc.Type = SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT;
- break;
-
- default:
- UNEXPECTED("Unknown SPIRV resource type");
- }
- return ResourceDesc;
-}
-
-
-static spv::ExecutionModel ShaderTypeToExecutionModel(SHADER_TYPE ShaderType)
-{
- static_assert(SHADER_TYPE_LAST == 0x080, "Please handle the new shader type in the switch below");
- switch (ShaderType)
- {
- // clang-format off
- case SHADER_TYPE_VERTEX: return spv::ExecutionModelVertex;
- case SHADER_TYPE_HULL: return spv::ExecutionModelTessellationControl;
- case SHADER_TYPE_DOMAIN: return spv::ExecutionModelTessellationEvaluation;
- case SHADER_TYPE_GEOMETRY: return spv::ExecutionModelGeometry;
- case SHADER_TYPE_PIXEL: return spv::ExecutionModelFragment;
- case SHADER_TYPE_COMPUTE: return spv::ExecutionModelGLCompute;
- case SHADER_TYPE_AMPLIFICATION: return spv::ExecutionModelTaskNV;
- case SHADER_TYPE_MESH: return spv::ExecutionModelMeshNV;
- // clang-format on
- default:
- UNEXPECTED("Unexpected shader type");
- return spv::ExecutionModelVertex;
- }
-}
-
-const std::string& GetUBName(diligent_spirv_cross::Compiler& Compiler,
- const diligent_spirv_cross::Resource& UB,
- const diligent_spirv_cross::ParsedIR::Source& IRSource)
-{
- // Consider the following HLSL constant buffer:
- //
- // cbuffer Constants
- // {
- // float4x4 g_WorldViewProj;
- // };
- //
- // glslang emits SPIRV as if the following GLSL was written:
- //
- // uniform Constants // UB.name
- // {
- // float4x4 g_WorldViewProj;
- // }; // no instance name
- //
- // DXC emits the byte code that corresponds to the following GLSL:
- //
- // uniform type_Constants // UB.name
- // {
- // float4x4 g_WorldViewProj;
- // }Constants; // get_name(UB.id)
- //
- //
- // | glslang | DXC
- // -------------------------------------------------------------------
- // UB.name | "Constants" | "type_Constants"
- // Compiler.get_name(UB.id) | "" | "Constants"
- //
- // Note that for the byte code produced from GLSL, we must always
- // use UB.name even if the instance name is present
-
- const auto& instance_name = Compiler.get_name(UB.id);
- return (IRSource.hlsl && !instance_name.empty()) ? instance_name : UB.name;
-}
-
-SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator& Allocator,
- IRenderDevice* pRenderDevice,
- std::vector<uint32_t> spirv_binary,
- const ShaderDesc& shaderDesc,
- const char* CombinedSamplerSuffix,
- bool LoadShaderStageInputs,
- std::string& EntryPoint) :
- m_ShaderType{shaderDesc.ShaderType}
-{
- // https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide
- diligent_spirv_cross::Parser parser(move(spirv_binary));
- parser.parse();
- const auto ParsedIRSource = parser.get_parsed_ir().source;
- m_IsHLSLSource = ParsedIRSource.hlsl;
- diligent_spirv_cross::Compiler Compiler(std::move(parser.get_parsed_ir()));
-
- spv::ExecutionModel ExecutionModel = ShaderTypeToExecutionModel(shaderDesc.ShaderType);
- auto EntryPoints = Compiler.get_entry_points_and_stages();
- for (const auto& CurrEntryPoint : EntryPoints)
- {
- if (CurrEntryPoint.execution_model == ExecutionModel)
- {
- if (!EntryPoint.empty())
- {
- LOG_WARNING_MESSAGE("More than one entry point of type ", GetShaderTypeLiteralName(shaderDesc.ShaderType), " found in SPIRV binary for shader '", shaderDesc.Name, "'. The first one ('", EntryPoint, "') will be used.");
- }
- else
- {
- EntryPoint = CurrEntryPoint.name;
- }
- }
- }
- if (EntryPoint.empty())
- {
- LOG_ERROR_AND_THROW("Unable to find entry point of type ", GetShaderTypeLiteralName(shaderDesc.ShaderType), " in SPIRV binary for shader '", shaderDesc.Name, "'");
- }
- Compiler.set_entry_point(EntryPoint, ExecutionModel);
-
- // The SPIR-V is now parsed, and we can perform reflection on it.
- diligent_spirv_cross::ShaderResources resources = Compiler.get_shader_resources();
-
- size_t ResourceNamesPoolSize = 0;
- for (const auto& ub : resources.uniform_buffers)
- ResourceNamesPoolSize += GetUBName(Compiler, ub, ParsedIRSource).length() + 1;
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please account for the new resource type below");
- for (auto* pResType :
- {
- &resources.storage_buffers,
- &resources.storage_images,
- &resources.sampled_images,
- &resources.atomic_counters,
- &resources.separate_images,
- &resources.separate_samplers,
- &resources.subpass_inputs
- // clang-format off
- })
- // clang-format on
- {
- for (const auto& res : *pResType)
- ResourceNamesPoolSize += res.name.length() + 1;
- }
-
- if (CombinedSamplerSuffix != nullptr)
- {
- ResourceNamesPoolSize += strlen(CombinedSamplerSuffix) + 1;
- }
-
- VERIFY_EXPR(shaderDesc.Name != nullptr);
- ResourceNamesPoolSize += strlen(shaderDesc.Name) + 1;
-
- Uint32 NumShaderStageInputs = 0;
-
- if (!m_IsHLSLSource || resources.stage_inputs.empty())
- LoadShaderStageInputs = false;
- if (LoadShaderStageInputs)
- {
- const auto& Extensions = Compiler.get_declared_extensions();
- bool HlslFunctionality1 = false;
- for (const auto& ext : Extensions)
- {
- HlslFunctionality1 = (ext == "SPV_GOOGLE_hlsl_functionality1");
- if (HlslFunctionality1)
- break;
- }
-
- if (HlslFunctionality1)
- {
- for (const auto& Input : resources.stage_inputs)
- {
- if (Compiler.has_decoration(Input.id, spv::Decoration::DecorationHlslSemanticGOOGLE))
- {
- const auto& Semantic = Compiler.get_decoration_string(Input.id, spv::Decoration::DecorationHlslSemanticGOOGLE);
- ResourceNamesPoolSize += Semantic.length() + 1;
- ++NumShaderStageInputs;
- }
- else
- {
- LOG_ERROR_MESSAGE("Shader input '", Input.name, "' does not have DecorationHlslSemanticGOOGLE decoration, which is unexpected as the shader declares SPV_GOOGLE_hlsl_functionality1 extension");
- }
- }
- }
- else
- {
- LoadShaderStageInputs = false;
- if (m_IsHLSLSource)
- {
- LOG_WARNING_MESSAGE("SPIRV byte code of shader '", shaderDesc.Name,
- "' does not use SPV_GOOGLE_hlsl_functionality1 extension. "
- "As a result, it is not possible to get semantics of shader inputs and map them to proper locations. "
- "The shader will still work correctly if all attributes are declared in ascending order without any gaps. "
- "Enable SPV_GOOGLE_hlsl_functionality1 in your compiler to allow proper mapping of vertex shader inputs.");
- }
- }
- }
-
- ResourceCounters ResCounters;
- ResCounters.NumUBs = static_cast<Uint32>(resources.uniform_buffers.size());
- ResCounters.NumSBs = static_cast<Uint32>(resources.storage_buffers.size());
- ResCounters.NumImgs = static_cast<Uint32>(resources.storage_images.size());
- ResCounters.NumSmpldImgs = static_cast<Uint32>(resources.sampled_images.size());
- ResCounters.NumACs = static_cast<Uint32>(resources.atomic_counters.size());
- ResCounters.NumSepSmplrs = static_cast<Uint32>(resources.separate_samplers.size());
- ResCounters.NumSepImgs = static_cast<Uint32>(resources.separate_images.size());
- ResCounters.NumInptAtts = static_cast<Uint32>(resources.subpass_inputs.size());
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please set the new resource type counter here");
- Initialize(Allocator, ResCounters, NumShaderStageInputs, ResourceNamesPoolSize);
-
- {
- Uint32 CurrUB = 0;
- for (const auto& UB : resources.uniform_buffers)
- {
- const auto& name = GetUBName(Compiler, UB, ParsedIRSource);
- new (&GetUB(CurrUB++))
- SPIRVShaderResourceAttribs(Compiler,
- UB,
- m_ResourceNames.CopyString(name),
- SPIRVShaderResourceAttribs::ResourceType::UniformBuffer);
- }
- VERIFY_EXPR(CurrUB == GetNumUBs());
- }
-
- {
- Uint32 CurrSB = 0;
- for (const auto& SB : resources.storage_buffers)
- {
- auto BufferFlags = Compiler.get_buffer_block_flags(SB.id);
- auto IsReadOnly = BufferFlags.get(spv::DecorationNonWritable);
- auto ResType = IsReadOnly ?
- SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer :
- SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer;
- new (&GetSB(CurrSB++))
- SPIRVShaderResourceAttribs(Compiler,
- SB,
- m_ResourceNames.CopyString(SB.name),
- ResType);
- }
- VERIFY_EXPR(CurrSB == GetNumSBs());
- }
-
- {
- Uint32 CurrSmplImg = 0;
- for (const auto& SmplImg : resources.sampled_images)
- {
- const auto& type = Compiler.get_type(SmplImg.type_id);
- auto ResType = type.image.dim == spv::DimBuffer ?
- SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer :
- SPIRVShaderResourceAttribs::ResourceType::SampledImage;
- new (&GetSmpldImg(CurrSmplImg++))
- SPIRVShaderResourceAttribs(Compiler,
- SmplImg,
- m_ResourceNames.CopyString(SmplImg.name),
- ResType);
- }
- VERIFY_EXPR(CurrSmplImg == GetNumSmpldImgs());
- }
-
- {
- Uint32 CurrImg = 0;
- for (const auto& Img : resources.storage_images)
- {
- const auto& type = Compiler.get_type(Img.type_id);
- auto ResType = type.image.dim == spv::DimBuffer ?
- SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer :
- SPIRVShaderResourceAttribs::ResourceType::StorageImage;
- new (&GetImg(CurrImg++))
- SPIRVShaderResourceAttribs(Compiler,
- Img,
- m_ResourceNames.CopyString(Img.name),
- ResType);
- }
- VERIFY_EXPR(CurrImg == GetNumImgs());
- }
-
- {
- Uint32 CurrAC = 0;
- for (const auto& AC : resources.atomic_counters)
- {
- new (&GetAC(CurrAC++))
- SPIRVShaderResourceAttribs(Compiler,
- AC,
- m_ResourceNames.CopyString(AC.name),
- SPIRVShaderResourceAttribs::ResourceType::AtomicCounter);
- }
- VERIFY_EXPR(CurrAC == GetNumACs());
- }
-
- {
- Uint32 CurrSepSmpl = 0;
- for (const auto& SepSam : resources.separate_samplers)
- {
- new (&GetSepSmplr(CurrSepSmpl++))
- SPIRVShaderResourceAttribs(Compiler,
- SepSam,
- m_ResourceNames.CopyString(SepSam.name),
- SPIRVShaderResourceAttribs::ResourceType::SeparateSampler);
- }
- VERIFY_EXPR(CurrSepSmpl == GetNumSepSmplrs());
- }
-
- {
- Uint32 CurrSepImg = 0;
- for (const auto& SepImg : resources.separate_images)
- {
- const auto& type = Compiler.get_type(SepImg.type_id);
- auto ResType = type.image.dim == spv::DimBuffer ?
- SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer :
- SPIRVShaderResourceAttribs::ResourceType::SeparateImage;
-
- Uint32 SamplerInd = SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd;
- if (CombinedSamplerSuffix != nullptr)
- {
- auto NumSepSmpls = GetNumSepSmplrs();
- for (SamplerInd = 0; SamplerInd < NumSepSmpls; ++SamplerInd)
- {
- auto& SepSmplr = GetSepSmplr(SamplerInd);
- if (StreqSuff(SepSmplr.Name, SepImg.name.c_str(), CombinedSamplerSuffix))
- {
- SepSmplr.AssignSeparateImage(CurrSepImg);
- break;
- }
- }
- if (SamplerInd == NumSepSmpls)
- SamplerInd = SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd;
- else
- {
- if (ResType == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer)
- {
- LOG_WARNING_MESSAGE("Combined image sampler assigned to uniform texel buffer '", SepImg.name, "' will be ignored");
- SamplerInd = SPIRVShaderResourceAttribs::InvalidSepSmplrOrImgInd;
- }
- }
- }
- auto* pNewSepImg = new (&GetSepImg(CurrSepImg++))
- SPIRVShaderResourceAttribs(Compiler,
- SepImg,
- m_ResourceNames.CopyString(SepImg.name),
- ResType,
- SamplerInd);
- if (ResType == SPIRVShaderResourceAttribs::ResourceType::SeparateImage && pNewSepImg->IsValidSepSamplerAssigned())
- {
-#ifdef DILIGENT_DEVELOPMENT
- const auto& SepSmplr = GetSepSmplr(pNewSepImg->GetAssignedSepSamplerInd());
- DEV_CHECK_ERR(SepSmplr.ArraySize == 1 || SepSmplr.ArraySize == pNewSepImg->ArraySize,
- "Array size (", SepSmplr.ArraySize, ") of separate sampler variable '",
- SepSmplr.Name, "' must be equal to 1 or be the same as the array size (", pNewSepImg->ArraySize,
- ") of separate image variable '", pNewSepImg->Name, "' it is assigned to");
-#endif
- }
- }
- VERIFY_EXPR(CurrSepImg == GetNumSepImgs());
- }
-
- {
- Uint32 CurrSubpassInput = 0;
- for (const auto& SubpassInput : resources.subpass_inputs)
- {
- new (&GetInptAtt(CurrSubpassInput++))
- SPIRVShaderResourceAttribs(Compiler,
- SubpassInput,
- m_ResourceNames.CopyString(SubpassInput.name),
- SPIRVShaderResourceAttribs::ResourceType::InputAttachment);
- }
- VERIFY_EXPR(CurrSubpassInput == GetNumInptAtts());
- }
-
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please initialize SPIRVShaderResourceAttribs for the new resource type here");
-
- if (CombinedSamplerSuffix != nullptr)
- {
- m_CombinedSamplerSuffix = m_ResourceNames.CopyString(CombinedSamplerSuffix);
- }
-
- m_ShaderName = m_ResourceNames.CopyString(shaderDesc.Name);
-
- if (LoadShaderStageInputs)
- {
- Uint32 CurrStageInput = 0;
- for (const auto& Input : resources.stage_inputs)
- {
- if (Compiler.has_decoration(Input.id, spv::Decoration::DecorationHlslSemanticGOOGLE))
- {
- const auto& Semantic = Compiler.get_decoration_string(Input.id, spv::Decoration::DecorationHlslSemanticGOOGLE);
- new (&GetShaderStageInputAttribs(CurrStageInput++))
- SPIRVShaderStageInputAttribs(m_ResourceNames.CopyString(Semantic), GetDecorationOffset(Compiler, Input, spv::Decoration::DecorationLocation));
- }
- }
- VERIFY_EXPR(CurrStageInput == GetNumShaderStageInputs());
- }
-
- VERIFY(m_ResourceNames.GetRemainingSize() == 0, "Names pool must be empty");
-
- //LOG_INFO_MESSAGE(DumpResources());
-
-#ifdef DILIGENT_DEVELOPMENT
- if (CombinedSamplerSuffix != nullptr)
- {
- for (Uint32 n = 0; n < GetNumSepSmplrs(); ++n)
- {
- const auto& SepSmplr = GetSepSmplr(n);
- if (!SepSmplr.IsValidSepImageAssigned())
- LOG_ERROR_MESSAGE("Shader '", shaderDesc.Name, "' uses combined texture samplers, but separate sampler '", SepSmplr.Name, "' is not assigned to any texture");
- }
- }
-#endif
-}
-
-void SPIRVShaderResources::Initialize(IMemoryAllocator& Allocator,
- const ResourceCounters& Counters,
- Uint32 NumShaderStageInputs,
- size_t ResourceNamesPoolSize)
-{
- Uint32 CurrentOffset = 0;
- constexpr Uint32 MaxOffset = std::numeric_limits<OffsetType>::max();
- auto AdvanceOffset = [&CurrentOffset, MaxOffset](Uint32 NumResources) {
- VERIFY(CurrentOffset <= MaxOffset, "Current offset (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
- (void)MaxOffset;
- auto Offset = static_cast<OffsetType>(CurrentOffset);
- CurrentOffset += NumResources;
- return Offset;
- };
-
- auto UniformBufferOffset = AdvanceOffset(Counters.NumUBs);
- (void)UniformBufferOffset;
- m_StorageBufferOffset = AdvanceOffset(Counters.NumSBs);
- m_StorageImageOffset = AdvanceOffset(Counters.NumImgs);
- m_SampledImageOffset = AdvanceOffset(Counters.NumSmpldImgs);
- m_AtomicCounterOffset = AdvanceOffset(Counters.NumACs);
- m_SeparateSamplerOffset = AdvanceOffset(Counters.NumSepSmplrs);
- m_SeparateImageOffset = AdvanceOffset(Counters.NumSepImgs);
- m_InputAttachmentOffset = AdvanceOffset(Counters.NumInptAtts);
- m_TotalResources = AdvanceOffset(0);
- static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 11, "Please update the new resource type offset");
-
- VERIFY(NumShaderStageInputs <= MaxOffset, "Max offset exceeded");
- m_NumShaderStageInputs = static_cast<OffsetType>(NumShaderStageInputs);
-
- auto AlignedResourceNamesPoolSize = Align(ResourceNamesPoolSize, sizeof(void*));
-
- static_assert(sizeof(SPIRVShaderResourceAttribs) % sizeof(void*) == 0, "Size of SPIRVShaderResourceAttribs struct must be multiple of sizeof(void*)");
- // clang-format off
- auto MemorySize = m_TotalResources * sizeof(SPIRVShaderResourceAttribs) +
- m_NumShaderStageInputs * sizeof(SPIRVShaderStageInputAttribs) +
- AlignedResourceNamesPoolSize * sizeof(char);
-
- VERIFY_EXPR(GetNumUBs() == Counters.NumUBs);
- VERIFY_EXPR(GetNumSBs() == Counters.NumSBs);
- VERIFY_EXPR(GetNumImgs() == Counters.NumImgs);
- VERIFY_EXPR(GetNumSmpldImgs() == Counters.NumSmpldImgs);
- VERIFY_EXPR(GetNumACs() == Counters.NumACs);
- VERIFY_EXPR(GetNumSepSmplrs() == Counters.NumSepSmplrs);
- VERIFY_EXPR(GetNumSepImgs() == Counters.NumSepImgs);
- // clang-format on
-
- if (MemorySize)
- {
- auto* pRawMem = Allocator.Allocate(MemorySize, "Memory for shader resources", __FILE__, __LINE__);
- m_MemoryBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, Allocator);
- char* NamesPool = reinterpret_cast<char*>(m_MemoryBuffer.get()) +
- m_TotalResources * sizeof(SPIRVShaderResourceAttribs) +
- m_NumShaderStageInputs * sizeof(SPIRVShaderStageInputAttribs);
- m_ResourceNames.AssignMemory(NamesPool, ResourceNamesPoolSize);
- }
-}
-
-SPIRVShaderResources::~SPIRVShaderResources()
-{
- for (Uint32 n = 0; n < GetNumUBs(); ++n)
- GetUB(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumSBs(); ++n)
- GetSB(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumImgs(); ++n)
- GetImg(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumSmpldImgs(); ++n)
- GetSmpldImg(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumACs(); ++n)
- GetAC(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumSepSmplrs(); ++n)
- GetSepSmplr(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumSepImgs(); ++n)
- GetSepImg(n).~SPIRVShaderResourceAttribs();
-
- for (Uint32 n = 0; n < GetNumShaderStageInputs(); ++n)
- GetShaderStageInputAttribs(n).~SPIRVShaderStageInputAttribs();
-}
-
-
-
-std::string SPIRVShaderResources::DumpResources()
-{
- std::stringstream ss;
- ss << "Shader '" << m_ShaderName << "' resource stats: total resources: " << GetTotalResources() << ":" << std::endl
- << "UBs: " << GetNumUBs() << "; SBs: " << GetNumSBs() << "; Imgs: " << GetNumImgs() << "; Smpl Imgs: " << GetNumSmpldImgs()
- << "; ACs: " << GetNumACs() << "; Sep Imgs: " << GetNumSepImgs() << "; Sep Smpls: " << GetNumSepSmplrs() << '.' << std::endl
- << "Resources:";
-
- Uint32 ResNum = 0;
- auto DumpResource = [&ss, &ResNum](const SPIRVShaderResourceAttribs& Res) {
- std::stringstream FullResNameSS;
- FullResNameSS << '\'' << Res.Name;
- if (Res.ArraySize > 1)
- FullResNameSS << '[' << Res.ArraySize << ']';
- FullResNameSS << '\'';
- ss << std::setw(32) << FullResNameSS.str();
-
- if (Res.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage && Res.IsValidSepSamplerAssigned())
- {
- ss << " Assigned sep sampler ind: " << Res.GetAssignedSepSamplerInd();
- }
- else if (Res.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.IsValidSepImageAssigned())
- {
- ss << " Assigned sep image ind: " << Res.GetAssignedSepImageInd();
- }
-
- ++ResNum;
- };
-
- ProcessResources(
- [&](const SPIRVShaderResourceAttribs& UB, Uint32) //
- {
- VERIFY(UB.Type == SPIRVShaderResourceAttribs::ResourceType::UniformBuffer, "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum << " Uniform Buffer ";
- DumpResource(UB);
- },
- [&](const SPIRVShaderResourceAttribs& SB, Uint32) //
- {
- VERIFY(SB.Type == SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer ||
- SB.Type == SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer,
- "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum
- << (SB.Type == SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer ? " RO Storage Buffer" : " RW Storage Buffer");
- DumpResource(SB);
- },
- [&](const SPIRVShaderResourceAttribs& Img, Uint32) //
- {
- if (Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageImage)
- {
- ss << std::endl
- << std::setw(3) << ResNum << " Storage Image ";
- }
- else if (Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer)
- {
- ss << std::endl
- << std::setw(3) << ResNum << " Storage Txl Buff ";
- }
- else
- UNEXPECTED("Unexpected resource type");
- DumpResource(Img);
- },
- [&](const SPIRVShaderResourceAttribs& SmplImg, Uint32) //
- {
- if (SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage)
- {
- ss << std::endl
- << std::setw(3) << ResNum << " Sampled Image ";
- }
- else if (SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer)
- {
- ss << std::endl
- << std::setw(3) << ResNum << " Uniform Txl Buff ";
- }
- else
- UNEXPECTED("Unexpected resource type");
- DumpResource(SmplImg);
- },
- [&](const SPIRVShaderResourceAttribs& AC, Uint32) //
- {
- VERIFY(AC.Type == SPIRVShaderResourceAttribs::ResourceType::AtomicCounter, "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum << " Atomic Cntr ";
- DumpResource(AC);
- },
- [&](const SPIRVShaderResourceAttribs& SepSmpl, Uint32) //
- {
- VERIFY(SepSmpl.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum << " Separate Smpl ";
- DumpResource(SepSmpl);
- },
- [&](const SPIRVShaderResourceAttribs& SepImg, Uint32) //
- {
- VERIFY(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage, "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum << " Separate Img ";
- DumpResource(SepImg);
- },
- [&](const SPIRVShaderResourceAttribs& InptAtt, Uint32) //
- {
- VERIFY(InptAtt.Type == SPIRVShaderResourceAttribs::ResourceType::InputAttachment, "Unexpected resource type");
- ss << std::endl
- << std::setw(3) << ResNum << " Input Attachment ";
- DumpResource(InptAtt);
- } //
- );
- VERIFY_EXPR(ResNum == GetTotalResources());
-
- return ss.str();
-}
-
-
-
-bool SPIRVShaderResources::IsCompatibleWith(const SPIRVShaderResources& Resources) const
-{
- // clang-format off
- if( GetNumUBs() != Resources.GetNumUBs() ||
- GetNumSBs() != Resources.GetNumSBs() ||
- GetNumImgs() != Resources.GetNumImgs() ||
- GetNumSmpldImgs() != Resources.GetNumSmpldImgs() ||
- GetNumACs() != Resources.GetNumACs() ||
- GetNumSepImgs() != Resources.GetNumSepImgs() ||
- GetNumSepSmplrs() != Resources.GetNumSepSmplrs())
- return false;
- // clang-format on
- VERIFY_EXPR(GetTotalResources() == Resources.GetTotalResources());
-
- bool IsCompatible = true;
- ProcessResources(
- [&](const SPIRVShaderResourceAttribs& Res, Uint32 n) {
- const auto& Res2 = Resources.GetResource(n);
- if (!Res.IsCompatibleWith(Res2))
- IsCompatible = false;
- });
-
- return IsCompatible;
-}
-
-} // namespace Diligent
diff --git a/Graphics/GLSLTools/src/SPIRVUtils.cpp b/Graphics/GLSLTools/src/SPIRVUtils.cpp
deleted file mode 100644
index 6543d4fb..00000000
--- a/Graphics/GLSLTools/src/SPIRVUtils.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * 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 <unordered_set>
-#include <unordered_map>
-#include <memory>
-#include <array>
-
-#if (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
-# include <MoltenGLSLToSPIRVConverter/GLSLToSPIRVConverter.h>
-#else
-# define ENABLE_HLSL
-# include "SPIRV/GlslangToSpv.h"
-#endif
-
-#include "SPIRVUtils.hpp"
-#include "DebugUtilities.hpp"
-#include "DataBlobImpl.hpp"
-#include "RefCntAutoPtr.hpp"
-
-#include "spirv-tools/optimizer.hpp"
-
-// clang-format off
-static const char g_HLSLDefinitions[] =
-{
-#include "../../GraphicsEngineD3DBase/include/HLSLDefinitions_inc.fxh"
-};
-// clang-format on
-
-namespace Diligent
-{
-
-// Implemented in GLSLSourceBuilder.cpp
-const char* GetShaderTypeDefines(SHADER_TYPE Type);
-
-void InitializeGlslang()
-{
- glslang::InitializeProcess();
-}
-
-void FinalizeGlslang()
-{
- glslang::FinalizeProcess();
-}
-
-EShLanguage ShaderTypeToShLanguage(SHADER_TYPE ShaderType)
-{
- static_assert(SHADER_TYPE_LAST == 0x080, "Please handle the new shader type in the switch below");
- switch (ShaderType)
- {
- // clang-format off
- case SHADER_TYPE_VERTEX: return EShLangVertex;
- case SHADER_TYPE_HULL: return EShLangTessControl;
- case SHADER_TYPE_DOMAIN: return EShLangTessEvaluation;
- case SHADER_TYPE_GEOMETRY: return EShLangGeometry;
- case SHADER_TYPE_PIXEL: return EShLangFragment;
- case SHADER_TYPE_COMPUTE: return EShLangCompute;
- case SHADER_TYPE_AMPLIFICATION: return EShLangTaskNV;
- case SHADER_TYPE_MESH: return EShLangMeshNV;
- // clang-format on
- default:
- UNEXPECTED("Unexpected shader type");
- return EShLangCount;
- }
-}
-
-static TBuiltInResource InitResources()
-{
- TBuiltInResource Resources;
-
- Resources.maxLights = 32;
- Resources.maxClipPlanes = 6;
- Resources.maxTextureUnits = 32;
- Resources.maxTextureCoords = 32;
- Resources.maxVertexAttribs = 64;
- Resources.maxVertexUniformComponents = 4096;
- Resources.maxVaryingFloats = 64;
- Resources.maxVertexTextureImageUnits = 32;
- Resources.maxCombinedTextureImageUnits = 80;
- Resources.maxTextureImageUnits = 32;
- Resources.maxFragmentUniformComponents = 4096;
- Resources.maxDrawBuffers = 32;
- Resources.maxVertexUniformVectors = 128;
- Resources.maxVaryingVectors = 8;
- Resources.maxFragmentUniformVectors = 16;
- Resources.maxVertexOutputVectors = 16;
- Resources.maxFragmentInputVectors = 15;
- Resources.minProgramTexelOffset = -8;
- Resources.maxProgramTexelOffset = 7;
- Resources.maxClipDistances = 8;
- Resources.maxComputeWorkGroupCountX = 65535;
- Resources.maxComputeWorkGroupCountY = 65535;
- Resources.maxComputeWorkGroupCountZ = 65535;
- Resources.maxComputeWorkGroupSizeX = 1024;
- Resources.maxComputeWorkGroupSizeY = 1024;
- Resources.maxComputeWorkGroupSizeZ = 64;
- Resources.maxComputeUniformComponents = 1024;
- Resources.maxComputeTextureImageUnits = 16;
- Resources.maxComputeImageUniforms = 8;
- Resources.maxComputeAtomicCounters = 8;
- Resources.maxComputeAtomicCounterBuffers = 1;
- Resources.maxVaryingComponents = 60;
- Resources.maxVertexOutputComponents = 64;
- Resources.maxGeometryInputComponents = 64;
- Resources.maxGeometryOutputComponents = 128;
- Resources.maxFragmentInputComponents = 128;
- Resources.maxImageUnits = 8;
- Resources.maxCombinedImageUnitsAndFragmentOutputs = 8;
- Resources.maxCombinedShaderOutputResources = 8;
- Resources.maxImageSamples = 0;
- Resources.maxVertexImageUniforms = 0;
- Resources.maxTessControlImageUniforms = 0;
- Resources.maxTessEvaluationImageUniforms = 0;
- Resources.maxGeometryImageUniforms = 0;
- Resources.maxFragmentImageUniforms = 8;
- Resources.maxCombinedImageUniforms = 8;
- Resources.maxGeometryTextureImageUnits = 16;
- Resources.maxGeometryOutputVertices = 256;
- Resources.maxGeometryTotalOutputComponents = 1024;
- Resources.maxGeometryUniformComponents = 1024;
- Resources.maxGeometryVaryingComponents = 64;
- Resources.maxTessControlInputComponents = 128;
- Resources.maxTessControlOutputComponents = 128;
- Resources.maxTessControlTextureImageUnits = 16;
- Resources.maxTessControlUniformComponents = 1024;
- Resources.maxTessControlTotalOutputComponents = 4096;
- Resources.maxTessEvaluationInputComponents = 128;
- Resources.maxTessEvaluationOutputComponents = 128;
- Resources.maxTessEvaluationTextureImageUnits = 16;
- Resources.maxTessEvaluationUniformComponents = 1024;
- Resources.maxTessPatchComponents = 120;
- Resources.maxPatchVertices = 32;
- Resources.maxTessGenLevel = 64;
- Resources.maxViewports = 16;
- Resources.maxVertexAtomicCounters = 0;
- Resources.maxTessControlAtomicCounters = 0;
- Resources.maxTessEvaluationAtomicCounters = 0;
- Resources.maxGeometryAtomicCounters = 0;
- Resources.maxFragmentAtomicCounters = 8;
- Resources.maxCombinedAtomicCounters = 8;
- Resources.maxAtomicCounterBindings = 1;
- Resources.maxVertexAtomicCounterBuffers = 0;
- Resources.maxTessControlAtomicCounterBuffers = 0;
- Resources.maxTessEvaluationAtomicCounterBuffers = 0;
- Resources.maxGeometryAtomicCounterBuffers = 0;
- Resources.maxFragmentAtomicCounterBuffers = 1;
- Resources.maxCombinedAtomicCounterBuffers = 1;
- Resources.maxAtomicCounterBufferSize = 16384;
- Resources.maxTransformFeedbackBuffers = 4;
- Resources.maxTransformFeedbackInterleavedComponents = 64;
- Resources.maxCullDistances = 8;
- Resources.maxCombinedClipAndCullDistances = 8;
- Resources.maxSamples = 4;
- Resources.maxMeshOutputVerticesNV = 256;
- Resources.maxMeshOutputPrimitivesNV = 512;
- Resources.maxMeshWorkGroupSizeX_NV = 32;
- Resources.maxMeshWorkGroupSizeY_NV = 1;
- Resources.maxMeshWorkGroupSizeZ_NV = 1;
- Resources.maxTaskWorkGroupSizeX_NV = 32;
- Resources.maxTaskWorkGroupSizeY_NV = 1;
- Resources.maxTaskWorkGroupSizeZ_NV = 1;
- Resources.maxMeshViewCountNV = 4;
-
- Resources.limits.nonInductiveForLoops = 1;
- Resources.limits.whileLoops = 1;
- Resources.limits.doWhileLoops = 1;
- Resources.limits.generalUniformIndexing = 1;
- Resources.limits.generalAttributeMatrixVectorIndexing = 1;
- Resources.limits.generalVaryingIndexing = 1;
- Resources.limits.generalSamplerIndexing = 1;
- Resources.limits.generalVariableIndexing = 1;
- Resources.limits.generalConstantMatrixVectorIndexing = 1;
-
- return Resources;
-}
-
-class IoMapResolver final : public glslang::TIoMapResolver
-{
-public:
- // Should return true if the resulting/current binding would be okay.
- // Basic idea is to do aliasing binding checks with this.
- virtual bool validateBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return true;
- }
-
- // Should return a value >= 0 if the current binding should be overridden.
- // Return -1 if the current binding (including no binding) should be kept.
- virtual int resolveBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- // We do not care about actual binding value here.
- // We only need decoration to be present in SPIRV
- return 0;
- }
-
- // Should return a value >= 0 if the current set should be overridden.
- // Return -1 if the current set (including no set) should be kept.
- virtual int resolveSet(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- // We do not care about actual descriptor set value here.
- // We only need decoration to be present in SPIRV
- return 0;
- }
-
- // Should return a value >= 0 if the current location should be overridden.
- // Return -1 if the current location (including no location) should be kept.
- virtual int resolveUniformLocation(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return -1;
- }
-
- // Should return true if the resulting/current setup would be okay.
- // Basic idea is to do aliasing checks and reject invalid semantic names.
- virtual bool validateInOut(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return true;
- }
-
- // Should return a value >= 0 if the current location should be overridden.
- // Return -1 if the current location (including no location) should be kept.
- virtual int resolveInOutLocation(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return -1;
- }
-
- // Should return a value >= 0 if the current component index should be overridden.
- // Return -1 if the current component index (including no index) should be kept.
- virtual int resolveInOutComponent(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return -1;
- }
-
- // Should return a value >= 0 if the current color index should be overridden.
- // Return -1 if the current color index (including no index) should be kept.
- virtual int resolveInOutIndex(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- return -1;
- }
-
- // Notification of a uniform variable
- virtual void notifyBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- }
-
- // Notification of a in or out variable
- virtual void notifyInOut(EShLanguage stage, glslang::TVarEntryInfo& ent) override final
- {
- }
-
- // Called by mapIO when it starts its notify pass for the given stage
- virtual void beginNotifications(EShLanguage stage) override final
- {
- }
-
- // Called by mapIO when it has finished the notify pass
- virtual void endNotifications(EShLanguage stage) override final
- {
- }
-
- // Called by mipIO when it starts its resolve pass for the given stage
- virtual void beginResolve(EShLanguage stage) override final
- {
- }
-
- // Called by mapIO when it has finished the resolve pass
- virtual void endResolve(EShLanguage stage) override final
- {
- }
-
- // Called by mapIO when it starts its symbol collect for teh given stage
- virtual void beginCollect(EShLanguage stage) override final
- {
- }
-
- // Called by mapIO when it has finished the symbol collect
- virtual void endCollect(EShLanguage stage) override final
- {
- }
-
- // Called by TSlotCollector to resolve storage locations or bindings
- virtual void reserverStorageSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) override final
- {
- }
-
- // Called by TSlotCollector to resolve resource locations or bindings
- virtual void reserverResourceSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) override final
- {
- }
-
- // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
- virtual void addStage(EShLanguage stage) override final
- {
- }
-};
-
-static void LogCompilerError(const char* DebugOutputMessage,
- const char* InfoLog,
- const char* InfoDebugLog,
- const char* ShaderSource,
- size_t SourceCodeLen,
- IDataBlob** ppCompilerOutput)
-{
- std::string ErrorLog(InfoLog);
- if (*InfoDebugLog != '\0')
- {
- ErrorLog.push_back('\n');
- ErrorLog.append(InfoDebugLog);
- }
- LOG_ERROR_MESSAGE(DebugOutputMessage, ErrorLog);
-
- if (ppCompilerOutput != nullptr)
- {
- auto* pOutputDataBlob = MakeNewRCObj<DataBlobImpl>()(SourceCodeLen + 1 + ErrorLog.length() + 1);
- char* DataPtr = reinterpret_cast<char*>(pOutputDataBlob->GetDataPtr());
- memcpy(DataPtr, ErrorLog.data(), ErrorLog.length() + 1);
- memcpy(DataPtr + ErrorLog.length() + 1, ShaderSource, SourceCodeLen + 1);
- pOutputDataBlob->QueryInterface(IID_DataBlob, reinterpret_cast<IObject**>(ppCompilerOutput));
- }
-}
-
-static std::vector<unsigned int> CompileShaderInternal(glslang::TShader& Shader,
- EShMessages messages,
- glslang::TShader::Includer* pIncluder,
- const char* ShaderSource,
- size_t SourceCodeLen,
- IDataBlob** ppCompilerOutput)
-{
- Shader.setAutoMapBindings(true);
- TBuiltInResource Resources = InitResources();
-
- auto ParseResult = pIncluder != nullptr ?
- Shader.parse(&Resources, 100, false, messages, *pIncluder) :
- Shader.parse(&Resources, 100, false, messages);
- if (!ParseResult)
- {
- LogCompilerError("Failed to parse shader source: \n", Shader.getInfoLog(), Shader.getInfoDebugLog(), ShaderSource, SourceCodeLen, ppCompilerOutput);
- return {};
- }
-
- glslang::TProgram Program;
- Program.addShader(&Shader);
- if (!Program.link(messages))
- {
- LogCompilerError("Failed to link program: \n", Program.getInfoLog(), Program.getInfoDebugLog(), ShaderSource, SourceCodeLen, ppCompilerOutput);
- return {};
- }
-
- IoMapResolver Resovler;
- // This step is essential to set bindings and descriptor sets
- Program.mapIO(&Resovler);
-
- std::vector<unsigned int> spirv;
- glslang::GlslangToSpv(*Program.getIntermediate(Shader.getStage()), spirv);
-
- return std::move(spirv);
-}
-
-
-class IncluderImpl : public glslang::TShader::Includer
-{
-public:
- IncluderImpl(IShaderSourceInputStreamFactory* pInputStreamFactory) :
- m_pInputStreamFactory(pInputStreamFactory)
- {}
-
- // For the "system" or <>-style includes; search the "system" paths.
- virtual IncludeResult* includeSystem(const char* headerName,
- const char* /*includerName*/,
- size_t /*inclusionDepth*/)
- {
- DEV_CHECK_ERR(m_pInputStreamFactory != nullptr, "The shader source conains #include directives, but no input stream factory was provided");
- RefCntAutoPtr<IFileStream> pSourceStream;
- m_pInputStreamFactory->CreateInputStream(headerName, &pSourceStream);
- if (pSourceStream == nullptr)
- {
- LOG_ERROR("Failed to open shader include file \"", headerName, "\". Check that the file exists");
- return nullptr;
- }
-
- RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0));
- pSourceStream->ReadBlob(pFileData);
- auto* pNewInclude =
- new IncludeResult{
- headerName,
- reinterpret_cast<const char*>(pFileData->GetDataPtr()),
- pFileData->GetSize(),
- nullptr};
-
- m_IncludeRes.emplace(pNewInclude);
- m_DataBlobs.emplace(pNewInclude, std::move(pFileData));
- return pNewInclude;
- }
-
- // For the "local"-only aspect of a "" include. Should not search in the
- // "system" paths, because on returning a failure, the parser will
- // call includeSystem() to look in the "system" locations.
- virtual IncludeResult* includeLocal(const char* /*headerName*/,
- const char* /*includerName*/,
- size_t /*inclusionDepth*/)
- {
- return nullptr;
- }
-
- // Signals that the parser will no longer use the contents of the
- // specified IncludeResult.
- virtual void releaseInclude(IncludeResult* IncldRes)
- {
- m_DataBlobs.erase(IncldRes);
- }
-
-private:
- IShaderSourceInputStreamFactory* const m_pInputStreamFactory;
- std::unordered_set<std::unique_ptr<IncludeResult>> m_IncludeRes;
- std::unordered_map<IncludeResult*, RefCntAutoPtr<IDataBlob>> m_DataBlobs;
-};
-
-std::vector<unsigned int> HLSLtoSPIRV(const ShaderCreateInfo& Attribs,
- const char* ExtraDefinitions,
- IDataBlob** ppCompilerOutput)
-{
- EShLanguage ShLang = ShaderTypeToShLanguage(Attribs.Desc.ShaderType);
- glslang::TShader Shader{ShLang};
- EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules | EShMsgReadHlsl | EShMsgHlslLegalization);
-
- VERIFY_EXPR(Attribs.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.setEnvTargetHlslFunctionality1();
-
- 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 Defines = g_HLSLDefinitions;
- if (const auto* ShaderTypeDefine = GetShaderTypeDefines(Attribs.Desc.ShaderType))
- Defines += ShaderTypeDefine;
-
- if (ExtraDefinitions != nullptr)
- Defines += ExtraDefinitions;
-
- if (Attribs.Macros != nullptr)
- {
- Defines += '\n';
- auto* pMacro = Attribs.Macros;
- while (pMacro->Name != nullptr && pMacro->Definition != nullptr)
- {
- Defines += "#define ";
- Defines += pMacro->Name;
- Defines += ' ';
- Defines += pMacro->Definition;
- Defines += "\n";
- ++pMacro;
- }
- }
- Shader.setPreamble(Defines.c_str());
-
- const char* ShaderStrings[] = {SourceCode};
- const int ShaderStringLenghts[] = {SourceCodeLen};
- const char* Names[] = {Attribs.FilePath != nullptr ? Attribs.FilePath : ""};
- Shader.setStringsWithLengthsAndNames(ShaderStrings, ShaderStringLenghts, Names, 1);
-
- IncluderImpl Includer(Attribs.pShaderSourceStreamFactory);
-
- auto SPIRV = CompileShaderInternal(Shader, messages, &Includer, SourceCode, SourceCodeLen, ppCompilerOutput);
- if (SPIRV.empty())
- return SPIRV;
-
- // SPIR-V bytecode generated from HLSL must be legalized to
- // turn it into a valid vulkan SPIR-V shader
- spvtools::Optimizer SpirvOptimizer(SPV_ENV_VULKAN_1_0);
- SpirvOptimizer.RegisterLegalizationPasses();
- SpirvOptimizer.RegisterPerformancePasses();
- std::vector<uint32_t> LegalizedSPIRV;
- if (SpirvOptimizer.Run(SPIRV.data(), SPIRV.size(), &LegalizedSPIRV))
- {
- return std::move(LegalizedSPIRV);
- }
- else
- {
- LOG_ERROR("Failed to legalize SPIR-V shader generated by HLSL front-end. This may result in undefined behavior.");
- return std::move(SPIRV);
- }
-}
-
-std::vector<unsigned int> GLSLtoSPIRV(const SHADER_TYPE ShaderType, const char* ShaderSource, int SourceCodeLen, IDataBlob** ppCompilerOutput)
-{
- EShLanguage ShLang = ShaderTypeToShLanguage(ShaderType);
- glslang::TShader Shader(ShLang);
-
- EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
-
- const char* ShaderStrings[] = {ShaderSource};
- int Lenghts[] = {SourceCodeLen};
- Shader.setStringsWithLengths(ShaderStrings, Lenghts, 1);
-
- auto SPIRV = CompileShaderInternal(Shader, messages, nullptr, ShaderSource, SourceCodeLen, ppCompilerOutput);
-
- spvtools::Optimizer SpirvOptimizer(SPV_ENV_VULKAN_1_0);
- SpirvOptimizer.RegisterPerformancePasses();
- std::vector<uint32_t> OptimizedSPIRV;
- if (SpirvOptimizer.Run(SPIRV.data(), SPIRV.size(), &OptimizedSPIRV))
- {
- return std::move(OptimizedSPIRV);
- }
- else
- {
- LOG_ERROR("Failed to optimize SPIR-V.");
- return std::move(SPIRV);
- }
-}
-
-} // namespace Diligent