diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-12-20 18:30:28 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-12-20 18:30:28 +0000 |
| commit | 9f75d12fe69fec0f2e0694d9b157dc283a888cf9 (patch) | |
| tree | 68e6b15591d1daa8fa6bb80a709842069eb94d80 /Graphics/GraphicsEngineD3D12 | |
| parent | DX compiler test: removed -Qembed_debug argument to fix compilation on CI server (diff) | |
| download | DiligentCore-9f75d12fe69fec0f2e0694d9b157dc283a888cf9.tar.gz DiligentCore-9f75d12fe69fec0f2e0694d9b157dc283a888cf9.zip | |
ShaderResourceLayoutD3D12: fixed problem with static resources for ray tracing shaders
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
5 files changed, 388 insertions, 308 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index c8ba2fa2..e29371a6 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -513,7 +513,7 @@ public: struct ImmutableSamplerAttribs { ImmutableSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast<UINT>(-1); + UINT ShaderRegister = ~UINT{0}; UINT ArraySize = 0; UINT RegisterSpace = 0; D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast<D3D12_SHADER_VISIBILITY>(-1); diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index de0ecc29..741b49e6 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -119,29 +119,31 @@ namespace Diligent class ShaderResourceLayoutD3D12 final { public: - explicit ShaderResourceLayoutD3D12(IObject& Owner) noexcept : - m_Owner{Owner} + explicit ShaderResourceLayoutD3D12(IObject& Owner, ID3D12Device* pd3d12Device) noexcept : + m_Owner{Owner}, + m_pd3d12Device{pd3d12Device} { #if defined(_MSC_VER) && defined(_WIN64) static_assert(sizeof(*this) == 56, "Unexpected sizeof(ShaderResourceLayoutD3D12)"); #endif } - // There are two modes a layout can be initialized: - // - initialize static resource layout and initialize shader resource cache to hold static resources - // - initialize reference layouts that address all types of resources (static, mutable, dynamic). - // Root indices and descriptor table offsets are assigned during the initialization; - // no shader resource cache is provided - void Initialize(ID3D12Device* pd3d12Device, - PIPELINE_TYPE PipelineType, - const PipelineResourceLayoutDesc& ResourceLayout, - const std::vector<ShaderD3D12Impl*>& Shaders, + // Initializes reference layouts that address all types of resources (static, mutable, dynamic). + // Root indices and descriptor table offsets are assigned during the initialization; + void Initialize(PIPELINE_TYPE PipelineType, + const PipelineResourceLayoutDesc& ResourceLayout, + const std::vector<ShaderD3D12Impl*>& Shaders, + IMemoryAllocator& LayoutDataAllocator, + class RootSignatureBuilder& RootSgnBldr, + class LocalRootSignature* pLocalRootSig); + + // Copies the specified variable types from the source layout and initializes the + // resource cache. + void Initialize(const ShaderResourceLayoutD3D12& SrcLayout, IMemoryAllocator& LayoutDataAllocator, - const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, + const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12* pResourceCache, - class RootSignatureBuilder* pRootSig, - class LocalRootSignature* pLocalRootSig); + ShaderResourceCacheD3D12& ResourceCache); // clang-format off ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; @@ -156,33 +158,31 @@ public: struct D3D12Resource final { // clang-format off + D3D12Resource (const D3D12Resource&) = delete; + D3D12Resource ( D3D12Resource&&) = delete; + D3D12Resource& operator=(const D3D12Resource&) = delete; + D3D12Resource& operator=( D3D12Resource&&) = delete; + // clang-format on - D3D12Resource (const D3D12Resource&) = delete; - D3D12Resource ( D3D12Resource&&) = delete; - D3D12Resource& operator = (const D3D12Resource&) = delete; - D3D12Resource& operator = ( D3D12Resource&&) = delete; - - static constexpr const Uint32 ResourceTypeBits = 3; - static constexpr const Uint32 VariableTypeBits = 2; - static constexpr const Uint32 RootIndexBits = 32 - ResourceTypeBits - VariableTypeBits; + static constexpr Uint32 ResourceTypeBits = 3; + static constexpr Uint32 VariableTypeBits = 2; + static constexpr Uint32 RootIndexBits = 32 - ResourceTypeBits - VariableTypeBits; - static constexpr const Uint32 InvalidRootIndex = (1U << RootIndexBits) - 1U; - static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1U; + static constexpr Uint32 InvalidRootIndex = (1U << RootIndexBits) - 1U; + static constexpr Uint32 MaxRootIndex = InvalidRootIndex - 1U; - static constexpr const Uint32 InvalidOffset = static_cast<Uint32>(-1); + static constexpr Uint32 InvalidOffset = static_cast<Uint32>(-1); - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_RESOURCE_VARIABLE_TYPE"); + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_RESOURCE_VARIABLE_TYPE"); static_assert(static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "Not enough bits to represent CachedResourceType"); -/* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout; -/* 8 */ const D3DShaderResourceAttribs Attribs; -/*24 */ const Uint32 OffsetFromTableStart; -/*28.0*/ const Uint32 ResourceType : ResourceTypeBits; // | 0 1 2 | -/*28.3*/ const Uint32 VariableType : VariableTypeBits; // | 3 4 | -/*28.5*/ const Uint32 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | -/*32 */ // End of data - - // clang-format on + /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout; + /* 8 */ const D3DShaderResourceAttribs Attribs; + /*24 */ const Uint32 OffsetFromTableStart; + /*28.0*/ const Uint32 ResourceType : ResourceTypeBits; // | 0 1 2 | + /*28.3*/ const Uint32 VariableType : VariableTypeBits; // | 3 4 | + /*28.5*/ const Uint32 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | + /*32 */ // End of data D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, StringPool& _StringPool, @@ -305,6 +305,8 @@ private: const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv); + Uint32 FindSamplerByName(const char* SamplerName) const; + const Char* GetShaderName() const { return GetStringPoolData(); @@ -349,6 +351,12 @@ private: VERIFY_EXPR(r < GetCbvSrvUavCount(VarType)); return GetResource(GetSrvCbvUavOffset(VarType, r)); } + const D3D12Resource& GetSrvCbvUav(Uint32 r) const + { + VERIFY_EXPR(r < GetTotalSrvCbvUavCount()); + return GetResource(m_CbvSrvUavOffsets[0] + r); + } + Uint32 GetSamplerOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) const { diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 49d9440d..10c45f1d 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -328,9 +328,11 @@ TBindingMapPerStage ExtractResourceBindingMap(const RootSignatureBuilder& if (LayoutIdx < 0) continue; - VERIFY_EXPR(ImtblSmplr.Name.length() > 0); if (ImtblSmplr.Name.empty()) + { + UNEXPECTED("Immutable sampler name is empty"); continue; + } auto& BindingMap = BindingMapPerStage[ShaderIdx]; BindingMap.emplace(HashMapStringKey{ImtblSmplr.Name.c_str()}, ImtblSmplr.ShaderRegister); @@ -389,7 +391,8 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create VERIFY_EXPR(Ptr == m_pStaticResourceCaches); (void)Ptr; - m_pShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutD3D12>(NumShaderStages * 2, std::ref(*this)); + auto* const pd3d12Device = GetDevice()->GetD3D12Device(); + m_pShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutD3D12>(NumShaderStages * 2, std::ref(*this), pd3d12Device); m_pStaticVarManagers = MemPool.Allocate<ShaderVariableManagerD3D12>(NumShaderStages); for (Uint32 s = 0; s < NumShaderStages; ++s) @@ -418,7 +421,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* TShaderStages ShaderStages; InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device(); if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) { const auto& GraphicsPipeline = GetGraphicsPipelineDesc(); @@ -624,7 +627,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* TShaderStages ShaderStages; InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device(); D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; @@ -803,31 +806,26 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s); + // Initialize general layout m_pShaderResourceLayouts[s].Initialize( - pd3d12Device, m_Desc.PipelineType, ResourceLayout, Shaders, GetRawAllocator(), - nullptr, - 0, - nullptr, - &RootSigBuilder, + RootSigBuilder, pLocalRoot // ); + // Initialize static resource layout and the cache. We must do this after + // general layout is initialized, because we will use the bind points that + // may have been assigned (for ray tracing shaders). const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; m_pShaderResourceLayouts[GetNumShaderStages() + s].Initialize( - pd3d12Device, - m_Desc.PipelineType, - ResourceLayout, - Shaders, + m_pShaderResourceLayouts[s], GetRawAllocator(), StaticVarType, _countof(StaticVarType), - m_pStaticResourceCaches + s, - nullptr, - pLocalRoot // + m_pStaticResourceCaches[s] // ); m_pStaticVarManagers[s].Initialize( diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 336c8a94..f6e9f2c6 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -192,15 +192,26 @@ void RootSignatureBuilder::InitImmutableSampler(SHADER_TYPE if (ImtblSmplr.ShaderVisibility == ShaderVisibility && StreqSuff(SamplerName, ImtblSmplr.SamplerDesc.SamplerOrTextureName, SamplerSuffix)) { - ImtblSmplr.ShaderRegister = SamplerAttribs.BindPoint; - ImtblSmplr.ArraySize = SamplerAttribs.BindCount; - ImtblSmplr.RegisterSpace = 0; - ImtblSmplr.Name = SamplerName; + if (ImtblSmplr.ShaderRegister == ~UINT{0}) + { + ImtblSmplr.ShaderRegister = SamplerAttribs.BindPoint; + ImtblSmplr.ArraySize = SamplerAttribs.BindCount; + ImtblSmplr.RegisterSpace = 0; + ImtblSmplr.Name = SamplerName; - if (ShaderType & RAY_TRACING_SHADER_TYPES) + if (ShaderType & RAY_TRACING_SHADER_TYPES) + { + ImtblSmplr.ShaderRegister = m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER]; + m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER] += SamplerAttribs.BindCount; + } + } + else { - ImtblSmplr.ShaderRegister = m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER]; - m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER] += SamplerAttribs.BindCount; + // Do not allocate another register if the sampler has already been processed + VERIFY(ShaderType & RAY_TRACING_SHADER_TYPES, "Multiple samplers with the same name can only be encountered in ray tracing shaders"); + DEV_CHECK_ERR(ImtblSmplr.ArraySize == SamplerAttribs.BindCount, "Immutable sampler '", SamplerName, + "' has already been found, but its previous array size (", ImtblSmplr.ArraySize, + ") does not match the new array size (", SamplerAttribs.BindCount, ")"); } SamplerFound = true; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 41abfd9e..fc42e273 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -131,323 +131,250 @@ StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Resource-Layouts-in-a-Pipeline-State -void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device, - PIPELINE_TYPE PipelineType, - const PipelineResourceLayoutDesc& ResourceLayout, - const std::vector<ShaderD3D12Impl*>& Shaders, - IMemoryAllocator& LayoutDataAllocator, - const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12* pResourceCache, - RootSignatureBuilder* pRootSig, - LocalRootSignature* pLocalRootSig) +void ShaderResourceLayoutD3D12::Initialize(PIPELINE_TYPE PipelineType, + const PipelineResourceLayoutDesc& ResourceLayout, + const std::vector<ShaderD3D12Impl*>& Shaders, + IMemoryAllocator& LayoutDataAllocator, + class RootSignatureBuilder& RootSgnBldr, + LocalRootSignature* pLocalRootSig) { - m_pd3d12Device = pd3d12Device; - - VERIFY_EXPR((pResourceCache != nullptr) ^ (pRootSig != nullptr)); VERIFY_EXPR(!Shaders.empty()); - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); + m_ShaderType = Shaders[0]->GetDesc().ShaderType; std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CbvSrvUavCount = {}; std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> SamplerCount = {}; - // Maps resource name to its index in m_ResourceBuffer + // Mapping from the resource name to its index in m_ResourceBuffer std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher> ResourceNameToIndex; - // Count the number of resources to allocate all needed memory - m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); - m_ShaderType = Shaders[0]->GetDesc().ShaderType; - // Construct shader or shader group name const auto ShaderName = GetShaderGroupName(Shaders); - size_t StringPoolSize = ShaderName.length() + 1; + // Start calculating the pool size required to keep all strings in the layout + size_t StringPoolSize = StringPool::GetRequiredReserveSize(ShaderName); static constexpr Uint32 InvalidResourceIndex = ~0u; - for (auto* pShader : Shaders) + // Count resources to calculate the required memory size. + for (auto* pShader : Shaders) // Iterate over all shaders in the stage. { - auto pResources = pShader->GetShaderResources(); - VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); - const auto HandleCbvSrvUav = [&](const auto& Res, Uint32) // + const auto& ShaderRes = *pShader->GetShaderResources(); + VERIFY_EXPR(ShaderRes.GetShaderType() == m_ShaderType); + + auto AddResource = [&](const D3DShaderResourceAttribs& Res, Uint32 /*Index*/ = 0) // { - auto VarType = pResources->FindVariableType(Res, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) + const auto IsNewResource = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second; + if (IsNewResource) { - if (pLocalRootSig && pLocalRootSig->SetOrMerge(Res)) - return; - - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second; - if (IsUniqueName) - { - StringPoolSize += strlen(Res.Name) + 1; + const auto VarType = ShaderRes.FindVariableType(Res, ResourceLayout); + StringPoolSize += StringPool::GetRequiredReserveSize(Res.Name); + if (Res.GetInputType() == D3D_SIT_SAMPLER) + ++SamplerCount[VarType]; + else ++CbvSrvUavCount[VarType]; - } } + return IsNewResource; }; - pResources->ProcessResources( - HandleCbvSrvUav, + ShaderRes.ProcessResources( + [&](const auto& CB, Uint32) // + { + if (pLocalRootSig != nullptr && pLocalRootSig->SetOrMerge(CB)) + return; + + AddResource(CB); + }, [&](const D3DShaderResourceAttribs& Sam, Uint32) // { - auto VarType = pResources->FindVariableType(Sam, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - constexpr bool LogImtblSamplerArrayError = true; + constexpr bool LogImtblSamplerArrayError = true; - auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); - // Skip immutable samplers - if (ImtblSamplerInd < 0) - { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, InvalidResourceIndex).second; - if (IsUniqueName) - { - StringPoolSize += strlen(Sam.Name) + 1; - ++SamplerCount[VarType]; - } - } - } + const auto ImtblSamplerInd = ShaderRes.FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + // Skip immutable samplers + if (ImtblSamplerInd >= 0) + return; + + AddResource(Sam); }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // { - auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) + if (AddResource(TexSRV)) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, InvalidResourceIndex).second; - if (IsUniqueName) +#if DILIGENT_DEVELOPMENT + if (TexSRV.IsCombinedWithSampler()) { - StringPoolSize += strlen(TexSRV.Name) + 1; - ++CbvSrvUavCount[VarType]; - if (TexSRV.IsCombinedWithSampler()) - { - const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); - auto SamplerVarType = pResources->FindVariableType(SamplerAttribs, ResourceLayout); - DEV_CHECK_ERR(SamplerVarType == VarType, - "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), - ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); - (void)SamplerVarType; - } + const auto& SamplerAttribs = ShaderRes.GetCombinedSampler(TexSRV); + auto SamplerVarType = ShaderRes.FindVariableType(SamplerAttribs, ResourceLayout); + const auto TexSrvVarType = ShaderRes.FindVariableType(TexSRV, ResourceLayout); + DEV_CHECK_ERR(SamplerVarType == TexSrvVarType, + "The type (", GetShaderVariableTypeLiteralName(TexSrvVarType), ") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), + ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); } +#endif } }, - HandleCbvSrvUav, - HandleCbvSrvUav, - HandleCbvSrvUav, - HandleCbvSrvUav); + AddResource, + AddResource, + AddResource, + AddResource // + ); } auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize); stringPool.CopyString(ShaderName); - std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {}; - std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {}; - std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> StaticResCacheTblSizes = {}; + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {}; + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {}; - auto AddResource = [&](const D3DShaderResourceAttribs& Attribs, - CachedResourceType ResType, - SHADER_RESOURCE_VARIABLE_TYPE VarType, - Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) // + for (auto* pShader : Shaders) { - auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); - VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); + const auto& ShaderRes = *pShader->GetShaderResources(); - if (ResIter->second == InvalidResourceIndex) + auto InitResource = [&](const D3DShaderResourceAttribs& Attribs, + CachedResourceType ResType, + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) // { - Uint32 RootIndex = D3D12Resource::InvalidRootIndex; - Uint32 Offset = D3D12Resource::InvalidOffset; - Uint32 BindPoint = D3DShaderResourceAttribs::InvalidBindPoint; + const auto VarType = ShaderRes.FindVariableType(Attribs, ResourceLayout); - D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); + auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); + VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (pRootSig) + if (ResIter->second == InvalidResourceIndex) { - pRootSig->AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, BindPoint, RootIndex, Offset); + Uint32 RootIndex = D3D12Resource::InvalidRootIndex; + Uint32 Offset = D3D12Resource::InvalidOffset; + Uint32 BindPoint = D3DShaderResourceAttribs::InvalidBindPoint; + + D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); + + RootSgnBldr.AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, BindPoint, RootIndex, Offset); VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit"); + VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); VERIFY(BindPoint <= D3DShaderResourceAttribs::MaxBindPoint, "Bind point excceeds allowed limit"); + VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); + + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId + Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? + GetSamplerOffset(VarType, CurrSampler[VarType]++) : + GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); + ResIter->second = ResOffset; + auto& NewResource = GetResource(ResOffset); + ::new (&NewResource) D3D12Resource // + { + *this, + stringPool, + Attribs, + SamplerId, + VarType, + ResType, + BindPoint, + RootIndex, + Offset // + }; } else { - // If root signature is not provided - use artifial root signature to store - // static shader resources: - // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV (0) - // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1) - // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2) - // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3) - - // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources - - VERIFY_EXPR(pResourceCache != nullptr); - - RootIndex = DescriptorRangeType; - Offset = Attribs.BindPoint; - BindPoint = Attribs.BindPoint; - // Resources in the static resource cache are indexed by the bind point - StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + Attribs.BindCount); + // Merge with existing + auto& ExistingRes = GetResource(ResIter->second); + VERIFY(ExistingRes.VariableType == VarType, + "The type of variable '", Attribs.Name, "' does not match the type determined for previous shaders. This appears to be a bug."); + + DEV_CHECK_ERR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType(), + "Shader variable '", Attribs.Name, + "' exists in multiple shaders from the same shader stage, but its input type is not consistent between " + "shaders. All variables with the same name from the same shader stage must have the same input type."); + + DEV_CHECK_ERR(ExistingRes.Attribs.GetSRVDimension() == Attribs.GetSRVDimension(), + "Shader variable '", Attribs.Name, + "' exists in multiple shaders from the same shader stage, but its SRV dimension is not consistent between " + "shaders. All variables with the same name from the same shader stage must have the same SRV dimension."); + + DEV_CHECK_ERR(ExistingRes.Attribs.BindCount == Attribs.BindCount, + "Shader variable '", Attribs.Name, + "' exists in multiple shaders from the same shader stage, but its array size is not consistent between " + "shaders. All variables with the same name from the same shader stage must have the same array size."); } - VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); - VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); - - // Immutable samplers are never copied, and SamplerId == InvalidSamplerId - Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? - GetSamplerOffset(VarType, CurrSampler[VarType]++) : - GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); - ResIter->second = ResOffset; - auto& NewResource = GetResource(ResOffset); - ::new (&NewResource) D3D12Resource // - { - *this, - stringPool, - Attribs, - SamplerId, - VarType, - ResType, - BindPoint, - RootIndex, - Offset // - }; - } - else - { - // Merge with existing - auto& ExistingRes = GetResource(ResIter->second); - VERIFY(ExistingRes.VariableType == VarType, - "The type of variable '", Attribs.Name, "' does not match the type determined for previous shaders. This appears to be a bug."); - - DEV_CHECK_ERR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType(), - "Shader variable '", Attribs.Name, - "' exists in multiple shaders from the same shader stage, but its input type is not consistent between " - "shaders. All variables with the same name from the same shader stage must have the same input type."); - - DEV_CHECK_ERR(ExistingRes.Attribs.GetSRVDimension() == Attribs.GetSRVDimension(), - "Shader variable '", Attribs.Name, - "' exists in multiple shaders from the same shader stage, but its SRV dimension is not consistent between " - "shaders. All variables with the same name from the same shader stage must have the same SRV dimension."); - - DEV_CHECK_ERR(ExistingRes.Attribs.BindCount == Attribs.BindCount, - "Shader variable '", Attribs.Name, - "' exists in multiple shaders from the same shader stage, but its array size is not consistent between " - "shaders. All variables with the same name from the same shader stage must have the same array size."); - - VERIFY_EXPR(ExistingRes.Attribs.BindPoint == Attribs.BindPoint || - Attribs.BindPoint == D3DShaderResourceAttribs::InvalidBindPoint); - } - }; + }; - for (auto* pShader : Shaders) - { - auto pResources = pShader->GetShaderResources(); - pResources->ProcessResources( + ShaderRes.ProcessResources( [&](const D3DShaderResourceAttribs& CB, Uint32) // { - if (pLocalRootSig && pLocalRootSig->SetOrMerge(CB)) + if (pLocalRootSig != nullptr && pLocalRootSig->SetOrMerge(CB)) return; - auto VarType = pResources->FindVariableType(CB, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(CB, CachedResourceType::CBV, VarType); + InitResource(CB, CachedResourceType::CBV); }, [&](const D3DShaderResourceAttribs& Sam, Uint32) // { - auto VarType = pResources->FindVariableType(Sam, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) + // The errors (if any) have already been logged when counting the resources + constexpr bool LogImtblSamplerArrayError = false; + + const auto ImtblSamplerInd = ShaderRes.FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { - // The error (if any) have already been logged when counting the resources - constexpr bool LogImtblSamplerArrayError = false; - const auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); - if (ImtblSamplerInd >= 0) - { - if (pRootSig != nullptr) - pRootSig->InitImmutableSampler(pResources->GetShaderType(), Sam.Name, pResources->GetCombinedSamplerSuffix(), Sam); - } - else - { - AddResource(Sam, CachedResourceType::Sampler, VarType); - } + // Note that there may be multiple immutable samplers with the same name in different shaders that + // are assigned to different registers. This not a problem, because InitImmutableSampler allocates new + // register only first time the sampler is encountered. + RootSgnBldr.InitImmutableSampler(ShaderRes.GetShaderType(), Sam.Name, ShaderRes.GetCombinedSamplerSuffix(), Sam); + } + else + { + InitResource(Sam, CachedResourceType::Sampler); } }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // { - auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); - VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); + VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); - Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; - if (TexSRV.IsCombinedWithSampler()) + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; + if (TexSRV.IsCombinedWithSampler()) + { + const auto& SamplerAttribs = ShaderRes.GetCombinedSampler(TexSRV); + const auto SamplerVarType = ShaderRes.FindVariableType(SamplerAttribs, ResourceLayout); + const auto TexSrvVarType = ShaderRes.FindVariableType(TexSRV, ResourceLayout); + DEV_CHECK_ERR(SamplerVarType == TexSrvVarType, + "The type (", GetShaderVariableTypeLiteralName(TexSrvVarType), ") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), + ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); + + // The errors (if any) have already been logged when counting the resources + constexpr bool LogImtblSamplerArrayError = false; + const auto ImtblSamplerInd = ShaderRes.FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { - const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); - auto SamplerVarType = pResources->FindVariableType(SamplerAttribs, ResourceLayout); - DEV_CHECK_ERR(SamplerVarType == VarType, - "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), - ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); - - // The error (if any) have already been logged when counting the resources - constexpr bool LogImtblSamplerArrayError = false; - const auto ImtblSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); - if (ImtblSamplerInd >= 0) - { - // Immutable samplers are never copied, and SamplerId == InvalidSamplerId -#ifdef DILIGENT_DEBUG - auto SamplerCount = GetTotalSamplerCount(); - for (Uint32 s = 0; s < SamplerCount; ++s) - { - const auto& Sampler = GetSampler(s); - if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0) - LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); - } -#endif - } - else - { - auto SamplerCount = GetTotalSamplerCount(); - bool SamplerFound = false; - for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) - { - const auto& Sampler = GetSampler(SamplerId); - SamplerFound = strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0; - if (SamplerFound) - break; - } - - if (!SamplerFound) - { - LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug."); - SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; - } - VERIFY(SamplerId <= D3DShaderResourceAttribs::MaxSamplerId, "Sampler index excceeds allowed limit"); - } + // Immutable samplers are never copied, and should not be found in resources + DEV_CHECK_ERR(FindSamplerByName(SamplerAttribs.Name) == D3DShaderResourceAttribs::InvalidSamplerId, + "Immutable sampler '", SamplerAttribs.Name, "' was found among shader resources. This seems to be a bug"); + } + else + { + SamplerId = FindSamplerByName(SamplerAttribs.Name); + DEV_CHECK_ERR(SamplerId != D3DShaderResourceAttribs::InvalidSamplerId, + "Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, + "' in the list of already created shader resources. This seems to be a bug."); } - AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId); } + InitResource(TexSRV, CachedResourceType::TexSRV, SamplerId); }, [&](const D3DShaderResourceAttribs& TexUAV, Uint32) // { - auto VarType = pResources->FindVariableType(TexUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(TexUAV, CachedResourceType::TexUAV, VarType); + InitResource(TexUAV, CachedResourceType::TexUAV); }, [&](const D3DShaderResourceAttribs& BufSRV, Uint32) // { - auto VarType = pResources->FindVariableType(BufSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(BufSRV, CachedResourceType::BufSRV, VarType); + InitResource(BufSRV, CachedResourceType::BufSRV); }, [&](const D3DShaderResourceAttribs& BufUAV, Uint32) // { - auto VarType = pResources->FindVariableType(BufUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(BufUAV, CachedResourceType::BufUAV, VarType); + InitResource(BufUAV, CachedResourceType::BufUAV); }, [&](const D3DShaderResourceAttribs& AccelStruct, Uint32) // { - auto VarType = pResources->FindVariableType(AccelStruct, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(AccelStruct, CachedResourceType::AccelStruct, VarType); + InitResource(AccelStruct, CachedResourceType::AccelStruct); } // ); } @@ -460,23 +387,142 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* VERIFY(CurrSampler[VarType] == SamplerCount[VarType], "Not all Samplers are initialized, which result in a crash when dtor is called"); } #endif +} - if (pResourceCache) +void ShaderResourceLayoutD3D12::Initialize(const ShaderResourceLayoutD3D12& SrcLayout, + IMemoryAllocator& LayoutDataAllocator, + const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12& ResourceCache) +{ + m_IsUsingSeparateSamplers = SrcLayout.m_IsUsingSeparateSamplers; + m_ShaderType = SrcLayout.m_ShaderType; + + const auto AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const auto* const ShaderName = SrcLayout.GetShaderName(); + + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CbvSrvUavCount = {}; + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> SamplerCount = {}; + + size_t StringPoolSize = StringPool::GetRequiredReserveSize(ShaderName); + + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; + VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1)) + { + if (!IsAllowedType(VarType, AllowedTypeBits)) + continue; + + CbvSrvUavCount[VarType] = SrcLayout.GetCbvSrvUavCount(VarType); + SamplerCount[VarType] = SrcLayout.GetSamplerCount(VarType); + + for (Uint32 i = 0; i < CbvSrvUavCount[VarType]; ++i) + StringPoolSize += StringPool::GetRequiredReserveSize(SrcLayout.GetSrvCbvUav(VarType, i).Attribs.Name); + for (Uint32 i = 0; i < SamplerCount[VarType]; ++i) + StringPoolSize += StringPool::GetRequiredReserveSize(SrcLayout.GetSampler(VarType, i).Attribs.Name); + } + + auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize); + stringPool.CopyString(ShaderName); + + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {}; + std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {}; + + std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> StaticResCacheTblSizes = {}; + + auto InitResource = [&](const D3D12Resource& SrcRes, + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) // { - // Initialize resource cache to store static resources - // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-the-Cache-for-Static-Shader-Resources - // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Objects - VERIFY_EXPR(pRootSig == nullptr); - pResourceCache->Initialize(GetRawAllocator(), static_cast<Uint32>(StaticResCacheTblSizes.size()), StaticResCacheTblSizes.data()); + const auto ResType = SrcRes.GetResType(); + const auto VarType = SrcRes.GetVariableType(); + + const Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? + GetSamplerOffset(VarType, CurrSampler[VarType]++) : + GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); + + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources + // Use artifial root signature: + // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV (0) + // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1) + // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2) + // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3) + const Uint32 RootIndex = GetDescriptorRangeType(ResType); + const Uint32 Offset = SrcRes.Attribs.BindPoint; // Offset is the same as the bind point + + auto& NewResource = GetResource(ResOffset); + ::new (&NewResource) D3D12Resource // + { + *this, + stringPool, + SrcRes.Attribs, + SamplerId, + VarType, + ResType, + SrcRes.Attribs.BindPoint, + RootIndex, + Offset // + }; + + // Resources in the static resource cache are indexed by the bind point + StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + NewResource.Attribs.BindCount); + }; + + // Process samplers first + for (Uint32 s = 0; s < SrcLayout.GetTotalSamplerCount(); ++s) + { + const auto& SrcSmplr = SrcLayout.GetSampler(s); + if (IsAllowedType(SrcSmplr.GetVariableType(), AllowedTypeBits)) + { + InitResource(SrcSmplr); + } + } + + // Process SRVs, CBVs, UAVs + for (Uint32 res = 0; res < SrcLayout.GetTotalSrvCbvUavCount(); ++res) + { + const auto& SrcRes = SrcLayout.GetSrvCbvUav(res); + const auto VarType = SrcRes.GetVariableType(); + if (!IsAllowedType(VarType, AllowedTypeBits)) + continue; + + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; + if (SrcRes.Attribs.IsCombinedWithSampler()) + { + // If source resource is combined with the static sampler, there must also be + // a corresponding sampler in this layout. + + const auto& SrcAssignedSmplr = SrcLayout.GetAssignedSampler(SrcRes); + VERIFY(SrcAssignedSmplr.GetVariableType() == SrcRes.GetVariableType(), + "The type of the sampler does not match the type of the texture it is assigned to. This is likely a bug."); + + SamplerId = FindSamplerByName(SrcAssignedSmplr.Attribs.Name); + VERIFY(SamplerId != D3DShaderResourceAttribs::InvalidSamplerId, + "Unable to find sampler '", SrcAssignedSmplr.Attribs.Name, "' among resources. This seems to be a bug."); + } + + InitResource(SrcRes, SamplerId); + } + #ifdef DILIGENT_DEBUG - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SRV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SRV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_UAV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_UAV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_CBV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_CBV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); -#endif + VERIFY_EXPR(stringPool.GetRemainingSize() == 0); + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1)) + { + VERIFY(CurrCbvSrvUav[VarType] == CbvSrvUavCount[VarType], "Not all Srv/Cbv/Uavs are initialized, which result in a crash when dtor is called"); + VERIFY(CurrSampler[VarType] == SamplerCount[VarType], "Not all Samplers are initialized, which result in a crash when dtor is called"); } -} +#endif + // Initialize resource cache to store static resources + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-the-Cache-for-Static-Shader-Resources + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Objects + ResourceCache.Initialize(GetRawAllocator(), static_cast<Uint32>(StaticResCacheTblSizes.size()), StaticResCacheTblSizes.data()); +#ifdef DILIGENT_DEBUG + ResourceCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SRV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SRV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + ResourceCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_UAV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_UAV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + ResourceCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_CBV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_CBV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + ResourceCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); +#endif +} void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* pBuffer, ShaderResourceCacheD3D12::Resource& DstRes, @@ -686,6 +732,23 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* } } + +Uint32 ShaderResourceLayoutD3D12::FindSamplerByName(const char* SamplerName) const +{ + const auto SamplerCount = GetTotalSamplerCount(); + for (Uint32 SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) + { + const auto& Sampler = GetSampler(SamplerId); + if (strcmp(Sampler.Attribs.Name, SamplerName) == 0) + { + VERIFY(SamplerId <= D3DShaderResourceAttribs::MaxSamplerId, "Sampler index excceeds allowed limit"); + return SamplerId; + } + } + + return D3DShaderResourceAttribs::InvalidSamplerId; +} + const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const { VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected"); |
