From b1bac52d792f348c8a5be7d85bae070d2322479d Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 25 Oct 2018 08:44:11 -0700 Subject: Some improvements D3D shader resource management --- .../include/ShaderResourceLayoutD3D11.h | 153 ++++------ .../src/ShaderResourceLayoutD3D11.cpp | 338 ++++++++++++--------- 2 files changed, 258 insertions(+), 233 deletions(-) (limited to 'Graphics/GraphicsEngineD3D11') diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h index 937a992d..3a5bbbe2 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h @@ -211,13 +211,28 @@ public: Uint32 GetVariableIndex(const ShaderVariableD3D11Base& Variable)const; Uint32 GetTotalResourceCount()const { - auto ResourceCount = m_NumCBs + m_NumTexSRVs + m_NumTexUAVs + m_NumBufUAVs + m_NumBufSRVs; + auto ResourceCount = GetNumCBs() + GetNumTexSRVs() + GetNumTexUAVs() + GetNumBufUAVs() + GetNumBufSRVs(); // Do not expose sampler variables when using combined texture samplers if (!m_pResources->IsUsingCombinedTextureSamplers()) - ResourceCount += m_NumSamplers; + ResourceCount += GetNumSamplers(); return ResourceCount; } + Uint32 GetNumCBs() const { return (m_TexSRVsOffset - 0 ) / sizeof(ConstBuffBindInfo);} + Uint32 GetNumTexSRVs() const { return (m_TexUAVsOffset - m_TexSRVsOffset ) / sizeof(TexSRVBindInfo); } + Uint32 GetNumTexUAVs() const { return (m_BuffSRVsOffset - m_TexUAVsOffset ) / sizeof(TexUAVBindInfo) ; } + Uint32 GetNumBufSRVs() const { return (m_BuffUAVsOffset - m_BuffSRVsOffset) / sizeof(BuffSRVBindInfo); } + Uint32 GetNumBufUAVs() const { return (m_SamplerOffset - m_BuffUAVsOffset) / sizeof(BuffUAVBindInfo); } + Uint32 GetNumSamplers() const { return (m_MemorySize - m_SamplerOffset ) / sizeof(SamplerBindInfo); } + + template Uint32 GetNumResources()const; + template<> Uint32 GetNumResources() const { return GetNumCBs(); } + template<> Uint32 GetNumResources () const { return GetNumTexSRVs(); } + template<> Uint32 GetNumResources () const { return GetNumTexUAVs(); } + template<> Uint32 GetNumResources () const { return GetNumBufSRVs(); } + template<> Uint32 GetNumResources () const { return GetNumBufUAVs(); } + template<> Uint32 GetNumResources () const { return GetNumSamplers(); } + private: const Char* GetShaderName()const @@ -232,84 +247,40 @@ private: std::unique_ptr > m_ResourceBuffer; // Offsets in bytes - Uint16 m_TexSRVsOffset = 0; - Uint16 m_TexUAVsOffset = 0; - Uint16 m_BuffUAVsOffset = 0; - Uint16 m_BuffSRVsOffset = 0; - Uint16 m_SamplerOffset = 0; + using OffsetType = Uint16; + OffsetType m_TexSRVsOffset = 0; + OffsetType m_TexUAVsOffset = 0; + OffsetType m_BuffSRVsOffset = 0; + OffsetType m_BuffUAVsOffset = 0; + OffsetType m_SamplerOffset = 0; + OffsetType m_MemorySize = 0; - Uint8 m_NumCBs = 0; // Max == 14 - Uint8 m_NumTexSRVs = 0; // Max == 128 - Uint8 m_NumTexUAVs = 0; // Max == 8 - Uint8 m_NumBufUAVs = 0; // Max == 8 - Uint8 m_NumBufSRVs = 0; // Max == 128 - Uint8 m_NumSamplers = 0; // Max == 16 - - ConstBuffBindInfo& GetCB(Uint32 cb) - { - VERIFY_EXPR(cb(m_ResourceBuffer.get())[cb]; - } - const ConstBuffBindInfo& GetCB(Uint32 cb)const - { - VERIFY_EXPR(cb(m_ResourceBuffer.get())[cb]; - } - - TexSRVBindInfo& GetTexSRV(Uint32 t) - { - VERIFY_EXPR(t( reinterpret_cast(m_ResourceBuffer.get()) + m_TexSRVsOffset)[t]; - } - const TexSRVBindInfo& GetTexSRV(Uint32 t)const - { - VERIFY_EXPR(t( reinterpret_cast(m_ResourceBuffer.get()) + m_TexSRVsOffset)[t]; - } - - TexUAVBindInfo& GetTexUAV(Uint32 u) - { - VERIFY_EXPR(u < m_NumTexUAVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_TexUAVsOffset)[u]; - } - const TexUAVBindInfo& GetTexUAV(Uint32 u)const - { - VERIFY_EXPR(u < m_NumTexUAVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_TexUAVsOffset)[u]; - } - - BuffUAVBindInfo& GetBufUAV(Uint32 u) - { - VERIFY_EXPR(u < m_NumBufUAVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_BuffUAVsOffset)[u]; - } - const BuffUAVBindInfo& GetBufUAV(Uint32 u)const - { - VERIFY_EXPR(u < m_NumBufUAVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_BuffUAVsOffset)[u]; - } - - BuffSRVBindInfo& GetBufSRV(Uint32 s) - { - VERIFY_EXPR(s < m_NumBufSRVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_BuffSRVsOffset)[s]; - } - const BuffSRVBindInfo& GetBufSRV(Uint32 s)const - { - VERIFY_EXPR(s < m_NumBufSRVs); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_BuffSRVsOffset)[s]; - } - - SamplerBindInfo& GetSampler(Uint32 s) + template OffsetType GetResourceOffset()const; + template<> OffsetType GetResourceOffset() const { return 0; } + template<> OffsetType GetResourceOffset () const { return m_TexSRVsOffset; } + template<> OffsetType GetResourceOffset () const { return m_TexUAVsOffset; } + template<> OffsetType GetResourceOffset () const { return m_BuffSRVsOffset; } + template<> OffsetType GetResourceOffset () const { return m_BuffUAVsOffset; } + template<> OffsetType GetResourceOffset () const { return m_SamplerOffset; } + + template + ResourceType& GetResource(Uint32 ResIndex) { - VERIFY_EXPR(s < m_NumSamplers); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_SamplerOffset)[s]; + VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources(), ")"); + auto Offset = GetResourceOffset(); + return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + Offset)[ResIndex]; } - const SamplerBindInfo& GetSampler(Uint32 s)const + + template + const ResourceType& GetConstResource(Uint32 ResIndex)const { - VERIFY_EXPR(s < m_NumSamplers); - return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + m_SamplerOffset)[s]; + VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources(), ")"); + auto Offset = GetResourceOffset(); + return reinterpret_cast( reinterpret_cast(m_ResourceBuffer.get()) + Offset)[ResIndex]; } + + template + IShaderVariable* GetResourceByName( const Char* Name ); template(); ++cb) + HandleCB(GetResource(cb)); + + for (Uint32 t = 0; t < GetNumResources(); ++t) + HandleTexSRV(GetResource(t)); + + for (Uint32 u = 0; u < GetNumResources(); ++u) + HandleTexUAV(GetResource(u)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleBufSRV(GetResource(s)); + + for (Uint32 u = 0; u < GetNumResources(); ++u) + HandleBufUAV(GetResource(u)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleSampler(GetResource(s)); } std::shared_ptr m_pResources; IObject& m_Owner; + + friend class ShaderVariableIndexLocator; + friend class ShaderVariableLocator; }; } diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp index 1a175e38..d0e5f982 100755 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp @@ -81,14 +81,13 @@ size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D const SHADER_VARIABLE_TYPE* VarTypes, Uint32 NumVarTypes) { - Uint32 NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers; - SrcResources.CountResources(VarTypes, NumVarTypes, NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); - auto MemSize = NumCBs * sizeof(ConstBuffBindInfo) + - NumTexSRVs * sizeof(TexSRVBindInfo) + - NumTexUAVs * sizeof(TexUAVBindInfo) + - NumBufUAVs * sizeof(BuffUAVBindInfo) + - NumBufSRVs * sizeof(BuffSRVBindInfo) + - NumSamplers * sizeof(SamplerBindInfo); + auto ResCounters = SrcResources.CountResources(VarTypes, NumVarTypes); + auto MemSize = ResCounters.NumCBs * sizeof(ConstBuffBindInfo) + + ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) + + ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) + + ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) + + ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) + + ResCounters.NumSamplers * sizeof(SamplerBindInfo); return MemSize; } @@ -107,37 +106,41 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptrCountResources(VarTypes, NumVarTypes, NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers); + auto ResCounters = m_pResources->CountResources(VarTypes, NumVarTypes); // Initialize offsets - m_TexSRVsOffset = 0 + static_cast( NumCBs * sizeof(ConstBuffBindInfo)); - m_TexUAVsOffset = m_TexSRVsOffset + static_cast( NumTexSRVs * sizeof(TexSRVBindInfo) ); - m_BuffUAVsOffset = m_TexUAVsOffset + static_cast( NumTexUAVs * sizeof(TexUAVBindInfo) ); - m_BuffSRVsOffset = m_BuffUAVsOffset + static_cast( NumBufUAVs * sizeof(BuffUAVBindInfo) ); - m_SamplerOffset = m_BuffSRVsOffset + static_cast( NumBufSRVs * sizeof(BuffSRVBindInfo) ); - auto MemorySize = m_SamplerOffset + NumSamplers * sizeof(SamplerBindInfo) ; - - VERIFY_EXPR(MemorySize == GetRequiredMemorySize(*m_pResources, VarTypes, NumVarTypes)); - - if( MemorySize ) + size_t CurrentOffset = 0; + auto AdvanceOffset = [&CurrentOffset](size_t NumResources) + { + constexpr size_t MaxOffset = std::numeric_limits::max(); + VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")"); + auto Offset = static_cast(CurrentOffset); + CurrentOffset += NumResources; + return Offset; + }; + + auto CBOffset = AdvanceOffset(ResCounters.NumCBs * sizeof(ConstBuffBindInfo)); CBOffset; // To suppress warning + m_TexSRVsOffset = AdvanceOffset(ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) ); + m_TexUAVsOffset = AdvanceOffset(ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) ); + m_BuffSRVsOffset = AdvanceOffset(ResCounters.NumBufSRVs * sizeof(BuffSRVBindInfo) ); + m_BuffUAVsOffset = AdvanceOffset(ResCounters.NumBufUAVs * sizeof(BuffUAVBindInfo) ); + m_SamplerOffset = AdvanceOffset(ResCounters.NumSamplers * sizeof(SamplerBindInfo) ); + m_MemorySize = AdvanceOffset(0); + + VERIFY_EXPR(m_MemorySize == GetRequiredMemorySize(*m_pResources, VarTypes, NumVarTypes)); + + if (m_MemorySize) { - auto *pRawMem = ALLOCATE(ResLayoutDataAllocator, "Raw memory buffer for shader resource layout resources", MemorySize); + auto *pRawMem = ALLOCATE(ResLayoutDataAllocator, "Raw memory buffer for shader resource layout resources", m_MemorySize); m_ResourceBuffer = std::unique_ptr >(pRawMem, ResLayoutDataAllocator); } - VERIFY_EXPR(NumCBs < 255); - VERIFY_EXPR(NumTexSRVs < 255); - VERIFY_EXPR(NumTexUAVs < 255); - VERIFY_EXPR(NumBufSRVs < 255); - VERIFY_EXPR(NumBufUAVs < 255); - VERIFY_EXPR(NumSamplers< 255); - m_NumCBs = static_cast(NumCBs); - m_NumTexSRVs = static_cast(NumTexSRVs); - m_NumTexUAVs = static_cast(NumTexUAVs); - m_NumBufSRVs = static_cast(NumBufSRVs); - m_NumBufUAVs = static_cast(NumBufUAVs); - m_NumSamplers = static_cast(NumSamplers); + VERIFY_EXPR(ResCounters.NumCBs == GetNumCBs() ); + VERIFY_EXPR(ResCounters.NumTexSRVs == GetNumTexSRVs() ); + VERIFY_EXPR(ResCounters.NumTexUAVs == GetNumTexUAVs() ); + VERIFY_EXPR(ResCounters.NumBufSRVs == GetNumBufSRVs() ); + VERIFY_EXPR(ResCounters.NumBufUAVs == GetNumBufUAVs() ); + VERIFY_EXPR(ResCounters.NumSamplers== GetNumSamplers()); // Current resource index for every resource type Uint32 cb = 0; @@ -159,7 +162,7 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(cb++)) ConstBuffBindInfo( CB, *this ); NumCBSlots = std::max(NumCBSlots, Uint32{CB.BindPoint} + Uint32{CB.BindCount}); }, @@ -171,7 +174,7 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(sam++)) SamplerBindInfo( Sampler, *this ); NumSamplerSlots = std::max(NumSamplerSlots, Uint32{Sampler.BindPoint} + Uint32{Sampler.BindCount}); } }, @@ -179,7 +182,8 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(AssignedSamplerIndex); if (strcmp(Sampler.Attribs.Name, AssignedSamplerAttribs.Name) == 0) break; } - VERIFY(AssignedSamplerIndex < m_NumSamplers, "Unable to find assigned sampler"); + VERIFY(AssignedSamplerIndex < NumSamplers, "Unable to find assigned sampler"); } } // Initialize tex SRV in place, increment counter of tex SRVs - new (&GetTexSRV(texSrv++)) TexSRVBindInfo( TexSRV, AssignedSamplerIndex, *this ); + new (&GetResource(texSrv++)) TexSRVBindInfo( TexSRV, AssignedSamplerIndex, *this ); NumSRVSlots = std::max(NumSRVSlots, Uint32{TexSRV.BindPoint} + Uint32{TexSRV.BindCount}); }, @@ -212,7 +216,7 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(texUav++)) TexUAVBindInfo( TexUAV, *this ); NumUAVSlots = std::max(NumUAVSlots, Uint32{TexUAV.BindPoint} + Uint32{TexUAV.BindCount}); }, @@ -221,7 +225,7 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(bufSrv++)) BuffSRVBindInfo( BuffSRV, *this ); NumSRVSlots = std::max(NumSRVSlots, Uint32{BuffSRV.BindPoint} + Uint32{BuffSRV.BindCount}); }, @@ -230,17 +234,17 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr(bufUav++)) BuffUAVBindInfo( BuffUAV, *this ); NumUAVSlots = std::max(NumUAVSlots, Uint32{BuffUAV.BindPoint} + Uint32{BuffUAV.BindCount}); } ); - VERIFY(cb == m_NumCBs, "Not all CBs are initialized which will cause a crash when dtor is called"); - VERIFY(texSrv == m_NumTexSRVs, "Not all Tex SRVs are initialized which will cause a crash when dtor is called"); - VERIFY(texUav == m_NumTexUAVs, "Not all Tex UAVs are initialized which will cause a crash when dtor is called"); - VERIFY(bufSrv == m_NumBufSRVs, "Not all Buf SRVs are initialized which will cause a crash when dtor is called"); - VERIFY(bufUav == m_NumBufUAVs, "Not all Buf UAVs are initialized which will cause a crash when dtor is called"); - VERIFY(sam == m_NumSamplers, "Not all samplers are initialized which will cause a crash when dtor is called"); + VERIFY(cb == GetNumCBs(), "Not all CBs are initialized which will cause a crash when dtor is called"); + VERIFY(texSrv == GetNumTexSRVs(), "Not all Tex SRVs are initialized which will cause a crash when dtor is called"); + VERIFY(texUav == GetNumTexUAVs(), "Not all Tex UAVs are initialized which will cause a crash when dtor is called"); + VERIFY(bufSrv == GetNumBufSRVs(), "Not all Buf SRVs are initialized which will cause a crash when dtor is called"); + VERIFY(bufUav == GetNumBufUAVs(), "Not all Buf UAVs are initialized which will cause a crash when dtor is called"); + VERIFY(sam == GetNumSamplers(), "Not all samplers are initialized which will cause a crash when dtor is called"); // Shader resource cache in the SRB is initialized by the constructor of ShaderResourceBindingD3D11Impl to // hold all variable types. The corresponding layout in the SRB is initialized to keep mutable and dynamic @@ -467,7 +471,7 @@ void ShaderResourceLayoutD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pVie if (ValidSamplerAssigned()) { - auto& Sampler = m_ParentResLayout.GetSampler(SamplerIndex); + auto& Sampler = m_ParentResLayout.GetResource(SamplerIndex); VERIFY(!Sampler.Attribs.IsStaticSampler(), "Static samplers are not assigned to texture SRVs as they are initialized directly in the shader resource cache"); VERIFY_EXPR(Sampler.Attribs.BindCount == Attribs.BindCount || Sampler.Attribs.BindCount == 1); auto SamplerBindPoint = Sampler.Attribs.BindPoint + (Sampler.Attribs.BindCount != 1 ? ArrayIndex : 0); @@ -771,34 +775,87 @@ void ShaderResourceLayoutD3D11::BindResources( IResourceMapping* pResourceMappin ); } +template +IShaderVariable* ShaderResourceLayoutD3D11::GetResourceByName( const Char* Name ) +{ + auto NumResources = GetNumResources(); + for (Uint32 res = 0; res < NumResources; ++res) + { + auto& Resource = GetResource(res); + if (strcmp(Resource.Attribs.Name, Name) == 0) + return &Resource; + } + + return nullptr; +} + IShaderVariable* ShaderResourceLayoutD3D11::GetShaderVariable(const Char* Name) { - for (Uint32 cb = 0; cb < m_NumCBs; ++cb) - if (strcmp(GetCB(cb).Attribs.Name, Name) == 0) - return &GetCB(cb); - for (Uint32 t = 0; t < m_NumTexSRVs; ++t) - if (strcmp(GetTexSRV(t).Attribs.Name, Name) == 0 ) - return &GetTexSRV(t); - for (Uint32 u = 0; u < m_NumTexUAVs; ++u) - if (strcmp(GetTexUAV(u).Attribs.Name, Name) == 0 ) - return &GetTexUAV(u); - for (Uint32 s = 0; s < m_NumBufSRVs; ++s) - if (strcmp(GetBufSRV(s).Attribs.Name, Name) == 0 ) - return &GetBufSRV(s); - for (Uint32 u = 0; u < m_NumBufUAVs; ++u) - if (strcmp(GetBufUAV(u).Attribs.Name, Name) == 0 ) - return &GetBufUAV(u); - + if(auto* pCB = GetResourceByName(Name)) + return pCB; + + if(auto* pTexSRV = GetResourceByName(Name)) + return pTexSRV; + + if(auto* pTexUAV = GetResourceByName(Name)) + return pTexUAV; + + if(auto* pBuffSRV = GetResourceByName(Name)) + return pBuffSRV; + + if(auto* pBuffUAV = GetResourceByName(Name)) + return pBuffUAV; + if (!m_pResources->IsUsingCombinedTextureSamplers()) { - for (Uint32 s = 0; s < m_NumSamplers; ++s) - if (strcmp(GetSampler(s).Attribs.Name, Name) == 0 ) - return &GetSampler(s); + if(auto* pSampler = GetResourceByName(Name)) + return pSampler; } return nullptr; } +class ShaderVariableIndexLocator +{ +public: + ShaderVariableIndexLocator(const ShaderResourceLayoutD3D11& _Layout, const ShaderResourceLayoutD3D11::ShaderVariableD3D11Base& Variable) : + Layout (_Layout), + VarOffset(reinterpret_cast(&Variable) - reinterpret_cast(_Layout.m_ResourceBuffer.get())) + {} + + template + bool TryResource(ShaderResourceLayoutD3D11::OffsetType NextResourceTypeOffset) + { +#ifdef _DEBUG + VERIFY(Layout.GetResourceOffset() >= dbgPreviousResourceOffset, "Resource types are processed out of order!"); + dbgPreviousResourceOffset = Layout.GetResourceOffset(); + VERIFY_EXPR(NextResourceTypeOffset >= Layout.GetResourceOffset()); +#endif + if (VarOffset < NextResourceTypeOffset) + { + auto RelativeOffset = VarOffset - Layout.GetResourceOffset(); + DEV_CHECK_ERR( RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")"); + Index += static_cast(RelativeOffset / sizeof(ResourceType)); + return true; + } + else + { + Index += Layout.GetNumResources(); + return false; + } + } + + Uint32 GetIndex() const {return Index;} + +private: + const ShaderResourceLayoutD3D11& Layout; + const size_t VarOffset; + Uint32 Index = 0; +#ifdef _DEBUG + Uint32 dbgPreviousResourceOffset = 0; +#endif +}; + Uint32 ShaderResourceLayoutD3D11::GetVariableIndex(const ShaderVariableD3D11Base& Variable)const { if (!m_ResourceBuffer) @@ -806,105 +863,94 @@ Uint32 ShaderResourceLayoutD3D11::GetVariableIndex(const ShaderVariableD3D11Base LOG_ERROR("This shader resource layout does not have resources"); return static_cast(-1); } + + ShaderVariableIndexLocator IdxLocator(*this, Variable); + if (IdxLocator.TryResource(m_TexSRVsOffset)) + return IdxLocator.GetIndex(); - auto Offset = reinterpret_cast(&Variable) - reinterpret_cast(m_ResourceBuffer.get()); - Uint32 Index = 0; - if (Offset < m_TexSRVsOffset) - { - DEV_CHECK_ERR(Offset % sizeof(ConstBuffBindInfo) == 0, "Offset is not multiple of sizeof(ConstBuffBindInfo)"); - return Index + static_cast(Offset / sizeof(ConstBuffBindInfo)); - } - else - Index += m_NumCBs; + if (IdxLocator.TryResource(m_TexUAVsOffset)) + return IdxLocator.GetIndex(); - if (Offset < m_TexUAVsOffset) - { - DEV_CHECK_ERR( (Offset - m_TexSRVsOffset) % sizeof(TexSRVBindInfo) == 0, "Offset is not multiple of sizeof(TexSRVBindInfo)"); - return Index + static_cast((Offset - m_TexSRVsOffset) / sizeof(TexSRVBindInfo)); - } - else - Index += m_NumTexSRVs; + if (IdxLocator.TryResource(m_BuffSRVsOffset)) + return IdxLocator.GetIndex(); - if (Offset < m_BuffUAVsOffset) - { - DEV_CHECK_ERR( (Offset - m_TexUAVsOffset) % sizeof(TexUAVBindInfo) == 0, "Offset is not multiple of sizeof(TexUAVBindInfo)"); - return Index + static_cast((Offset - m_TexUAVsOffset) / sizeof(TexUAVBindInfo)); - } - else - Index += m_NumTexUAVs; + if (IdxLocator.TryResource(m_BuffUAVsOffset)) + return IdxLocator.GetIndex(); - if (Offset < m_BuffSRVsOffset) - { - DEV_CHECK_ERR( (Offset - m_BuffUAVsOffset) % sizeof(BuffUAVBindInfo) == 0, "Offset is not multiple of sizeof(BuffUAVBindInfo)" ); - return Index + static_cast((Offset - m_BuffUAVsOffset) / sizeof(BuffUAVBindInfo)); - } - else - Index += m_NumBufUAVs; + if (IdxLocator.TryResource(m_SamplerOffset)) + return IdxLocator.GetIndex(); - if (Offset < static_cast(m_BuffSRVsOffset + m_NumBufSRVs * sizeof(BuffSRVBindInfo))) + if (!m_pResources->IsUsingCombinedTextureSamplers()) { - DEV_CHECK_ERR( (Offset - m_BuffSRVsOffset) % sizeof(BuffSRVBindInfo) == 0, "Offset is not multiple of sizeof(BuffSRVBindInfo)" ); - return Index + static_cast((Offset - m_BuffSRVsOffset) / sizeof(BuffSRVBindInfo)); + if (IdxLocator.TryResource(m_MemorySize)) + return IdxLocator.GetIndex(); } - else - Index += m_NumBufSRVs; - if (!m_pResources->IsUsingCombinedTextureSamplers() && - Offset < static_cast(m_SamplerOffset + m_NumSamplers * sizeof(SamplerBindInfo))) + LOG_ERROR("Failed to get variable index. The variable ", &Variable, " does not belong to this shader resource layout"); + return static_cast(-1); +} + +class ShaderVariableLocator +{ +public: + ShaderVariableLocator(ShaderResourceLayoutD3D11& _Layout, Uint32 _Index) : + Layout(_Layout), + Index (_Index) { - DEV_CHECK_ERR( (Offset - m_SamplerOffset) % sizeof(SamplerBindInfo) == 0, "Offset is not multiple of sizeof(SamplerBindInfo)" ); - return Index + static_cast((Offset - m_SamplerOffset) / sizeof(SamplerBindInfo)); } - else + + template + IShaderVariable* TryResource() { - LOG_ERROR("Failed to get variable index. The variable ", &Variable, " does not belong to this shader resource layout"); - return static_cast(-1); +#ifdef _DEBUG + VERIFY(Layout.GetResourceOffset() >= dbgPreviousResourceOffset, "Resource types are processed out of order!"); + dbgPreviousResourceOffset = Layout.GetResourceOffset(); +#endif + auto NumResources = Layout.GetNumResources(); + if (Index < NumResources) + return &Layout.GetResource(Index); + else + { + Index -= NumResources; + return nullptr; + } } -} + +private: + ShaderResourceLayoutD3D11& Layout; + Uint32 Index; +#ifdef _DEBUG + Uint32 dbgPreviousResourceOffset = 0; +#endif +}; IShaderVariable* ShaderResourceLayoutD3D11::GetShaderVariable( Uint32 Index ) { - if (Index >= GetTotalResourceCount()) - { - LOG_ERROR("Invalid resource index ", Index); - return nullptr; - } + ShaderVariableLocator VarLocator(*this, Index); - if (Index < m_NumCBs) - return &GetCB(Index); - else - Index -= m_NumCBs; + if(auto* pCB = VarLocator.TryResource()) + return pCB; - if (Index < m_NumTexSRVs) - return &GetTexSRV(Index); - else - Index -= m_NumTexSRVs; - - if (Index < m_NumTexUAVs) - return &GetTexUAV(Index); - else - Index -= m_NumTexUAVs; + if(auto* pTexSRV = VarLocator.TryResource()) + return pTexSRV; - if (Index < m_NumBufUAVs) - return &GetBufUAV(Index); - else - Index -= m_NumBufUAVs; + if(auto* pTexUAV = VarLocator.TryResource()) + return pTexUAV; + + if(auto* pBuffSRV = VarLocator.TryResource()) + return pBuffSRV; + + if(auto* pBuffUAV = VarLocator.TryResource()) + return pBuffUAV; - if (Index < m_NumBufSRVs) - return &GetBufSRV(Index); - else - Index -= m_NumBufSRVs; - if (!m_pResources->IsUsingCombinedTextureSamplers()) { - if (Index < m_NumSamplers) - return &GetSampler(Index); - else - Index -= m_NumSamplers; + if(auto* pSampler = VarLocator.TryResource()) + return pSampler; } - + auto TotalResCount = GetTotalResourceCount(); - LOG_ERROR(Index + TotalResCount, " is not a valid variable index. Maximum allowed index: ", TotalResCount); + LOG_ERROR(Index, " is not a valid variable index. Total resource count: ", TotalResCount); return nullptr; } @@ -944,7 +990,7 @@ do{ \ if (ts.ValidSamplerAssigned()) { - const auto& Sampler = GetSampler(ts.SamplerIndex); + const auto& Sampler = GetConstResource(ts.SamplerIndex); VERIFY_EXPR(Sampler.Attribs.BindCount == ts.Attribs.BindCount || Sampler.Attribs.BindCount == 1); // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent -- cgit v1.2.3