From 2808b9f671e29e27a4d04f6c8ea21c40d8c573eb Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 3 Mar 2019 18:09:24 -0800 Subject: Almost completed refactoring d3d11 backend to comply with the new API --- Graphics/GraphicsEngine/interface/Shader.h | 2 +- .../include/PipelineStateD3D11Impl.h | 10 + .../GraphicsEngineD3D11/include/ShaderD3D11Impl.h | 16 +- .../include/ShaderResourceBindingD3D11Impl.h | 16 +- .../include/ShaderResourceCacheD3D11.h | 4 +- .../include/ShaderResourceLayoutD3D11.h | 105 +++++--- .../include/ShaderResourcesD3D11.h | 21 +- .../src/DeviceContextD3D11Impl.cpp | 27 +- .../src/PipelineStateD3D11Impl.cpp | 109 +++++++- .../src/RenderDeviceD3D11Impl.cpp | 6 +- .../GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp | 9 +- .../src/ShaderResourceBindingD3D11Impl.cpp | 56 ++-- .../src/ShaderResourceLayoutD3D11.cpp | 292 +++++++++++---------- .../src/ShaderResourcesD3D11.cpp | 3 +- .../include/ShaderResources.h | 99 ++++--- .../GraphicsEngineD3DBase/src/ShaderResources.cpp | 230 +++++++++++----- 16 files changed, 649 insertions(+), 356 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index 2ac6a2c6..e877ce17 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -241,7 +241,7 @@ public: virtual Uint32 GetResourceCount()const = 0; /// Returns the pointer to the array of shader resources - virtual const ShaderResourceDesc* GetResources()const = 0; + virtual ShaderResourceDesc GetResource(Uint32 Index)const = 0; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h index 04e0edc0..583190aa 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h @@ -72,6 +72,14 @@ public: virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; + virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags)override final; + + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) override final; + SRBMemoryAllocator& GetSRBMemoryAllocator() { return m_SRBMemAllocator; @@ -102,6 +110,8 @@ private: // SRB memory allocator must be defined before the default shader res binding SRBMemoryAllocator m_SRBMemAllocator; + + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h index c5005c4e..35a50a08 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderD3D11Impl.h @@ -55,6 +55,16 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderD3D11, TShaderBase); + virtual Uint32 GetResourceCount()const override final + { + return m_pShaderResources->GetTotalResources(); + } + + virtual ShaderResourceDesc GetResource(Uint32 Index)const override final + { + return m_pShaderResources->GetShaderResourceDesc(Index); + } + virtual ID3D11DeviceChild* GetD3D11Shader()override final { return m_pShader; @@ -62,13 +72,15 @@ public: ID3DBlob* GetBytecode(){return m_pShaderByteCode;} - Uint32 GetShaderTypeIndex()const{return m_ShaderTypeIndex;} + const std::shared_ptr& GetD3D11Resources()const{return m_pShaderResources;} private: /// D3D11 shader CComPtr m_pShader; - Uint32 m_ShaderTypeIndex; // VS == 0, PS == 1, GS == 2, HS == 3, DS == 4, CS == 5 + // ShaderResources class instance must be referenced through the shared pointer, because + // it is referenced by ShaderResourceLayoutD3D11 class instances + std::shared_ptr m_pShaderResources; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h index 9f175f1d..b3274b21 100755 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h @@ -48,15 +48,15 @@ public: bool IsInternal); ~ShaderResourceBindingD3D11Impl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name)override final; virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; @@ -74,14 +74,14 @@ public: private: // The caches are indexed by the shader order in the PSO, not shader index - ShaderResourceCacheD3D11* m_pBoundResourceCaches = nullptr; - ShaderResourceLayoutD3D11* m_pResourceLayouts = nullptr; + ShaderResourceCacheD3D11* m_pBoundResourceCaches = nullptr; + ShaderResourceLayoutD3D11* m_pResourceLayouts = nullptr; - Int8 m_ShaderTypeIndex[6] = {}; + Int8 m_ShaderTypeIndex[6] = {}; // Resource layout index in m_ResourceLayouts[] array for every shader stage - Int8 m_ResourceLayoutIndex[6]; - Uint8 m_NumActiveShaders = 0; + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; + Uint8 m_NumActiveShaders = 0; bool m_bIsStaticResourcesBound = false; }; diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h index 02cde863..f25dff7c 100755 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.h @@ -117,8 +117,8 @@ public: static size_t GetRequriedMemorySize(const class ShaderResourcesD3D11& Resources); - void Initialize(const class ShaderResourcesD3D11& Resources, class IMemoryAllocator &MemAllocator); - void Initialize(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount, class IMemoryAllocator &MemAllocator); + void Initialize(const class ShaderResourcesD3D11& Resources, class IMemoryAllocator& MemAllocator); + void Initialize(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount, class IMemoryAllocator& MemAllocator); void Destroy(class IMemoryAllocator& MemAllocator); diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h index c6dd714b..6666777b 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.h @@ -41,10 +41,19 @@ class IMemoryAllocator; /// Diligent::ShaderResourceLayoutD3D11 class /// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout/ +// sizeof(ShaderResourceLayoutD3D11) == 64 (x64) class ShaderResourceLayoutD3D11 { public: - ShaderResourceLayoutD3D11(IObject& Owner); + ShaderResourceLayoutD3D11(IObject& Owner, + IRenderDevice* pRenderDevice, + std::shared_ptr pSrcResources, + const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes, + Uint32 NumVarTypes, + ShaderResourceCacheD3D11& ResourceCache, + IMemoryAllocator& ResCacheDataAllocator, + IMemoryAllocator& ResLayoutDataAllocator); ~ShaderResourceLayoutD3D11(); // No copies, only moves are allowed @@ -58,14 +67,7 @@ public: const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes); - void Initialize(std::shared_ptr pSrcResources, - const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes, - Uint32 NumVarTypes, - ShaderResourceCacheD3D11& ResourceCache, - IMemoryAllocator& ResCacheDataAllocator, - IMemoryAllocator& ResLayoutDataAllocator); - - void CopyResources(ShaderResourceCacheD3D11& DstCache); + void CopyResources(ShaderResourceCacheD3D11& DstCache)const; using ShaderVariableD3D11Base = ShaderVariableD3DBase; @@ -86,7 +88,7 @@ public: BindResource(ppObjects[elem], FirstElement+elem); } - __forceinline bool IsBound(Uint32 ArrayIndex); + __forceinline bool IsBound(Uint32 ArrayIndex)const; }; struct TexSRVBindInfo final : ShaderVariableD3D11Base @@ -184,8 +186,10 @@ public: { SamplerBindInfo( const D3DShaderResourceAttribs& ResourceAttribs, ShaderResourceLayoutD3D11& ParentResLayout, - SHADER_RESOURCE_VARIABLE_TYPE VariableType ) : - ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs, VariableType) + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + RefCntAutoPtr _pStaticSampler) : + ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs, VariableType), + pStaticSampler(std::move(_pStaticSampler)) {} // Non-virtual function @@ -199,17 +203,15 @@ public: } __forceinline bool IsBound(Uint32 ArrayIndex)const; - - bool IsStaticSampler()const - { - UNEXPECTED("Not implemented"); - return false; - } + + RefCntAutoPtr pStaticSampler; }; // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive // while Layout is alive void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11& dbgResourceCache ); + + void SetStaticSamplers(ShaderResourceCacheD3D11& ResourceCache)const; #ifdef DEVELOPMENT bool dvpVerifyBindings()const; @@ -246,28 +248,34 @@ public: template<> Uint32 GetNumResources () const { return GetNumBufUAVs(); } template<> Uint32 GetNumResources () const { return GetNumSamplers(); } -private: - const Char* GetShaderName()const { return m_pResources->GetShaderName(); } - // No need to use shared pointer, as the resource cache is either part of the same - // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object - ShaderResourceCacheD3D11* m_pResourceCache = nullptr; +private: + +/* 0 */ IObject& m_Owner; +/* 8 */ std::shared_ptr m_pResources; - std::unique_ptr > m_ResourceBuffer; + // No need to use shared pointer, as the resource cache is either part of the same + // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object +/*24*/ ShaderResourceCacheD3D11& m_ResourceCache; - // Offsets in bytes - 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; +/*32*/ std::unique_ptr > m_ResourceBuffer; + // Offsets in bytes + using OffsetType = Uint16; +/*48*/ OffsetType m_TexSRVsOffset = 0; +/*50*/ OffsetType m_TexUAVsOffset = 0; +/*52*/ OffsetType m_BuffSRVsOffset = 0; +/*54*/ OffsetType m_BuffUAVsOffset = 0; +/*56*/ OffsetType m_SamplerOffset = 0; +/*58*/ OffsetType m_MemorySize = 0; +/*60 - 64*/ +/*64*/ // End of data + + template OffsetType GetResourceOffset()const; template<> OffsetType GetResourceOffset() const { return 0; } template<> OffsetType GetResourceOffset () const { return m_TexSRVsOffset; } @@ -327,8 +335,37 @@ private: HandleSampler(GetResource(s)); } - std::shared_ptr m_pResources; - IObject& m_Owner; + template + void HandleConstResources(THandleCB HandleCB, + THandleTexSRV HandleTexSRV, + THandleTexUAV HandleTexUAV, + THandleBufSRV HandleBufSRV, + THandleBufUAV HandleBufUAV, + THandleSampler HandleSampler)const + { + for (Uint32 cb = 0; cb < GetNumResources(); ++cb) + HandleCB(GetConstResource(cb)); + + for (Uint32 t = 0; t < GetNumResources(); ++t) + HandleTexSRV(GetConstResource(t)); + + for (Uint32 u = 0; u < GetNumResources(); ++u) + HandleTexUAV(GetConstResource(u)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleBufSRV(GetConstResource(s)); + + for (Uint32 u = 0; u < GetNumResources(); ++u) + HandleBufUAV(GetConstResource(u)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleSampler(GetConstResource(s)); + } friend class ShaderVariableIndexLocator; friend class ShaderVariableLocator; diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h index a241b486..c2c3a34d 100644 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourcesD3D11.h @@ -28,7 +28,7 @@ // ShaderResourcesD3D11 are created by ShaderD3D11Impl instances. They are then referenced by ShaderResourceLayoutD3D11 objects, which are in turn -// created by instances of ShaderResourceBindingsD3D11Impl (and ShaderD3D11Impl too) +// created by instances of ShaderResourceBindingsD3D11Impl and PipelineStateD3D11Impl // // _________________ // | | @@ -64,13 +64,17 @@ // | | shared_ptr | | shared_ptr| | | | | // | ShaderD3D11Impl |--------------->| ShaderResourcesD3D11 |<---------------| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl | // |_________________| |______________________| | |___________________________| |________________________________| -// | A | -// V | | -// ________ | | _______ ________________________________ +// A | +// | | +// __________ | | _______ ________________________________ // | | shared_ptr | | | | | | // | ShaderResourceLayoutD3D11 |------------------- ----| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl | // |___________________________| |___________________________| |________________________________| -// +// A +// ___________|______________ +// | | +// | PipelineStateD3D11Impl | +// |__________________________| // #include @@ -111,8 +115,7 @@ public: class ShaderResourceCacheD3D11& ResourceCache)const; #endif - const Char* GetShaderName() const { return m_ShaderName; } - + private: using MaxBindPointType = Int8; @@ -126,10 +129,6 @@ private: static_assert(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max SRV slot"); static_assert(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max Sampler slot"); static_assert(D3D11_PS_CS_UAV_REGISTER_COUNT-1 <= MaxAllowedBindPoint, "Not enough bits to represent max UAV slot"); - - // ShaderResourcesD3D11 is part of the ShaderD3D11Impl object, so we can simply - // reference shader name without the need to copy it - const Char* const m_ShaderName; }; } diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 0c205533..f531ab9a 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -151,19 +151,16 @@ namespace Diligent VERIFY_EXPR(pPSO != nullptr); static_assert(TransitionResources || CommitResources, "At least one of TransitionResources or CommitResources flags is expected to be true"); -#ifdef DEVELOPMENT - auto pdbgPipelineStateD3D11 = ValidatedCast( pPSO ); - auto ppdbgShaders = pdbgPipelineStateD3D11->GetShaders(); -#endif + auto* pPipelineStateD3D11 = ValidatedCast(pPSO); if (pShaderResourceBinding == nullptr) { #ifdef DEVELOPMENT bool ResourcesPresent = false; - for (Uint32 s = 0; s < pdbgPipelineStateD3D11->GetNumShaders(); ++s) + for (Uint32 s = 0; s < pPipelineStateD3D11->GetNumShaders(); ++s) { - auto* pShaderD3D11 = ValidatedCast(ppdbgShaders[s]); - if (pShaderD3D11->GetResources()->GetTotalResources() > 0) + auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s); + if (pShaderD3D11->GetD3D11Resources()->GetTotalResources() > 0) ResourcesPresent = true; } @@ -179,7 +176,7 @@ namespace Diligent auto pShaderResBindingD3D11 = ValidatedCast(pShaderResourceBinding); #ifdef DEVELOPMENT - if (pdbgPipelineStateD3D11->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState())) + if (pPipelineStateD3D11->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState())) { LOG_ERROR_MESSAGE("Shader resource binding does not match Pipeline State"); return; @@ -187,16 +184,14 @@ namespace Diligent #endif auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders(); - VERIFY(NumShaders == pdbgPipelineStateD3D11->GetNumShaders(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); + VERIFY(NumShaders == pPipelineStateD3D11->GetNumShaders(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); #ifdef DEVELOPMENT bool StaticResourcesPresent = false; for (Uint32 s = 0; s < NumShaders; ++s) { - pShaderResBindingD3D11->GetResourceLayout(s).dvpVerifyBindings(); - // Static resource bindings are verified in BindStaticShaderResources() - auto* pShaderD3D11 = ValidatedCast(ppdbgShaders[s]); - if (pShaderD3D11->GetStaticResourceLayout().GetTotalResourceCount() > 0) + const auto& StaticResLayout = pPipelineStateD3D11->GetStaticResourceLayout(s); + if (StaticResLayout.GetTotalResourceCount() > 0) StaticResourcesPresent = true; } // Static resource bindings are verified in BindStaticShaderResources() @@ -213,7 +208,7 @@ namespace Diligent auto ShaderTypeInd = pShaderResBindingD3D11->GetActiveShaderTypeIndex(s); #ifdef DEVELOPMENT - auto* pShaderD3D11 = ValidatedCast(ppdbgShaders[s]); + auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s); VERIFY_EXPR( ShaderTypeInd == static_cast(GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType)) ); #endif @@ -359,7 +354,7 @@ namespace Diligent auto ShaderTypeInd = pShaderResBindingD3D11->GetActiveShaderTypeIndex(s); #ifdef DEVELOPMENT - auto* pShaderD3D11 = ValidatedCast(ppdbgShaders[s]); + auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s); VERIFY_EXPR( ShaderTypeInd == static_cast(GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType)) ); #endif @@ -595,7 +590,7 @@ namespace Diligent if (CommitResources && (m_DebugFlags & (Uint32)EngineD3D11DebugFlags::VerifyCommittedShaderResources) != 0) { // Use full resource layout to verify that all required resources are committed - pShaderD3D11->GetResources()->dvpVerifyCommittedResources( + pShaderD3D11->GetD3D11Resources()->dvpVerifyCommittedResources( m_CommittedD3D11CBs[ShaderTypeInd], m_CommittedD3D11SRVs[ShaderTypeInd], m_CommittedD3D11SRVResources[ShaderTypeInd], diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp index 90828884..eec91b20 100644 --- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp @@ -27,6 +27,7 @@ #include "RenderDeviceD3D11Impl.h" #include "ShaderResourceBindingD3D11Impl.h" #include "EngineMemory.h" +#include "ShaderD3D11Impl.h" namespace Diligent { @@ -50,7 +51,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun { LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType), " provided"); } - m_ShaderResourceLayoutHash = pCS->GetResources()->GetHash(); + m_ShaderResourceLayoutHash = pCS->GetD3D11Resources()->GetHash(); } else { @@ -64,7 +65,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(ExpectedType), " shader is expeceted while ", GetShaderTypeLiteralName(m_p##ShortName->GetDesc().ShaderType)," provided" ); \ } \ if(pShader!=nullptr) \ - HashCombine(m_ShaderResourceLayoutHash, pShader->GetResources()->GetHash() ); \ + HashCombine(m_ShaderResourceLayoutHash, pShader->GetD3D11Resources()->GetHash() ); \ } INIT_SHADER(VS, SHADER_TYPE_VERTEX); @@ -110,19 +111,51 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun } } - if(PipelineDesc.SRBAllocationGranularity > 1) + auto* pStaticResLayoutRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", m_NumShaders * sizeof(ShaderResourceLayoutD3D11)); + m_pStaticResourceLayouts = reinterpret_cast(pStaticResLayoutRawMem); + + auto* pResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheD3D11", m_NumShaders * sizeof(ShaderResourceCacheD3D11)); + m_pStaticResourceCaches = reinterpret_cast(pResCacheRawMem); + + const auto& ResourceLayout = PipelineDesc.ResourceLayout; + std::array ShaderResLayoutDataSizes = {}; + std::array ShaderResCacheDataSizes = {}; + for (Uint32 s = 0; s < m_NumShaders; ++s) { - std::array ShaderResLayoutDataSizes = {}; - std::array ShaderResCacheDataSizes = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) + auto* pShader = GetShader(s); + const auto& ShaderResources = *pShader->GetD3D11Resources(); + + new (m_pStaticResourceCaches+s) ShaderResourceCacheD3D11; + // Do not initialize the cache as this will be performed by the resource layout + + // Shader resource layout will only contain dynamic and mutable variables + const SHADER_RESOURCE_VARIABLE_TYPE StaticVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; + new (m_pStaticResourceLayouts + s) + ShaderResourceLayoutD3D11 + { + *this, + pRenderDeviceD3D11, + pShader->GetD3D11Resources(), + m_Desc.ResourceLayout, + StaticVarTypes, + _countof(StaticVarTypes), + m_pStaticResourceCaches[s], + GetRawAllocator(), + GetRawAllocator() + }; + + m_pStaticResourceLayouts[s].SetStaticSamplers(m_pStaticResourceCaches[s]); + + if (PipelineDesc.SRBAllocationGranularity > 1) { - auto* pShader = GetShader(s); - const auto& ShaderResources = *pShader->GetResources(); - std::array AllowedVarTypes = { SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC }; - ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(ShaderResources, AllowedVarTypes.data(), static_cast(AllowedVarTypes.size())); + const SHADER_RESOURCE_VARIABLE_TYPE SRBVarTypes[] = { SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC }; + ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(ShaderResources, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes)); ShaderResCacheDataSizes[s] = ShaderResourceCacheD3D11::GetRequriedMemorySize(ShaderResources); } + } + if (PipelineDesc.SRBAllocationGranularity > 1) + { m_SRBMemAllocator.Initialize(PipelineDesc.SRBAllocationGranularity, m_NumShaders, ShaderResLayoutDataSizes.data(), m_NumShaders, ShaderResCacheDataSizes.data()); } } @@ -130,6 +163,18 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun PipelineStateD3D11Impl::~PipelineStateD3D11Impl() { + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + m_pStaticResourceCaches[s].Destroy(GetRawAllocator()); + m_pStaticResourceCaches[s].~ShaderResourceCacheD3D11(); + } + GetRawAllocator().Free(m_pStaticResourceCaches); + + for (Uint32 l = 0; l < m_NumShaders; ++l) + { + m_pStaticResourceLayouts[l].~ShaderResourceLayoutD3D11(); + } + GetRawAllocator().Free(m_pStaticResourceLayouts); } IMPLEMENT_QUERY_INTERFACE( PipelineStateD3D11Impl, IID_PipelineStateD3D11, TPipelineStateBase ) @@ -183,11 +228,11 @@ bool PipelineStateD3D11Impl::IsCompatibleWith(const IPipelineState* pPSO)const { auto* pShader0 = GetShader(s); auto* pShader1 = pPSOD3D11->GetShader(s); - if (pShader0->GetShaderTypeIndex() != pShader1->GetShaderTypeIndex()) + if (pShader0->GetDesc().ShaderType != pShader1->GetDesc().ShaderType) return false; - const ShaderResourcesD3D11* pRes0 = pShader0->GetResources().get(); - const ShaderResourcesD3D11* pRes1 = pShader1->GetResources().get(); - if (!pRes0->IsCompatibleWith(*pRes1)) + const auto& Res0 = *pShader0->GetD3D11Resources(); + const auto& Res1 = *pShader1->GetD3D11Resources(); + if (!Res0.IsCompatibleWith(Res1)) return false; } @@ -236,4 +281,40 @@ ID3D11ComputeShader* PipelineStateD3D11Impl::GetD3D11ComputeShader() return static_cast(pCSD3D11->GetD3D11Shader()); } + +void PipelineStateD3D11Impl::BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags) +{ + for (Uint32 s=0; s < m_NumShaders; ++s) + { + m_pStaticResourceLayouts[s].BindResources(pResourceMapping, Flags, m_pStaticResourceCaches[s]); + } +} + +Uint32 PipelineStateD3D11Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) const +{ + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) + return 0; + + return m_pStaticResourceLayouts[LayoutInd].GetTotalResourceCount(); +} + +IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) +{ + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) + return nullptr; + + return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Name); +} + +IShaderResourceVariable* PipelineStateD3D11Impl::GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) +{ + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) + return nullptr; + + return m_pStaticResourceLayouts[LayoutInd].GetShaderVariable(Index); +} + } diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp index 2d08f430..86eae24a 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -134,13 +134,13 @@ void RenderDeviceD3D11Impl :: CreateBuffer(const BufferDesc& BuffDesc, const Buf ); } -void RenderDeviceD3D11Impl :: CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader) +void RenderDeviceD3D11Impl :: CreateShader(const ShaderCreateInfo& ShaderCI, IShader** ppShader) { - CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + CreateDeviceObject( "shader", ShaderCI.Desc, ppShader, [&]() { ShaderD3D11Impl* pShaderD3D11( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderD3D11Impl instance", ShaderD3D11Impl) - (this, ShaderCreationAttribs ) ); + (this, ShaderCI) ); pShaderD3D11->QueryInterface( IID_Shader, reinterpret_cast(ppShader) ); OnCreateDeviceObject( pShaderD3D11 ); diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp index 3af91c50..677cd40c 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp @@ -34,8 +34,7 @@ ShaderD3D11Impl::ShaderD3D11Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D11Impl* pRenderDeviceD3D11, const ShaderCreateInfo& ShaderCI) : TShaderBase(pRefCounters, pRenderDeviceD3D11, ShaderCI.Desc), - ShaderD3DBase(ShaderCI), - m_ShaderTypeIndex(Diligent::GetShaderTypeIndex(ShaderCI.Desc.ShaderType)) + ShaderD3DBase(ShaderCI) { auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); switch (ShaderCI.Desc.ShaderType) @@ -74,6 +73,12 @@ ShaderD3D11Impl::ShaderD3D11Impl(IReferenceCounters* pRefCounters, DEV_CHECK_ERR(SUCCEEDED(hr), "Failed to set shader name"); } + // Load shader resources + auto& Allocator = GetRawAllocator(); + auto* pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", sizeof(ShaderResourcesD3D11)); + auto* pResources = new (pRawMem) ShaderResourcesD3D11(pRenderDeviceD3D11, m_pShaderByteCode, m_Desc, ShaderCI.UseCombinedTextureSamplers ? ShaderCI.CombinedSamplerSuffix : nullptr); + m_pShaderResources.reset(pResources, STDDeleterRawMem(Allocator)); + // Byte code is only required for the vertex shader to create input layout if( ShaderCI.Desc.ShaderType != SHADER_TYPE_VERTEX ) m_pShaderByteCode.Release(); diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp index 3cce0055..0091cc54 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp @@ -37,24 +37,22 @@ ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl( IReferenceCounte TBase( pRefCounters, pPSO, IsInternal ), m_bIsStaticResourcesBound(false) { - for(size_t s=0; s < _countof(m_ResourceLayoutIndex); ++s) - m_ResourceLayoutIndex[s] = -1; + m_NumActiveShaders = static_cast(pPSO->GetNumShaders()); - auto ppShaders = pPSO->GetShaders(); - m_NumActiveShaders = static_cast( pPSO->GetNumShaders() ); - - auto *pResLayoutRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", m_NumActiveShaders * sizeof(ShaderResourceLayoutD3D11)); + auto* pResLayoutRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D11", m_NumActiveShaders * sizeof(ShaderResourceLayoutD3D11)); m_pResourceLayouts = reinterpret_cast(pResLayoutRawMem); - auto *pResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheD3D11", m_NumActiveShaders * sizeof(ShaderResourceCacheD3D11)); + auto* pResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheD3D11", m_NumActiveShaders * sizeof(ShaderResourceCacheD3D11)); m_pBoundResourceCaches = reinterpret_cast(pResCacheRawMem); + + auto* pRenderDevice = pPSO->GetDevice(); + const auto& PSODesc = pPSO->GetDesc(); // Reserve memory for resource layouts for (Uint8 s = 0; s < m_NumActiveShaders; ++s) { - auto *pShaderD3D11 = ValidatedCast(ppShaders[s]); - auto ShaderInd = pShaderD3D11->GetShaderTypeIndex(); - VERIFY_EXPR(static_cast(ShaderInd) == GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType)); + auto* pShaderD3D11 = pPSO->GetShader(s); + auto ShaderInd = GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType); auto& SRBMemAllocator = pPSO->GetSRBMemoryAllocator(); auto& ResCacheDataAllocator = SRBMemAllocator.GetResourceCacheDataAllocator(s); @@ -62,17 +60,29 @@ ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl( IReferenceCounte // Initialize resource cache to have enough space to contain all shader resources, including static ones // Static resources are copied before resources are committed - const auto& Resources = *pShaderD3D11->GetResources(); + const auto& Resources = *pShaderD3D11->GetD3D11Resources(); new (m_pBoundResourceCaches+s) ShaderResourceCacheD3D11; m_pBoundResourceCaches[s].Initialize(Resources, ResCacheDataAllocator); // Shader resource layout will only contain dynamic and mutable variables // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache#Shader-Resource-Cache-Initialization - SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; - new (m_pResourceLayouts + s) ShaderResourceLayoutD3D11(*this); - m_pResourceLayouts[s].Initialize(pShaderD3D11->GetResources(), VarTypes, _countof(VarTypes), m_pBoundResourceCaches[s], ResCacheDataAllocator, ResLayoutDataAllocator); - - Resources.SetStaticSamplers(m_pBoundResourceCaches[s]); + SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + new (m_pResourceLayouts + s) + ShaderResourceLayoutD3D11 + { + *this, + pRenderDevice, + pShaderD3D11->GetD3D11Resources(), + PSODesc.ResourceLayout, + VarTypes, + _countof(VarTypes), + m_pBoundResourceCaches[s], + ResCacheDataAllocator, + ResLayoutDataAllocator + }; + + m_pResourceLayouts[s].SetStaticSamplers(m_pBoundResourceCaches[s]); + pPSO->GetStaticResourceLayout(s).SetStaticSamplers(m_pBoundResourceCaches[s]); m_ResourceLayoutIndex[ShaderInd] = s; m_ShaderTypeIndex[s] = static_cast(ShaderInd); @@ -99,7 +109,7 @@ ShaderResourceBindingD3D11Impl::~ShaderResourceBindingD3D11Impl() IMPLEMENT_QUERY_INTERFACE( ShaderResourceBindingD3D11Impl, IID_ShaderResourceBindingD3D11, TBase ) -void ShaderResourceBindingD3D11Impl::BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) +void ShaderResourceBindingD3D11Impl::BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) { for(Uint32 ResLayoutInd = 0; ResLayoutInd < m_NumActiveShaders; ++ResLayoutInd) { @@ -135,9 +145,10 @@ void ShaderResourceBindingD3D11Impl::InitializeStaticResources(const IPipelineSt for (Uint32 shader = 0; shader < NumShaders; ++shader) { + const auto& StaticResLayout = pPSOD3D11->GetStaticResourceLayout(shader); auto* pShaderD3D11 = ValidatedCast(ppShaders[shader]); #ifdef DEVELOPMENT - if (!pShaderD3D11->GetStaticResourceLayout().dvpVerifyBindings()) + if (!StaticResLayout.dvpVerifyBindings()) { LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOD3D11->GetDesc().Name, "' will not be successfully initialized " "because not all static resource bindings in shader '", pShaderD3D11->GetDesc().Name, "' are valid. " @@ -147,17 +158,18 @@ void ShaderResourceBindingD3D11Impl::InitializeStaticResources(const IPipelineSt #endif #ifdef _DEBUG - auto ShaderTypeInd = pShaderD3D11->GetShaderTypeIndex(); + auto ShaderTypeInd = GetShaderTypeIndex(pShaderD3D11->GetDesc().ShaderType); auto ResourceLayoutInd = m_ResourceLayoutIndex[ShaderTypeInd]; VERIFY_EXPR(ResourceLayoutInd == static_cast(shader) ); #endif - pShaderD3D11->GetStaticResourceLayout().CopyResources( m_pBoundResourceCaches[shader] ); + StaticResLayout.CopyResources(m_pBoundResourceCaches[shader]); + //StaticResLayout.SetStaticSamplers(m_pBoundResourceCaches[shader]); } m_bIsStaticResourcesBound = true; } -IShaderVariable* ShaderResourceBindingD3D11Impl::GetVariable(SHADER_TYPE ShaderType, const char* Name) +IShaderResourceVariable* ShaderResourceBindingD3D11Impl::GetVariable(SHADER_TYPE ShaderType, const char* Name) { auto Ind = GetShaderTypeIndex(ShaderType); VERIFY_EXPR(Ind >= 0 && Ind < _countof(m_ResourceLayoutIndex)); @@ -185,7 +197,7 @@ Uint32 ShaderResourceBindingD3D11Impl::GetVariableCount(SHADER_TYPE ShaderType) return m_pResourceLayouts[ResLayoutIndex].GetTotalResourceCount(); } -IShaderVariable* ShaderResourceBindingD3D11Impl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) +IShaderResourceVariable* ShaderResourceBindingD3D11Impl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) { auto Ind = GetShaderTypeIndex(ShaderType); VERIFY_EXPR(Ind >= 0 && Ind < _countof(m_ResourceLayoutIndex)); diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp index c6cf6f6b..6839e29d 100755 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp @@ -33,14 +33,11 @@ #include "TextureViewD3D11.h" #include "SamplerD3D11Impl.h" #include "ShaderD3D11Impl.h" +#include "ShaderResourceVariableBase.h" namespace Diligent { -ShaderResourceLayoutD3D11::ShaderResourceLayoutD3D11(IObject& Owner) : - m_Owner(Owner) -{ -} ShaderResourceLayoutD3D11::~ShaderResourceLayoutD3D11() { @@ -83,7 +80,7 @@ size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes) { - auto ResCounters = SrcResources.CountResources(ResourceLayout, SrcResources.GetShaderType(), SrcResources.GetCombinedSamplerSuffix(), AllowedVarTypes, NumAllowedTypes); + auto ResCounters = SrcResources.CountResources(ResourceLayout, AllowedVarTypes, NumAllowedTypes); auto MemSize = ResCounters.NumCBs * sizeof(ConstBuffBindInfo) + ResCounters.NumTexSRVs * sizeof(TexSRVBindInfo) + ResCounters.NumTexUAVs * sizeof(TexUAVBindInfo) + @@ -93,23 +90,26 @@ size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D return MemSize; } -#if 0 -void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr pSrcResources, - const SHADER_VARIABLE_TYPE* VarTypes, - Uint32 NumVarTypes, - ShaderResourceCacheD3D11& ResourceCache, - IMemoryAllocator& ResCacheDataAllocator, - IMemoryAllocator& ResLayoutDataAllocator) + +ShaderResourceLayoutD3D11::ShaderResourceLayoutD3D11(IObject& Owner, + IRenderDevice* pRenderDevice, + std::shared_ptr pSrcResources, + const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes, + Uint32 NumVarTypes, + ShaderResourceCacheD3D11& ResourceCache, + IMemoryAllocator& ResCacheDataAllocator, + IMemoryAllocator& ResLayoutDataAllocator) : + m_Owner (Owner), + m_pResources (std::move(pSrcResources)), + m_ResourceCache (ResourceCache) { // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout#Shader-Resource-Layout-Initialization - m_pResources = std::move(pSrcResources); - m_pResourceCache = &ResourceCache; - - auto AllowedTypeBits = GetAllowedTypeBits(VarTypes, NumVarTypes); + const auto AllowedTypeBits = GetAllowedTypeBits(VarTypes, NumVarTypes); // Count total number of resources of allowed types - auto ResCounters = m_pResources->CountResources(VarTypes, NumVarTypes); + auto ResCounters = m_pResources->CountResources(ResourceLayout, VarTypes, NumVarTypes); // Initialize offsets size_t CurrentOffset = 0; @@ -122,7 +122,7 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr >(pRawMem, ResLayoutDataAllocator); } @@ -158,33 +158,41 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptrProcessResources( - VarTypes, NumVarTypes, - [&](const D3DShaderResourceAttribs& CB, Uint32) { - VERIFY_EXPR( CB.IsAllowedType(AllowedTypeBits) ); - - // Initialize current CB in place, increment CB counter - new (&GetResource(cb++)) ConstBuffBindInfo( CB, *this ); - NumCBSlots = std::max(NumCBSlots, Uint32{CB.BindPoint} + Uint32{CB.BindCount}); + auto VarType = m_pResources->FindVariableType(CB, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + // Initialize current CB in place, increment CB counter + new (&GetResource(cb++)) ConstBuffBindInfo(CB, *this, VarType); + NumCBSlots = std::max(NumCBSlots, Uint32{CB.BindPoint} + Uint32{CB.BindCount}); + } }, [&](const D3DShaderResourceAttribs& Sampler, Uint32) { - VERIFY_EXPR(Sampler.IsAllowedType(AllowedTypeBits)); - - // Skip static samplers as they are initialized in the resource cache - if (!Sampler.IsStaticSampler()) + auto VarType = m_pResources->FindVariableType(Sampler, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { + auto StaticSamplerInd = m_pResources->FindStaticSampler(Sampler, ResourceLayout); + RefCntAutoPtr pStaticSampler; + if (StaticSamplerInd >= 0) + { + const auto& StaticSamplerDesc = ResourceLayout.StaticSamplers[StaticSamplerInd]; + pRenderDevice->CreateSampler(StaticSamplerDesc.Desc, &pStaticSampler); + } // Initialize current sampler in place, increment sampler counter - new (&GetResource(sam++)) SamplerBindInfo( Sampler, *this ); + new (&GetResource(sam++)) SamplerBindInfo(Sampler, *this, VarType, std::move(pStaticSampler)); NumSamplerSlots = std::max(NumSamplerSlots, Uint32{Sampler.BindPoint} + Uint32{Sampler.BindCount}); } }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { - VERIFY_EXPR( TexSRV.IsAllowedType(AllowedTypeBits) ); + auto VarType = m_pResources->FindVariableType(TexSRV, ResourceLayout); + if (!IsAllowedType(VarType, AllowedTypeBits)) + return; + auto NumSamplers = GetNumSamplers(); VERIFY(sam == NumSamplers, "All samplers must be initialized before texture SRVs"); @@ -192,53 +200,66 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptrGetSampler(TexSRV.GetSamplerId()); - DEV_CHECK_ERR(AssignedSamplerAttribs.GetVariableType() == TexSRV.GetVariableType(), - "The type (", GetShaderVariableTypeLiteralName(TexSRV.GetVariableType()),") of texture SRV variable '", TexSRV.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(AssignedSamplerAttribs.GetVariableType()), + auto AssignedSamplerType = m_pResources->FindVariableType(AssignedSamplerAttribs, ResourceLayout); + DEV_CHECK_ERR(AssignedSamplerType == VarType, + "The type (", GetShaderVariableTypeLiteralName(VarType),") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(AssignedSamplerType), ") of the sampler '", AssignedSamplerAttribs.Name, "' that is assigned to it"); - // Do not assign static sampler to texture SRV as it is initialized directly in the shader resource cache - if (!AssignedSamplerAttribs.IsStaticSampler()) + + bool SamplerFound = false; + for (AssignedSamplerIndex = 0; AssignedSamplerIndex < NumSamplers && !SamplerFound; ++AssignedSamplerIndex) { - for (AssignedSamplerIndex = 0; AssignedSamplerIndex < NumSamplers; ++AssignedSamplerIndex) + const auto& Sampler = GetResource(AssignedSamplerIndex); + SamplerFound = strcmp(Sampler.m_Attribs.Name, AssignedSamplerAttribs.Name) == 0; + if (SamplerFound) { - const auto& Sampler = GetResource(AssignedSamplerIndex); - if (strcmp(Sampler.m_Attribs.Name, AssignedSamplerAttribs.Name) == 0) + if (Sampler.pStaticSampler) + { + // Do not assign static samplers to texture SRV + AssignedSamplerIndex = TexSRVBindInfo::InvalidSamplerIndex; break; + } } - VERIFY(AssignedSamplerIndex < NumSamplers, "Unable to find assigned sampler"); } + VERIFY(SamplerFound, "Unable to find sampler assigned to texture SRV '", TexSRV.Name, "'"); } // Initialize tex SRV in place, increment counter of tex SRVs - new (&GetResource(texSrv++)) TexSRVBindInfo( TexSRV, AssignedSamplerIndex, *this ); + new (&GetResource(texSrv++)) TexSRVBindInfo(TexSRV, AssignedSamplerIndex, *this, VarType); NumSRVSlots = std::max(NumSRVSlots, Uint32{TexSRV.BindPoint} + Uint32{TexSRV.BindCount}); }, [&](const D3DShaderResourceAttribs& TexUAV, Uint32) { - VERIFY_EXPR( TexUAV.IsAllowedType(AllowedTypeBits) ); - - // Initialize tex UAV in place, increment counter of tex UAVs - new (&GetResource(texUav++)) TexUAVBindInfo( TexUAV, *this ); - NumUAVSlots = std::max(NumUAVSlots, Uint32{TexUAV.BindPoint} + Uint32{TexUAV.BindCount}); + auto VarType = m_pResources->FindVariableType(TexUAV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + // Initialize tex UAV in place, increment counter of tex UAVs + new (&GetResource(texUav++)) TexUAVBindInfo(TexUAV, *this, VarType); + NumUAVSlots = std::max(NumUAVSlots, Uint32{TexUAV.BindPoint} + Uint32{TexUAV.BindCount}); + } }, [&](const D3DShaderResourceAttribs& BuffSRV, Uint32) { - VERIFY_EXPR(BuffSRV.IsAllowedType(AllowedTypeBits)); - - // Initialize buff SRV in place, increment counter of buff SRVs - new (&GetResource(bufSrv++)) BuffSRVBindInfo( BuffSRV, *this ); - NumSRVSlots = std::max(NumSRVSlots, Uint32{BuffSRV.BindPoint} + Uint32{BuffSRV.BindCount}); + auto VarType = m_pResources->FindVariableType(BuffSRV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + // Initialize buff SRV in place, increment counter of buff SRVs + new (&GetResource(bufSrv++)) BuffSRVBindInfo(BuffSRV, *this, VarType); + NumSRVSlots = std::max(NumSRVSlots, Uint32{BuffSRV.BindPoint} + Uint32{BuffSRV.BindCount}); + } }, [&](const D3DShaderResourceAttribs& BuffUAV, Uint32) { - VERIFY_EXPR(BuffUAV.IsAllowedType(AllowedTypeBits)); - - // Initialize buff UAV in place, increment counter of buff UAVs - new (&GetResource(bufUav++)) BuffUAVBindInfo( BuffUAV, *this ); - NumUAVSlots = std::max(NumUAVSlots, Uint32{BuffUAV.BindPoint} + Uint32{BuffUAV.BindCount}); + auto VarType = m_pResources->FindVariableType(BuffUAV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + // Initialize buff UAV in place, increment counter of buff UAVs + new (&GetResource(bufUav++)) BuffUAVBindInfo(BuffUAV, *this, VarType); + NumUAVSlots = std::max(NumUAVSlots, Uint32{BuffUAV.BindPoint} + Uint32{BuffUAV.BindCount}); + } } ); @@ -253,22 +274,19 @@ void ShaderResourceLayoutD3D11::Initialize(std::shared_ptrIsInitialized()) + if (!m_ResourceCache.IsInitialized()) { // NOTE that here we are using max bind points required to cache only the shader variables of allowed types! - m_pResourceCache->Initialize(NumCBSlots, NumSRVSlots, NumSamplerSlots, NumUAVSlots, ResCacheDataAllocator); + m_ResourceCache.Initialize(NumCBSlots, NumSRVSlots, NumSamplerSlots, NumUAVSlots, ResCacheDataAllocator); } } -#endif -void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache) +void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache)const { - VERIFY(m_pResourceCache, "Resource cache must not be null"); - - VERIFY( DstCache.GetCBCount() >= m_pResourceCache->GetCBCount(), "Dst cache is not large enough to contain all CBs" ); - VERIFY( DstCache.GetSRVCount() >= m_pResourceCache->GetSRVCount(), "Dst cache is not large enough to contain all SRVs" ); - VERIFY( DstCache.GetSamplerCount() >= m_pResourceCache->GetSamplerCount(), "Dst cache is not large enough to contain all samplers" ); - VERIFY( DstCache.GetUAVCount() >= m_pResourceCache->GetUAVCount(), "Dst cache is not large enough to contain all UAVs" ); + VERIFY( DstCache.GetCBCount() >= m_ResourceCache.GetCBCount(), "Dst cache is not large enough to contain all CBs" ); + VERIFY( DstCache.GetSRVCount() >= m_ResourceCache.GetSRVCount(), "Dst cache is not large enough to contain all SRVs" ); + VERIFY( DstCache.GetSamplerCount() >= m_ResourceCache.GetSamplerCount(), "Dst cache is not large enough to contain all samplers" ); + VERIFY( DstCache.GetUAVCount() >= m_ResourceCache.GetUAVCount(), "Dst cache is not large enough to contain all UAVs" ); ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr; ID3D11Buffer** d3d11CBs = nullptr; @@ -278,10 +296,10 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache ID3D11SamplerState** d3d11Samplers = nullptr; ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr; ID3D11UnorderedAccessView** d3d11UAVs = nullptr; - m_pResourceCache->GetCBArrays (CachedCBs, d3d11CBs); - m_pResourceCache->GetSRVArrays (CachedSRVResources, d3d11SRVs); - m_pResourceCache->GetSamplerArrays(CachedSamplers, d3d11Samplers); - m_pResourceCache->GetUAVArrays (CachedUAVResources, d3d11UAVs); + m_ResourceCache.GetCBArrays (CachedCBs, d3d11CBs); + m_ResourceCache.GetSRVArrays (CachedSRVResources, d3d11SRVs); + m_ResourceCache.GetSamplerArrays(CachedSamplers, d3d11Samplers); + m_ResourceCache.GetUAVArrays (CachedUAVResources, d3d11UAVs); ShaderResourceCacheD3D11::CachedCB* DstCBs = nullptr; @@ -297,12 +315,12 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache DstCache.GetSamplerArrays(DstSamplers, DstD3D11Samplers); DstCache.GetUAVArrays (DstUAVResources, DstD3D11UAVs); - HandleResources( + HandleConstResources( [&](const ConstBuffBindInfo& cb) { for(auto CBSlot = cb.m_Attribs.BindPoint; CBSlot < cb.m_Attribs.BindPoint+cb.m_Attribs.BindCount; ++CBSlot) { - VERIFY_EXPR(CBSlot < m_pResourceCache->GetCBCount() && CBSlot < DstCache.GetCBCount()); + VERIFY_EXPR(CBSlot < m_ResourceCache.GetCBCount() && CBSlot < DstCache.GetCBCount()); DstCBs [CBSlot] = CachedCBs[CBSlot]; DstD3D11CBs[CBSlot] = d3d11CBs [CBSlot]; } @@ -312,7 +330,7 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache { for(auto SRVSlot = ts.m_Attribs.BindPoint; SRVSlot < ts.m_Attribs.BindPoint + ts.m_Attribs.BindCount; ++SRVSlot) { - VERIFY_EXPR(SRVSlot < m_pResourceCache->GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); + VERIFY_EXPR(SRVSlot < m_ResourceCache.GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot]; DstD3D11SRVs [SRVSlot] = d3d11SRVs [SRVSlot]; } @@ -322,7 +340,7 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache { for(auto UAVSlot = uav.m_Attribs.BindPoint; UAVSlot < uav.m_Attribs.BindPoint + uav.m_Attribs.BindCount; ++UAVSlot) { - VERIFY_EXPR(UAVSlot < m_pResourceCache->GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); + VERIFY_EXPR(UAVSlot < m_ResourceCache.GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot]; DstD3D11UAVs [UAVSlot] = d3d11UAVs [UAVSlot]; } @@ -332,7 +350,7 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache { for(auto SRVSlot = srv.m_Attribs.BindPoint; SRVSlot < srv.m_Attribs.BindPoint + srv.m_Attribs.BindCount; ++SRVSlot) { - VERIFY_EXPR(SRVSlot < m_pResourceCache->GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); + VERIFY_EXPR(SRVSlot < m_ResourceCache.GetSRVCount() && SRVSlot < DstCache.GetSRVCount()); DstSRVResources[SRVSlot] = CachedSRVResources[SRVSlot]; DstD3D11SRVs [SRVSlot] = d3d11SRVs [SRVSlot]; } @@ -342,7 +360,7 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache { for(auto UAVSlot = uav.m_Attribs.BindPoint; UAVSlot < uav.m_Attribs.BindPoint + uav.m_Attribs.BindCount; ++UAVSlot) { - VERIFY_EXPR(UAVSlot < m_pResourceCache->GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); + VERIFY_EXPR(UAVSlot < m_ResourceCache.GetUAVCount() && UAVSlot < DstCache.GetUAVCount()); DstUAVResources[UAVSlot] = CachedUAVResources[UAVSlot]; DstD3D11UAVs [UAVSlot] = d3d11UAVs [UAVSlot]; } @@ -350,10 +368,10 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache [&](const SamplerBindInfo& sam) { - VERIFY(!sam.IsStaticSampler(), "Variables are not created for static samplers"); + VERIFY(!sam.pStaticSampler, "Variables are not created for static samplers"); for(auto SamSlot = sam.m_Attribs.BindPoint; SamSlot < sam.m_Attribs.BindPoint + sam.m_Attribs.BindCount; ++SamSlot) { - VERIFY_EXPR(SamSlot < m_pResourceCache->GetSamplerCount() && SamSlot < DstCache.GetSamplerCount()); + VERIFY_EXPR(SamSlot < m_ResourceCache.GetSamplerCount() && SamSlot < DstCache.GetSamplerCount()); DstSamplers [SamSlot] = CachedSamplers[SamSlot]; DstD3D11Samplers[SamSlot] = d3d11Samplers [SamSlot]; } @@ -361,6 +379,24 @@ void ShaderResourceLayoutD3D11::CopyResources(ShaderResourceCacheD3D11& DstCache ); } +void ShaderResourceLayoutD3D11::SetStaticSamplers(ShaderResourceCacheD3D11& ResourceCache)const +{ + auto NumCachedSamplers = ResourceCache.GetSamplerCount(); + for (Uint32 s = 0; s < GetNumResources(); ++s) + { + auto& Sampler = GetConstResource(s); + if (Sampler.pStaticSampler) + { + const auto& SamAttribs = Sampler.m_Attribs; + auto* pSamplerD3D11Impl = const_cast(Sampler.pStaticSampler.RawPtr()); + // Limiting EndBindPoint is required when initializing static samplers in a Shader's static cache + auto EndBindPoint = std::min( static_cast(SamAttribs.BindPoint) + SamAttribs.BindCount, NumCachedSamplers); + for (Uint32 BindPoint = SamAttribs.BindPoint; BindPoint < EndBindPoint; ++BindPoint ) + ResourceCache.SetSampler(BindPoint, pSamplerD3D11Impl); + } + } +} + #define LOG_RESOURCE_BINDING_ERROR(ResType, pResource, Attribs, ArrayInd, ShaderName, ...)\ do{ \ const auto* ResName = pResource->GetDesc().Name; \ @@ -375,9 +411,8 @@ do{ void ShaderResourceLayoutD3D11::ConstBuffBindInfo::BindResource(IDeviceObject* pBuffer, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -408,13 +443,10 @@ void ShaderResourceLayoutD3D11::ConstBuffBindInfo::BindResource(IDeviceObject* p -bool ShaderResourceLayoutD3D11::ConstBuffBindInfo::IsBound(Uint32 ArrayIndex) +bool ShaderResourceLayoutD3D11::ConstBuffBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsCBBound(m_Attribs.BindPoint + ArrayIndex); + return m_ParentResLayout.m_ResourceCache.IsCBBound(m_Attribs.BindPoint + ArrayIndex); } @@ -449,9 +481,8 @@ bool dbgVerifyViewType( const char* ViewTypeName, void ShaderResourceLayoutD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -476,7 +507,7 @@ void ShaderResourceLayoutD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pVie if (ValidSamplerAssigned()) { auto& Sampler = m_ParentResLayout.GetResource(SamplerIndex); - VERIFY(!Sampler.IsStaticSampler(), "Static samplers are not assigned to texture SRVs as they are initialized directly in the shader resource cache"); + VERIFY(!Sampler.pStaticSampler, "Static samplers are not assigned to texture SRVs as they are initialized directly in the shader resource cache"); VERIFY_EXPR(Sampler.m_Attribs.BindCount == m_Attribs.BindCount || Sampler.m_Attribs.BindCount == 1); auto SamplerBindPoint = Sampler.m_Attribs.BindPoint + (Sampler.m_Attribs.BindCount != 1 ? ArrayIndex : 0); @@ -514,10 +545,9 @@ void ShaderResourceLayoutD3D11::TexSRVBindInfo::BindResource(IDeviceObject* pVie void ShaderResourceLayoutD3D11::SamplerBindInfo::BindResource(IDeviceObject* pSampler, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; - VERIFY(!IsStaticSampler(), "Cannot bind sampler to a static sampler"); + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; + VERIFY(!pStaticSampler, "Cannot bind sampler to a static sampler"); // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -550,9 +580,8 @@ void ShaderResourceLayoutD3D11::SamplerBindInfo::BindResource(IDeviceObject* pSa void ShaderResourceLayoutD3D11::BuffSRVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -581,9 +610,8 @@ void ShaderResourceLayoutD3D11::BuffSRVBindInfo::BindResource(IDeviceObject* pVi void ShaderResourceLayoutD3D11::TexUAVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -612,9 +640,8 @@ void ShaderResourceLayoutD3D11::TexUAVBindInfo::BindResource(IDeviceObject* pVie void ShaderResourceLayoutD3D11::BuffUAVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) { - VERIFY(m_ParentResLayout.m_pResourceCache != nullptr, "Resource cache is null"); DEV_CHECK_ERR(ArrayIndex < m_Attribs.BindCount, "Array index (", ArrayIndex, ") is out of range for variable '", m_Attribs.Name, "'. Max allowed index: ", m_Attribs.BindCount); - auto& ResourceCache = *m_ParentResLayout.m_pResourceCache; + auto& ResourceCache = m_ParentResLayout.m_ResourceCache; // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type @@ -642,48 +669,33 @@ void ShaderResourceLayoutD3D11::BuffUAVBindInfo::BindResource(IDeviceObject* pVi bool ShaderResourceLayoutD3D11::TexSRVBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache != nullptr, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsSRVBound(m_Attribs.BindPoint + ArrayIndex, true); + return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, true); } bool ShaderResourceLayoutD3D11::BuffSRVBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsSRVBound(m_Attribs.BindPoint + ArrayIndex, false); + return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, false); } bool ShaderResourceLayoutD3D11::TexUAVBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsUAVBound(m_Attribs.BindPoint + ArrayIndex, true); + return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, true); } bool ShaderResourceLayoutD3D11::BuffUAVBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsUAVBound(m_Attribs.BindPoint + ArrayIndex, false); + return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, false); } bool ShaderResourceLayoutD3D11::SamplerBindInfo::IsBound(Uint32 ArrayIndex)const { - auto* pResourceCache = m_ParentResLayout.m_pResourceCache; - VERIFY(pResourceCache, "Resource cache is null"); VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount); - - return pResourceCache->IsSamplerBound(m_Attribs.BindPoint + ArrayIndex); + return m_ParentResLayout.m_ResourceCache.IsSamplerBound(m_Attribs.BindPoint + ArrayIndex); } @@ -699,7 +711,7 @@ public: } template - void Bind( ResourceType &Res) + void Bind( ResourceType& Res) { if ( (Flags & (1 << Res.GetType())) == 0 ) return; @@ -732,7 +744,7 @@ private: void ShaderResourceLayoutD3D11::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11& dbgResourceCache ) { - VERIFY(&dbgResourceCache == m_pResourceCache, "Resource cache does not match the cache provided at initialization"); + VERIFY(&dbgResourceCache == &m_ResourceCache, "Resource cache does not match the cache provided at initialization"); if (pResourceMapping == nullptr) { @@ -812,8 +824,16 @@ IShaderResourceVariable* ShaderResourceLayoutD3D11::GetShaderVariable(const Char if (!m_pResources->IsUsingCombinedTextureSamplers()) { - if(auto* pSampler = GetResourceByName(Name)) - return pSampler; + auto NumSamplers = GetNumResources(); + for (Uint32 s = 0; s < NumSamplers; ++s) + { + auto& Sampler = GetResource(s); + if (strcmp(Sampler.m_Attribs.Name, Name) == 0) + { + // Do not return static samplers + return Sampler.pStaticSampler ? nullptr : &Sampler; + } + } } return nullptr; @@ -971,17 +991,15 @@ do{ \ LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable '", Attrs.Name, "[", BindPt-Attrs.BindPoint, "]' in shader '", GetShaderName(), "'" );\ }while(false) - m_pResourceCache->dbgVerifyCacheConsistency(); + m_ResourceCache.dbgVerifyCacheConsistency(); bool BindingsOK = true; - // Use const_cast to avoid duplication of the HandleResources() function - // The function actually changes nothing - const_cast(this)->HandleResources( + HandleConstResources( [&](const ConstBuffBindInfo& cb) { for (Uint32 BindPoint = cb.m_Attribs.BindPoint; BindPoint < Uint32{cb.m_Attribs.BindPoint} + cb.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsCBBound(BindPoint)) + if (!m_ResourceCache.IsCBBound(BindPoint)) { LOG_MISSING_BINDING("constant buffer", cb.m_Attribs, BindPoint); BindingsOK = false; @@ -993,7 +1011,7 @@ do{ \ { for (Uint32 BindPoint = ts.m_Attribs.BindPoint; BindPoint < Uint32{ts.m_Attribs.BindPoint} + ts.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsSRVBound(BindPoint, true)) + if (!m_ResourceCache.IsSRVBound(BindPoint, true)) { LOG_MISSING_BINDING("texture", ts.m_Attribs, BindPoint); BindingsOK = false; @@ -1009,14 +1027,14 @@ do{ \ { ShaderResourceCacheD3D11::CachedSampler* pCachedSamplers = nullptr; ID3D11SamplerState** ppCachedD3D11Samplers = nullptr; - m_pResourceCache->GetSamplerArrays(pCachedSamplers, ppCachedD3D11Samplers); - VERIFY_EXPR(Sampler.m_Attribs.BindPoint < m_pResourceCache->GetSamplerCount()); + m_ResourceCache.GetSamplerArrays(pCachedSamplers, ppCachedD3D11Samplers); + VERIFY_EXPR(Sampler.m_Attribs.BindPoint < m_ResourceCache.GetSamplerCount()); const auto& CachedSampler = pCachedSamplers[Sampler.m_Attribs.BindPoint]; ShaderResourceCacheD3D11::CachedResource* pCachedResources = nullptr; ID3D11ShaderResourceView** ppCachedD3D11Resources = nullptr; - m_pResourceCache->GetSRVArrays(pCachedResources, ppCachedD3D11Resources); - VERIFY_EXPR(BindPoint < m_pResourceCache->GetSRVCount()); + m_ResourceCache.GetSRVArrays(pCachedResources, ppCachedD3D11Resources); + VERIFY_EXPR(BindPoint < m_ResourceCache.GetSRVCount()); auto& CachedResource = pCachedResources[BindPoint]; if (CachedResource.pView) { @@ -1036,7 +1054,7 @@ do{ \ { for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsUAVBound(BindPoint, true)) + if (!m_ResourceCache.IsUAVBound(BindPoint, true)) { LOG_MISSING_BINDING("texture UAV", uav.m_Attribs, BindPoint); BindingsOK = false; @@ -1048,7 +1066,7 @@ do{ \ { for (Uint32 BindPoint = buf.m_Attribs.BindPoint; BindPoint < Uint32{buf.m_Attribs.BindPoint} + buf.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsSRVBound(BindPoint, false)) + if (!m_ResourceCache.IsSRVBound(BindPoint, false)) { LOG_MISSING_BINDING("buffer", buf.m_Attribs, BindPoint); BindingsOK = false; @@ -1060,7 +1078,7 @@ do{ \ { for (Uint32 BindPoint = uav.m_Attribs.BindPoint; BindPoint < Uint32{uav.m_Attribs.BindPoint} + uav.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsUAVBound(BindPoint, false)) + if (!m_ResourceCache.IsUAVBound(BindPoint, false)) { LOG_MISSING_BINDING("buffer UAV", uav.m_Attribs, BindPoint); BindingsOK = false; @@ -1072,7 +1090,7 @@ do{ \ { for (Uint32 BindPoint = sam.m_Attribs.BindPoint; BindPoint < Uint32{sam.m_Attribs.BindPoint} + sam.m_Attribs.BindCount; ++BindPoint) { - if (!m_pResourceCache->IsSamplerBound(BindPoint)) + if (!m_ResourceCache.IsSamplerBound(BindPoint)) { LOG_MISSING_BINDING("sampler", sam.m_Attribs, BindPoint); BindingsOK = false; diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp index 78dfcf63..a12a8ff6 100755 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp @@ -37,8 +37,7 @@ ShaderResourcesD3D11::ShaderResourcesD3D11(RenderDeviceD3D11Impl* pDeviceD3D11Im ID3DBlob* pShaderBytecode, const ShaderDesc& ShdrDesc, const char* CombinedSamplerSuffix) : - ShaderResources(ShdrDesc.ShaderType), - m_ShaderName(ShdrDesc.Name) + ShaderResources(ShdrDesc.ShaderType) { class NewResourceHandler { diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h index 64c8fe61..4c38c4f5 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h @@ -67,33 +67,35 @@ namespace Diligent { +// sizeof(D3DShaderResourceAttribs) == 16 (x64) struct D3DShaderResourceAttribs { - const char* const Name; +/* 0 */ const char* const Name; - const Uint16 BindPoint; - const Uint16 BindCount; +/* 8 */ const Uint16 BindPoint; +/*10 */ const Uint16 BindCount; private: // 4 4 24 // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 | // | | | | // | InputType | SRV Dim | SamplerOrTexSRVIdBits | - static constexpr const Uint32 ShaderInputTypeBits = 4; - static constexpr const Uint32 SRVDimBits = 4; - static constexpr const Uint32 SamplerOrTexSRVIdBits = 24; + static constexpr const Uint32 ShaderInputTypeBits = 4; + static constexpr const Uint32 SRVDimBits = 4; + static constexpr const Uint32 SamplerOrTexSRVIdBits = 24; static_assert(ShaderInputTypeBits + SRVDimBits + SamplerOrTexSRVIdBits == 32, "Attributes are better be packed into 32 bits"); static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE"); static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION"); - // We need to use Uint32 instead of the actual type for reliability and correctness. - // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: - // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type - // is signed) causing errors - const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 - const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 - Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 1048575 + // We need to use Uint32 instead of the actual type for reliability and correctness. + // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: + // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type + // is signed) causing errors +/*12.0*/ const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 +/*12.4*/ const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 +/*13.0*/ Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 2^24-1 +/*16 */ // End of structure public: static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1; @@ -224,10 +226,6 @@ public: SamplerOrTexSRVId == Attribs.SamplerOrTexSRVId; } - SHADER_RESOURCE_VARIABLE_TYPE FindVariableType(SHADER_TYPE ShaderType, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const char* CombinedSamplerSuffix)const; - size_t GetHash()const { return ComputeHash(BindPoint, BindCount, InputType, SRVDimension, SamplerOrTexSRVId); @@ -240,33 +238,37 @@ static_assert(sizeof(D3DShaderResourceAttribs) == sizeof(void*) + sizeof(Uint32) class ShaderResources { public: - ShaderResources(SHADER_TYPE ShaderType); + ShaderResources(SHADER_TYPE ShaderType)noexcept : + m_ShaderType(ShaderType) + { + } - ShaderResources (const ShaderResources&) = delete; - ShaderResources (ShaderResources&&) = delete; - ShaderResources& operator = (const ShaderResources&) = delete; - ShaderResources& operator = (ShaderResources&&) = delete; + ShaderResources (const ShaderResources&) = delete; + ShaderResources ( ShaderResources&&) = delete; + ShaderResources& operator = (const ShaderResources&) = delete; + ShaderResources& operator = ( ShaderResources&&) = delete; ~ShaderResources(); - Uint32 GetNumCBs() const noexcept{ return (m_TexSRVOffset - 0); } - Uint32 GetNumTexSRV() const noexcept{ return (m_TexUAVOffset - m_TexSRVOffset); } - Uint32 GetNumTexUAV() const noexcept{ return (m_BufSRVOffset - m_TexUAVOffset); } - Uint32 GetNumBufSRV() const noexcept{ return (m_BufUAVOffset - m_BufSRVOffset); } - Uint32 GetNumBufUAV() const noexcept{ return (m_SamplersOffset - m_BufUAVOffset); } - Uint32 GetNumSamplers() const noexcept{ return (m_TotalResources - m_SamplersOffset); } - Uint32 GetTotalResources()const noexcept{ return m_TotalResources; } - - const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumCBs(), 0); } - const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } - const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } - const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } - const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } - const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } + Uint32 GetNumCBs() const noexcept { return (m_TexSRVOffset - 0); } + Uint32 GetNumTexSRV() const noexcept { return (m_TexUAVOffset - m_TexSRVOffset); } + Uint32 GetNumTexUAV() const noexcept { return (m_BufSRVOffset - m_TexUAVOffset); } + Uint32 GetNumBufSRV() const noexcept { return (m_BufUAVOffset - m_BufSRVOffset); } + Uint32 GetNumBufUAV() const noexcept { return (m_SamplersOffset - m_BufUAVOffset); } + Uint32 GetNumSamplers() const noexcept { return (m_TotalResources - m_SamplersOffset); } + Uint32 GetTotalResources()const noexcept { return m_TotalResources; } + + const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept { return GetResAttribs(n, GetNumCBs(), 0); } + const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } SHADER_TYPE GetShaderType()const noexcept{return m_ShaderType;} - // Processes only resources listed in AllowedVarTypes + ShaderResourceDesc GetShaderResourceDesc(Uint32 Index)const; + template > m_MemoryBuffer; StringPool m_ResourceNames; - const char* m_SamplerSuffix = nullptr; // The suffix is put into the m_ResourceNames + const char* m_SamplerSuffix = nullptr; // The suffix and the shader name + const char* m_ShaderName = nullptr; // are put into the m_ResourceNames // Offsets in elements of D3DShaderResourceAttribs typedef Uint16 OffsetType; @@ -384,7 +395,7 @@ private: OffsetType m_SamplersOffset = 0; OffsetType m_TotalResources = 0; - SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; + const SHADER_TYPE m_ShaderType; }; @@ -403,6 +414,9 @@ void ShaderResources::Initialize(ID3DBlob* pShaderByteCode, [&](const D3DShaderResourceCounters& ResCounters, size_t ResourceNamesPoolSize) { + VERIFY_EXPR(ShaderName != nullptr); + ResourceNamesPoolSize += strlen(ShaderName)+1; + if (CombinedSamplerSuffix != nullptr) ResourceNamesPoolSize += strlen(CombinedSamplerSuffix)+1; @@ -459,6 +473,8 @@ void ShaderResources::Initialize(ID3DBlob* pShaderByteCode, NewResHandler.OnNewTexSRV(*pNewTexSRV); }); + m_ShaderName = m_ResourceNames.CopyString(ShaderName); + if (CombinedSamplerSuffix != nullptr) { m_SamplerSuffix = m_ResourceNames.CopyString(CombinedSamplerSuffix); @@ -504,4 +520,3 @@ namespace std } }; } - diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index 97107560..613cd96a 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -31,25 +31,6 @@ namespace Diligent { -SHADER_RESOURCE_VARIABLE_TYPE D3DShaderResourceAttribs::FindVariableType(SHADER_TYPE ShaderType, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const char* CombinedSamplerSuffix)const -{ - if (GetInputType() == D3D_SIT_SAMPLER) - { - // Only use CombinedSamplerSuffix when looking for the sampler variable type - return GetShaderVariableType(ShaderType, ResourceLayoutDesc.DefaultVariableType, ResourceLayoutDesc.Variables, ResourceLayoutDesc.NumVariables, - [&](const char* VarName) - { - return StreqSuff(Name, VarName, CombinedSamplerSuffix); - }); - } - else - { - return GetShaderVariableType(ShaderType, Name, ResourceLayoutDesc); - } -} - ShaderResources::~ShaderResources() { for(Uint32 n=0; n < GetNumCBs(); ++n) @@ -85,7 +66,7 @@ void ShaderResources::AllocateMemory(IMemoryAllocator& Allocator, return Offset; }; - auto CBOffset = AdvanceOffset(ResCounters.NumCBs); CBOffset; // To suppress warning + auto CBOffset = AdvanceOffset(ResCounters.NumCBs); (void)CBOffset; // To suppress warning m_TexSRVOffset = AdvanceOffset(ResCounters.NumTexSRVs); m_TexUAVOffset = AdvanceOffset(ResCounters.NumTexUAVs); m_BufSRVOffset = AdvanceOffset(ResCounters.NumBufSRVs); @@ -111,15 +92,41 @@ void ShaderResources::AllocateMemory(IMemoryAllocator& Allocator, } } -ShaderResources::ShaderResources(SHADER_TYPE ShaderType): - m_ShaderType(ShaderType) +SHADER_RESOURCE_VARIABLE_TYPE ShaderResources::FindVariableType(const D3DShaderResourceAttribs& ResourceAttribs, + const PipelineResourceLayoutDesc& ResourceLayout)const { + if (ResourceAttribs.GetInputType() == D3D_SIT_SAMPLER) + { + // Only use CombinedSamplerSuffix when looking for the sampler variable type + return GetShaderVariableType(m_ShaderType, ResourceLayout.DefaultVariableType, ResourceLayout.Variables, ResourceLayout.NumVariables, + [&](const char* VarName) + { + return StreqSuff(ResourceAttribs.Name, VarName, m_SamplerSuffix); + }); + } + else + { + return GetShaderVariableType(m_ShaderType, ResourceAttribs.Name, ResourceLayout); + } +} + +Int32 ShaderResources::FindStaticSampler(const D3DShaderResourceAttribs& ResourceAttribs, + const PipelineResourceLayoutDesc& ResourceLayoutDesc)const +{ + VERIFY(ResourceAttribs.GetInputType() == D3D_SIT_SAMPLER, "Sampler is expected"); + + for (Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + { + const auto& StSam = ResourceLayoutDesc.StaticSamplers[s]; + if ( ((StSam.ShaderStages & m_ShaderType) != 0) && StreqSuff(ResourceAttribs.Name, StSam.SamplerOrTextureName, m_SamplerSuffix) ) + return s; + } + + return -1; } D3DShaderResourceCounters ShaderResources::CountResources(const PipelineResourceLayoutDesc& ResourceLayout, - SHADER_TYPE ShaderStage, - const char* CombinedSamplerSuffix, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes)const noexcept { @@ -129,41 +136,37 @@ D3DShaderResourceCounters ShaderResources::CountResources(const PipelineResource ProcessResources( [&](const D3DShaderResourceAttribs& CB, Uint32) { - auto VarType = CB.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(CB, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) ++Counters.NumCBs; }, [&](const D3DShaderResourceAttribs& Sam, Uint32) { - auto VarType = Sam.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(Sam, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) - { - // Skip static samplers - //if (!Sam.IsStaticSampler()) ++Counters.NumSamplers; - } }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { - auto VarType = TexSRV.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(TexSRV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) ++Counters.NumTexSRVs; }, [&](const D3DShaderResourceAttribs& TexUAV, Uint32) { - auto VarType = TexUAV.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(TexUAV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) ++Counters.NumTexUAVs; }, [&](const D3DShaderResourceAttribs& BufSRV, Uint32) { - auto VarType = BufSRV.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(BufSRV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) ++Counters.NumBufSRVs; }, [&](const D3DShaderResourceAttribs& BufUAV, Uint32) { - auto VarType = BufUAV.FindVariableType(ShaderStage, ResourceLayout, CombinedSamplerSuffix); + auto VarType = FindVariableType(BufUAV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) ++Counters.NumBufUAVs; } @@ -172,6 +175,82 @@ D3DShaderResourceCounters ShaderResources::CountResources(const PipelineResource return Counters; } +#ifdef DEVELOPMENT +void ShaderResources::DvpVerifyResourceLayout(const PipelineResourceLayoutDesc& ResourceLayout)const +{ + const auto UseCombinedTextureSamplers = IsUsingCombinedTextureSamplers(); + for (Uint32 v = 0; v < ResourceLayout.NumVariables; ++v) + { + const auto& VarDesc = ResourceLayout.Variables[v]; + if (VarDesc.ShaderStages == SHADER_TYPE_UNKNOWN) + { + LOG_WARNING_MESSAGE("No allowed shader stages are specified for ", GetShaderVariableTypeLiteralName(VarDesc.Type), " variable '", VarDesc.Name, "'."); + continue; + } + + if( (VarDesc.ShaderStages & m_ShaderType) == 0) + continue; + + bool VariableFound = false; + for (Uint32 n=0; n < m_TotalResources && !VariableFound; ++n) + { + const auto& Res = GetResAttribs(n, m_TotalResources, 0); + + // Skip samplers if combined texture samplers are used as + // in this case they are not treated as independent variables + if (UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) + continue; + + VariableFound = (strcmp(Res.Name, VarDesc.Name) == 0); + } + + if(!VariableFound) + { + LOG_WARNING_MESSAGE("Variable '", VarDesc.Name, "' is not found in shader '", m_ShaderName, '\''); + } + } + + for (Uint32 s = 0; s < ResourceLayout.NumStaticSamplers; ++s) + { + const auto& StSamDesc = ResourceLayout.StaticSamplers[s]; + if (StSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) + { + LOG_WARNING_MESSAGE("No allowed shader stages are specified for static sampler '", StSamDesc.SamplerOrTextureName, "'."); + continue; + } + + if ( (StSamDesc.ShaderStages & m_ShaderType) == 0) + continue; + + const auto* TexOrSamName = StSamDesc.SamplerOrTextureName; + + if (UseCombinedTextureSamplers) + { + bool TextureFound = false; + for(Uint32 n=0; n < GetNumTexSRV() && !TextureFound; ++n) + { + const auto& TexSRV = GetTexSRV(n); + TextureFound = (strcmp(TexSRV.Name, TexOrSamName) == 0); + } + if (!TextureFound) + { + LOG_WARNING_MESSAGE("Static sampler specifies a texture '", TexOrSamName, "' that is not found in shader '", m_ShaderName, '\''); + } + } + else + { + bool SamplerFound = false; + for(Uint32 n=0; n < GetNumSamplers() && !SamplerFound; ++n) + { + const auto& Sampler = GetSampler(n); + SamplerFound = (strcmp(Sampler.Name, TexOrSamName) == 0); + } + if (!SamplerFound) + LOG_WARNING_MESSAGE("Static sampler '", TexOrSamName, "' is not found in shader '", m_ShaderName, '\''); + } + } +} +#endif Uint32 ShaderResources::FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix)const @@ -237,35 +316,66 @@ bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const return IsCompatible; } -size_t ShaderResources::GetHash()const +ShaderResourceDesc ShaderResources::GetShaderResourceDesc(Uint32 Index)const { - size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV(), GetNumSamplers()); - ProcessResources( - [&](const D3DShaderResourceAttribs& CB, Uint32) - { - HashCombine(hash, CB); - }, - [&](const D3DShaderResourceAttribs& Sam, Uint32) - { - HashCombine(hash, Sam); - }, - [&](const D3DShaderResourceAttribs& TexSRV, Uint32) - { - HashCombine(hash, TexSRV); - }, - [&](const D3DShaderResourceAttribs& TexUAV, Uint32) - { - HashCombine(hash, TexUAV); - }, - [&](const D3DShaderResourceAttribs& BufSRV, Uint32) - { - HashCombine(hash, BufSRV); - }, - [&](const D3DShaderResourceAttribs& BufUAV, Uint32) + DEV_CHECK_ERR(Index < m_TotalResources, "Resource index (", Index, ") is out of range"); + ShaderResourceDesc ResourceDesc; + if (Index < m_TotalResources) + { + const auto& Res = GetResAttribs(Index, 0, m_TotalResources); + ResourceDesc.Name = Res.Name; + ResourceDesc.ArraySize = Res.BindCount; + switch(Res.GetInputType()) { - HashCombine(hash, BufUAV); + case D3D_SIT_CBUFFER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; + break; + + case D3D_SIT_TBUFFER: + UNSUPPORTED( "TBuffers are not supported" ); + ResourceDesc.Type = SHADER_RESOURCE_TYPE_UNKNOWN; + break; + + case D3D_SIT_TEXTURE: + ResourceDesc.Type = (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV); + break; + + case D3D_SIT_SAMPLER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; + break; + + case D3D_SIT_UAV_RWTYPED: + ResourceDesc.Type = (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV); + break; + + case D3D_SIT_STRUCTURED: + case D3D_SIT_BYTEADDRESS: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; + break; + + case D3D_SIT_UAV_RWSTRUCTURED: + case D3D_SIT_UAV_RWBYTEADDRESS: + case D3D_SIT_UAV_APPEND_STRUCTURED: + case D3D_SIT_UAV_CONSUME_STRUCTURED: + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; + break; + + default: + UNEXPECTED("Unknown input type"); } - ); + } + return ResourceDesc; +} + +size_t ShaderResources::GetHash()const +{ + size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV(), GetNumSamplers()); + for (Uint32 n=0; n < m_TotalResources; ++n) + { + const auto& Res = GetResAttribs(n, m_TotalResources, 0); + HashCombine(hash, Res); + } return hash; } -- cgit v1.2.3