From 6e5be00eb6db740e5db88a49f5a158f74fd7eb47 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 26 Apr 2018 09:05:36 -0700 Subject: Working on SPIRV resource loading --- Graphics/GLSLTools/include/SPIRVShaderResources.h | 14 +- Graphics/GLSLTools/src/SPIRVShaderResources.cpp | 257 ++++++++++++++++++---- 2 files changed, 217 insertions(+), 54 deletions(-) (limited to 'Graphics/GLSLTools') 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 spirv_binary); - void Load(std::vector 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 spirv_binary) : m_MemoryBuffer(nullptr, STDDeleterRawMem(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(resources.uniform_buffers.size()), + static_cast(resources.storage_buffers.size()), + static_cast(resources.storage_images.size()), + static_cast(resources.sampled_images.size()), + static_cast(resources.atomic_counters.size()), + static_cast(resources.separate_images.size()), + static_cast(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(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(std::numeric_limits::max()); + VERIFY(UniformBufferOffset + NumUBs <= MaxOffset, "Max offset exceeded"); + m_StorageBufferOffset = UniformBufferOffset + static_cast(NumUBs); + + VERIFY(m_StorageBufferOffset + NumSBs <= MaxOffset, "Max offset exceeded"); + m_StorageImageOffset = m_StorageBufferOffset + static_cast(NumSBs); + + VERIFY(m_StorageImageOffset + NumImgs <= MaxOffset, "Max offset exceeded"); + m_SampledImageOffset = m_StorageImageOffset + static_cast(NumImgs); + + VERIFY(m_SampledImageOffset + NumSmplImgs <= MaxOffset, "Max offset exceeded"); + m_AtomicCounterOffset = m_SampledImageOffset + static_cast(NumSmplImgs); + + VERIFY(m_AtomicCounterOffset + NumACs <= MaxOffset, "Max offset exceeded"); + m_SeparateImageOffset = m_AtomicCounterOffset + static_cast(NumACs); + + VERIFY(m_SeparateImageOffset + NumSepImgs <= MaxOffset, "Max offset exceeded"); + m_SeparateSamplerOffset = m_SeparateImageOffset + static_cast(NumSepImgs); + + VERIFY(m_SeparateSamplerOffset + NumSepSmpls <= MaxOffset, "Max offset exceeded"); + m_BufferEndOffset = m_SeparateSamplerOffset + static_cast(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 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) - { - - } -} - } -- cgit v1.2.3