diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-04-26 16:05:36 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-04-26 16:05:36 +0000 |
| commit | 6e5be00eb6db740e5db88a49f5a158f74fd7eb47 (patch) | |
| tree | b526d1f7dd966641f1de1ece95fb79c21b0ceb16 /Graphics | |
| parent | Added SPIRVShaderResources class (diff) | |
| download | DiligentCore-6e5be00eb6db740e5db88a49f5a158f74fd7eb47.tar.gz DiligentCore-6e5be00eb6db740e5db88a49f5a158f74fd7eb47.zip | |
Working on SPIRV resource loading
Diffstat (limited to 'Graphics')
| -rw-r--r-- | Graphics/GLSLTools/include/SPIRVShaderResources.h | 14 | ||||
| -rw-r--r-- | Graphics/GLSLTools/src/SPIRVShaderResources.cpp | 257 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h | 18 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 8 |
4 files changed, 230 insertions, 67 deletions
diff --git a/Graphics/GLSLTools/include/SPIRVShaderResources.h b/Graphics/GLSLTools/include/SPIRVShaderResources.h index cf2efe88..0b740b14 100644 --- a/Graphics/GLSLTools/include/SPIRVShaderResources.h +++ b/Graphics/GLSLTools/include/SPIRVShaderResources.h @@ -116,18 +116,14 @@ struct SPIRVShaderResourceAttribs class SPIRVShaderResources { public: - SPIRVShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType); + SPIRVShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType, std::vector<uint32_t> spirv_binary); - void Load(std::vector<uint32_t> spirv_binary); - -#if 0 // Copies specified types of resources from another ShaderResources objects // Only resources listed in AllowedVarTypes are copied SPIRVShaderResources(IMemoryAllocator &Allocator, - const ShaderResources& SPIRVShaderResources, - const SHADER_VARIABLE_TYPE *AllowedVarTypes, - Uint32 NumAllowedTypes); -#endif + const SPIRVShaderResources& SrcResources, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes); SPIRVShaderResources (const SPIRVShaderResources&) = delete; SPIRVShaderResources (SPIRVShaderResources&&) = delete; @@ -239,7 +235,7 @@ public: //size_t GetHash()const; protected: - void Initialize(IMemoryAllocator &Allocator, Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers); + void Initialize(IMemoryAllocator &Allocator, Uint32 NumUBs, Uint32 NumSBs, Uint32 NumImgs, Uint32 NumSmplImgs, Uint32 NumACs, Uint32 NumSepImgs, Uint32 NumSepSmpls); __forceinline SPIRVShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset)noexcept { diff --git a/Graphics/GLSLTools/src/SPIRVShaderResources.cpp b/Graphics/GLSLTools/src/SPIRVShaderResources.cpp index 1cfae64b..36fd9d4f 100644 --- a/Graphics/GLSLTools/src/SPIRVShaderResources.cpp +++ b/Graphics/GLSLTools/src/SPIRVShaderResources.cpp @@ -27,10 +27,220 @@ namespace Diligent { -SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType) : +SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator &Allocator, SHADER_TYPE ShaderType, std::vector<uint32_t> spirv_binary) : m_MemoryBuffer(nullptr, STDDeleterRawMem<void>(Allocator)), m_ShaderType(ShaderType) { + spirv_cross::Compiler Compiler(std::move(spirv_binary)); + + // The SPIR-V is now parsed, and we can perform reflection on it. + spirv_cross::ShaderResources resources = Compiler.get_shader_resources(); + + Initialize(Allocator, + static_cast<Uint32>(resources.uniform_buffers.size()), + static_cast<Uint32>(resources.storage_buffers.size()), + static_cast<Uint32>(resources.storage_images.size()), + static_cast<Uint32>(resources.sampled_images.size()), + static_cast<Uint32>(resources.atomic_counters.size()), + static_cast<Uint32>(resources.separate_images.size()), + static_cast<Uint32>(resources.separate_samplers.size()) + ); + + for (const auto &UB : resources.uniform_buffers) + { + UB.name; + unsigned location = Compiler.get_decoration(UB.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(UB.id, spv::DecorationBinding); + + int a=0; + } + + for (const auto &SB : resources.storage_buffers) + { + SB.name; + unsigned location = Compiler.get_decoration(SB.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(SB.id, spv::DecorationBinding); + + int a = 0; + } + + for (const auto &SmplImg : resources.sampled_images) + { + SmplImg.name; + unsigned location = Compiler.get_decoration(SmplImg.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(SmplImg.id, spv::DecorationBinding); + + int a = 0; + } + + for (const auto &Img : resources.storage_images) + { + Img.name; + unsigned location = Compiler.get_decoration(Img.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(Img.id, spv::DecorationBinding); + + int a = 0; + } + + for (const auto &AC : resources.atomic_counters) + { + AC.name; + unsigned location = Compiler.get_decoration(AC.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(AC.id, spv::DecorationBinding); + + int a = 0; + } + + for (const auto &SepImg : resources.separate_images) + { + SepImg.name; + unsigned location = Compiler.get_decoration(SepImg.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(SepImg.id, spv::DecorationBinding); + + int a = 0; + } + + for (const auto &SepSam : resources.separate_samplers) + { + SepSam.name; + unsigned location = Compiler.get_decoration(SepSam.id, spv::DecorationLocation); + unsigned binding = Compiler.get_decoration(SepSam.id, spv::DecorationBinding); + + int a = 0; + } +} + +SPIRVShaderResources::SPIRVShaderResources(IMemoryAllocator &Allocator, + const SPIRVShaderResources& SrcResources, + const SHADER_VARIABLE_TYPE *AllowedVarTypes, + Uint32 NumAllowedTypes) : + m_MemoryBuffer(nullptr, STDDeleterRawMem<void>(Allocator)), + m_ShaderType(SrcResources.m_ShaderType) +{ + Uint32 NumUBs = 0, NumSBs = 0, NumImgs = 0, NumSmplImgs = 0, NumACs = 0, NumSepImgs = 0, NumSepSmpls = 0; + SrcResources.CountResources(AllowedVarTypes, NumAllowedTypes, NumUBs, NumSBs, NumImgs, NumSmplImgs, NumACs, NumSepImgs, NumSepSmpls); + + Initialize(Allocator, NumUBs, NumSBs, NumImgs, NumSmplImgs, NumACs, NumSepImgs, NumSepSmpls); + + Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + Uint32 CurrUB = 0, CurrSB = 0, CurrImg = 0, CurrSmplImg = 0, CurrAC = 0, CurrSepImg = 0, CurrSepSmpl = 0; + SrcResources.ProcessResources( + AllowedVarTypes, NumAllowedTypes, + + [&](const SPIRVShaderResourceAttribs &UB, Uint32) + { + VERIFY_EXPR(IsAllowedType(UB.VarType, AllowedTypeBits)); + new (&GetUB(CurrUB++)) SPIRVShaderResourceAttribs(UB); + }, + [&](const SPIRVShaderResourceAttribs& SB, Uint32) + { + VERIFY_EXPR(IsAllowedType(SB.VarType, AllowedTypeBits)); + new (&GetSB(CurrSB++)) SPIRVShaderResourceAttribs(SB); + }, + [&](const SPIRVShaderResourceAttribs &Img, Uint32) + { + VERIFY_EXPR(IsAllowedType(Img.VarType, AllowedTypeBits)); + new (&GetImg(CurrImg++)) SPIRVShaderResourceAttribs(Img); + }, + [&](const SPIRVShaderResourceAttribs &SmplImg, Uint32) + { + VERIFY_EXPR(IsAllowedType(SmplImg.VarType, AllowedTypeBits)); + new (&GetSmplImg(CurrSmplImg++)) SPIRVShaderResourceAttribs(SmplImg); + }, + [&](const SPIRVShaderResourceAttribs &AC, Uint32) + { + VERIFY_EXPR(IsAllowedType(AC.VarType, AllowedTypeBits)); + new (&GetAC(CurrAC++)) SPIRVShaderResourceAttribs(AC); + }, + [&](const SPIRVShaderResourceAttribs &SepImg, Uint32) + { + VERIFY_EXPR(IsAllowedType(SepImg.VarType, AllowedTypeBits)); + new (&GetSepImg(CurrSepImg++)) SPIRVShaderResourceAttribs(SepImg); + }, + [&](const SPIRVShaderResourceAttribs &SepSmpl, Uint32) + { + VERIFY_EXPR(IsAllowedType(SepSmpl.VarType, AllowedTypeBits)); + new (&GetSepSmpl(CurrSepSmpl++)) SPIRVShaderResourceAttribs(SepSmpl); + } + ); + + VERIFY_EXPR(CurrUB == NumUBs); + VERIFY_EXPR(CurrSB == NumSBs); + VERIFY_EXPR(CurrImg == NumImgs); + VERIFY_EXPR(CurrSmplImg == NumSmplImgs); + VERIFY_EXPR(CurrAC == NumACs); + VERIFY_EXPR(CurrSepImg == NumSepImgs); + VERIFY_EXPR(CurrSepSmpl == NumSepSmpls); +} + +void SPIRVShaderResources::Initialize(IMemoryAllocator &Allocator, Uint32 NumUBs, Uint32 NumSBs, Uint32 NumImgs, Uint32 NumSmplImgs, Uint32 NumACs, Uint32 NumSepImgs, Uint32 NumSepSmpls) +{ + VERIFY(&m_MemoryBuffer.get_deleter().m_Allocator == &Allocator, "Incosistent allocators provided"); + + static constexpr Uint16 UniformBufferOffset = 0; + + const auto MaxOffset = static_cast<Uint32>(std::numeric_limits<OffsetType>::max()); + VERIFY(UniformBufferOffset + NumUBs <= MaxOffset, "Max offset exceeded"); + m_StorageBufferOffset = UniformBufferOffset + static_cast<OffsetType>(NumUBs); + + VERIFY(m_StorageBufferOffset + NumSBs <= MaxOffset, "Max offset exceeded"); + m_StorageImageOffset = m_StorageBufferOffset + static_cast<OffsetType>(NumSBs); + + VERIFY(m_StorageImageOffset + NumImgs <= MaxOffset, "Max offset exceeded"); + m_SampledImageOffset = m_StorageImageOffset + static_cast<OffsetType>(NumImgs); + + VERIFY(m_SampledImageOffset + NumSmplImgs <= MaxOffset, "Max offset exceeded"); + m_AtomicCounterOffset = m_SampledImageOffset + static_cast<OffsetType>(NumSmplImgs); + + VERIFY(m_AtomicCounterOffset + NumACs <= MaxOffset, "Max offset exceeded"); + m_SeparateImageOffset = m_AtomicCounterOffset + static_cast<OffsetType>(NumACs); + + VERIFY(m_SeparateImageOffset + NumSepImgs <= MaxOffset, "Max offset exceeded"); + m_SeparateSamplerOffset = m_SeparateImageOffset + static_cast<OffsetType>(NumSepImgs); + + VERIFY(m_SeparateSamplerOffset + NumSepSmpls <= MaxOffset, "Max offset exceeded"); + m_BufferEndOffset = m_SeparateSamplerOffset + static_cast<OffsetType>(NumSepSmpls); + + auto MemorySize = m_BufferEndOffset * sizeof(SPIRVShaderResourceAttribs); + + VERIFY_EXPR(GetNumUBs() == NumUBs); + VERIFY_EXPR(GetNumSBs() == NumSBs); + VERIFY_EXPR(GetNumImgs() == NumImgs); + VERIFY_EXPR(GetNumSmplImgs() == NumSmplImgs); + VERIFY_EXPR(GetNumACs() == NumACs); + VERIFY_EXPR(GetNumSepImgs() == NumSepImgs); + VERIFY_EXPR(GetNumSepSmpls() == NumSepSmpls); + + if (MemorySize) + { + auto *pRawMem = Allocator.Allocate(MemorySize, "Memory for shader resources", __FILE__, __LINE__); + m_MemoryBuffer.reset(pRawMem); + } +} + +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 < GetNumSmplImgs(); ++n) + GetSmplImg(n).~SPIRVShaderResourceAttribs(); + + for (Uint32 n = 0; n < GetNumACs(); ++n) + GetAC(n).~SPIRVShaderResourceAttribs(); + + for (Uint32 n = 0; n < GetNumSepImgs(); ++n) + GetSepImg(n).~SPIRVShaderResourceAttribs(); + + for (Uint32 n = 0; n < GetNumSepSmpls(); ++n) + GetSepSmpl(n).~SPIRVShaderResourceAttribs(); } void SPIRVShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, @@ -49,7 +259,7 @@ void SPIRVShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVar NumImgs = 0; NumSmplImgs = 0; NumACs = 0; - NumSepImgs = 0; + NumSepImgs = 0; NumSepSmpls = 0; ProcessResources( @@ -93,47 +303,4 @@ void SPIRVShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVar ); } -void SPIRVShaderResources::Load(std::vector<uint32_t> spirv_binary) -{ - spirv_cross::Compiler Compiler(std::move(spirv_binary)); - - // The SPIR-V is now parsed, and we can perform reflection on it. - spirv_cross::ShaderResources resources = Compiler.get_shader_resources(); - - for(const auto &UB : resources.uniform_buffers) - { - - } - - for (const auto &SB : resources.storage_buffers) - { - - } - - for (const auto &SmplImg : resources.sampled_images) - { - - } - - for (const auto &Img : resources.storage_images) - { - - } - - for (const auto &AC : resources.atomic_counters) - { - - } - - for (const auto &SepImg : resources.separate_images) - { - - } - - for (const auto &SepSam : resources.separate_samplers) - { - - } -} - } diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index a861700f..d2541077 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -31,6 +31,7 @@ #include "ShaderBase.h" #include "ShaderResourceLayoutVk.h" #include "VulkanUtilities/VulkanObjectWrappers.h" +#include "SPIRVShaderResources.h" #ifdef _DEBUG # define VERIFY_SHADER_BINDINGS @@ -62,10 +63,9 @@ public: return m_VkShaderModule; } -/* - const std::shared_ptr<const ShaderResourcesVk>& GetShaderResources()const{return m_pShaderResources;} - const ShaderResourceLayoutVk& GetConstResLayout()const{return m_StaticResLayout;} - + const std::shared_ptr<const SPIRVShaderResources>& GetShaderResources()const{return m_pShaderResources;} + //const ShaderResourceLayoutVk& GetConstResLayout()const{return m_StaticResLayout;} + /* #ifdef VERIFY_SHADER_BINDINGS void DbgVerifyStaticResourceBindings(); #endif @@ -73,13 +73,13 @@ public: private: DummyShaderVariable m_DummyShaderVar; ///< Dummy shader variable - + */ // ShaderResources class instance must be referenced through the shared pointer, because // it is referenced by ShaderResourceLayoutVk class instances - std::shared_ptr<const ShaderResourcesVk> m_pShaderResources; - ShaderResourceLayoutVk m_StaticResLayout; - ShaderResourceCacheVk m_ConstResCache; -*/ + std::shared_ptr<const SPIRVShaderResources> m_pShaderResources; + //ShaderResourceLayoutVk m_StaticResLayout; + //ShaderResourceCacheVk m_ConstResCache; + VulkanUtilities::ShaderModuleWrapper m_VkShaderModule; }; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index 507d3aea..73c97870 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -59,13 +59,13 @@ ShaderVkImpl::ShaderVkImpl(IReferenceCounters *pRefCounters, RenderDeviceVkImpl ShaderModuleCI.pCode = SPIRV.data(); m_VkShaderModule = LogicalDevice.CreateShaderModule(ShaderModuleCI, m_Desc.Name); -/* // Load shader resources auto &Allocator = GetRawAllocator(); - auto *pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", sizeof(ShaderResourcesVk)); - auto *pResources = new (pRawMem) ShaderResourcesVk(m_pShaderByteCode, m_Desc); - m_pShaderResources.reset(pResources, STDDeleterRawMem<ShaderResourcesVk>(Allocator)); + auto *pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", sizeof(SPIRVShaderResources)); + auto *pResources = new (pRawMem) SPIRVShaderResources(Allocator, m_Desc.ShaderType, std::move(SPIRV)); + m_pShaderResources.reset(pResources, STDDeleterRawMem<SPIRVShaderResources>(Allocator)); + /* // Clone only static resources that will be set directly in the shader // http://diligentgraphics.com/diligent-engine/architecture/Vk/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC}; |
