From f8491bc2e3bd00dff8d86ad7f3da266005e01483 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Tue, 26 Jan 2021 10:13:23 +0300 Subject: added immutable samplers to descriptor set layout, fixed PRS tests --- .../include/PipelineResourceSignatureVkImpl.hpp | 33 +++++++++++++---- .../GraphicsEngineVulkan/src/PipelineLayoutVk.cpp | 17 +++++++++ .../src/PipelineResourceSignatureVkImpl.cpp | 42 ++++++++++++++++++---- .../src/PipelineStateVkImpl.cpp | 11 ++++++ 4 files changed, 90 insertions(+), 13 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp index 4bdb1865..3dfb7a4b 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp @@ -83,6 +83,7 @@ public: Uint32 GetDynamicStorageBufferCount() const { return m_DynamicStorageBufferCount; } Uint32 GetNumDescriptorSets() const; + SHADER_TYPE GetActiveShaderStages() const { return m_ShaderStages; } Uint32 GetNumShaderStages() const { return m_NumShaderStages; } SHADER_TYPE GetShaderStageType(Uint32 StageIndex) const; @@ -92,16 +93,15 @@ public: SRB = 1 // in SRB }; - // sizeof(ResourceAttribs) == 12, x64 + // sizeof(ResourceAttribs) == 16, x64 struct ResourceAttribs { private: static constexpr Uint32 _DescrTypeBits = 4; static constexpr Uint32 _DescrSetBits = 1; static constexpr Uint32 _BindingIndexBits = 16; - static constexpr Uint32 _SamplerIndBits = 10; + static constexpr Uint32 _SamplerIndBits = 16; static constexpr Uint32 _SamplerAssignedBits = 1; - static_assert((_DescrTypeBits + _DescrSetBits + _BindingIndexBits + _SamplerIndBits + _SamplerAssignedBits) % 8 == 0, "Fields are not properly packed"); static_assert((1u << _DescrTypeBits) >= static_cast(DescriptorType::Count), "Not enough bits to store DescriptorType values"); static_assert((1u << _DescrSetBits) >= MAX_DESCR_SET_PER_SIGNATURE, "Not enough bits to store descriptor set index"); @@ -164,6 +164,28 @@ public: return m_Desc.Resources[ResIndex]; } + struct ImmutableSamplerAttribs + { + RefCntAutoPtr Ptr; + Uint32 DescrSet : 16; + Uint32 BindingIndex : 16; + + ImmutableSamplerAttribs() : + DescrSet{~0u}, BindingIndex{~0u} {} + }; + + const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const + { + VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers); + return m_ImmutableSamplers[SampIndex]; + } + + const ImmutableSamplerDesc& GetImmutableSamplerDesc(Uint32 SampIndex) const + { + VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers); + return m_Desc.ImmutableSamplers[SampIndex]; + } + VkDescriptorSetLayout GetStaticVkDescriptorSetLayout() const { return m_VkDescSetLayouts[0]; } VkDescriptorSetLayout GetDynamicVkDescriptorSetLayout() const { return m_VkDescSetLayouts[1]; } @@ -275,10 +297,7 @@ private: ShaderResourceCacheVk* m_pResourceCache = nullptr; ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages] - - using ImmutableSamplerPtrType = RefCntAutoPtr; - - ImmutableSamplerPtrType* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers] + ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers] SRBMemoryAllocator m_SRBMemAllocator; }; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp index 7d1d2c7c..969fe16e 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp @@ -33,6 +33,7 @@ #include "PipelineLayoutVk.hpp" #include "RenderDeviceVkImpl.hpp" #include "VulkanTypeConversions.hpp" +#include "StringTools.hpp" namespace Diligent { @@ -175,6 +176,22 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso Info.Type = ResDesc.ResourceType; Info.BindingIndex = Attr.BindingIndex; Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet; + Info.Signature = pSignature; + return true; + } + } + + for (Uint32 s = 0, SampCount = pSignature->GetImmutableSamplerCount(); s < SampCount; ++s) + { + const auto& Desc = pSignature->GetImmutableSamplerDesc(s); + const auto& Attr = pSignature->GetImmutableSamplerAttribs(s); + + if (Attr.Ptr && (Desc.ShaderStages & Stage) && StreqSuff(Name, Desc.SamplerOrTextureName, pSignature->GetCombinedSamplerSuffix())) + { + Info.Type = SHADER_RESOURCE_TYPE_SAMPLER; + Info.BindingIndex = Attr.BindingIndex; + Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet; + Info.Signature = pSignature; return true; } } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp index d3426240..b51d74b6 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp @@ -283,7 +283,7 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount // Reserve at least 1 element because m_pResourceAttribs must hold a pointer to memory MemPool.AddSpace(std::max(1u, Desc.NumResources)); - MemPool.AddSpace(Desc.NumImmutableSamplers); + MemPool.AddSpace(Desc.NumImmutableSamplers); ReserveSpaceForDescription(MemPool, Desc); @@ -335,7 +335,7 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount MemPool.Reserve(); m_pResourceAttribs = MemPool.Allocate(std::max(1u, m_Desc.NumResources)); - m_ImmutableSamplers = MemPool.ConstructArray(m_Desc.NumImmutableSamplers); + m_ImmutableSamplers = MemPool.ConstructArray(m_Desc.NumImmutableSamplers); // The memory is now owned by PipelineResourceSignatureVkImpl and will be freed by Destruct(). auto* Ptr = MemPool.ReleaseOwnership(); @@ -457,10 +457,10 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache { auto& ImmutableSampler = m_ImmutableSamplers[SrcImmutableSamplerInd]; const auto& ImmutableSamplerDesc = m_Desc.ImmutableSamplers[SrcImmutableSamplerInd].Desc; - if (!ImmutableSampler) - GetDevice()->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); + if (!ImmutableSampler.Ptr) + GetDevice()->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler.Ptr); - pVkImmutableSamplers = TempAllocator.ConstructArray(ResDesc.ArraySize, ImmutableSampler.RawPtr()->GetVkSampler()); + pVkImmutableSamplers = TempAllocator.ConstructArray(ResDesc.ArraySize, ImmutableSampler.Ptr.RawPtr()->GetVkSampler()); } } @@ -512,6 +512,36 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache VERIFY_EXPR(BindingIndices[CACHE_GROUP_DYN_SB_DYN_VAR] == BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR]); VERIFY_EXPR(BindingIndices[CACHE_GROUP_OTHER_DYN_VAR] == BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR] + BindingCount[CACHE_GROUP_OTHER_DYN_VAR]); + // Add immutable samplers that is not exist in m_Desc.Resources + // If static/mutable descriptor set layout is empty, then add samplers to dynamic layout. + for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i) + { + auto& ImmutableSampler = m_ImmutableSamplers[i]; + const auto& SamplerDesc = m_Desc.ImmutableSamplers[i]; + const Uint32 SetIdx = (DSMapping[0] < MAX_DESCR_SET_PER_SIGNATURE ? 0 : 1); + auto& BindingIndex = BindingIndices[SetIdx * 3 + 2]; + + if (ImmutableSampler.Ptr) + continue; + + GetDevice()->CreateSampler(SamplerDesc.Desc, &ImmutableSampler.Ptr); + + ImmutableSampler.DescrSet = DSMapping[SetIdx]; + ImmutableSampler.BindingIndex = BindingIndex; + + VERIFY_EXPR(ImmutableSampler.BindingIndex == BindingIndex); + ++BindingIndex; + + vkSetLayoutBindings[SetIdx].emplace_back(); + auto& vkSetLayoutBinding = vkSetLayoutBindings[SetIdx].back(); + + vkSetLayoutBinding.binding = ImmutableSampler.BindingIndex; + vkSetLayoutBinding.descriptorCount = 1; + vkSetLayoutBinding.stageFlags = ShaderTypesToVkShaderStageFlags(SamplerDesc.ShaderStages); + vkSetLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + vkSetLayoutBinding.pImmutableSamplers = TempAllocator.Construct(ImmutableSampler.Ptr.RawPtr()->GetVkSampler()); + } + if (m_Desc.SRBAllocationGranularity > 1) { std::array ShaderVariableDataSizes = {}; @@ -647,7 +677,7 @@ void PipelineResourceSignatureVkImpl::Destruct() for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i) { - m_ImmutableSamplers[i].~ImmutableSamplerPtrType(); + m_ImmutableSamplers[i].~ImmutableSamplerAttribs(); } m_ImmutableSamplers = nullptr; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index dc184e1b..41585909 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -857,6 +857,17 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea "' that is not present in any pipeline resource signature that is used to create pipeline state '", m_Desc.Name, "'."); } + + SHADER_RESOURCE_TYPE Type; + PIPELINE_RESOURCE_FLAGS Flags; + GetShaderResourceTypeAndFlags(Res.Type, Type, Flags); + if (Type != Info.Type) + { + LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Res.Name, + "' and type '", GetShaderResourceTypeLiteralName(Type), "' that is not compatible with type '", + GetShaderResourceTypeLiteralName(Info.Type), "' in pipeline resource signature '", Info.Signature->GetDesc().Name, "'."); + } + SPIRV[Res.BindingDecorationOffset] = Info.BindingIndex; SPIRV[Res.DescriptorSetDecorationOffset] = Info.DescrSetIndex; }); -- cgit v1.2.3