diff options
| author | azhirnov <zh1dron@gmail.com> | 2021-01-26 07:13:23 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2021-01-26 07:13:23 +0000 |
| commit | f8491bc2e3bd00dff8d86ad7f3da266005e01483 (patch) | |
| tree | 5235768a948e41fc2c9516433148f5fa30372daa /Graphics | |
| parent | removed empty signature, added test for partially compatible pipeline layouts (diff) | |
| download | DiligentCore-f8491bc2e3bd00dff8d86ad7f3da266005e01483.tar.gz DiligentCore-f8491bc2e3bd00dff8d86ad7f3da266005e01483.zip | |
added immutable samplers to descriptor set layout, fixed PRS tests
Diffstat (limited to 'Graphics')
6 files changed, 109 insertions, 20 deletions
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index bded504e..af4a04ea 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -550,16 +550,19 @@ const Char* GetShaderVariableTypeLiteralName(SHADER_RESOURCE_VARIABLE_TYPE VarTy const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, bool bGetFullName) { + static_assert(SHADER_RESOURCE_TYPE_LAST == SHADER_RESOURCE_TYPE_ACCEL_STRUCT, "Please update the switch below to handle the new shader resource type"); switch (ResourceType) { // clang-format off - case SHADER_RESOURCE_TYPE_UNKNOWN: return bGetFullName ? "SHADER_RESOURCE_TYPE_UNKNOWN" : "unknown"; - case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return bGetFullName ? "SHADER_RESOURCE_TYPE_CONSTANT_BUFFER" : "constant buffer"; - case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_SRV" : "texture SRV"; - case SHADER_RESOURCE_TYPE_BUFFER_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_SRV" : "buffer SRV"; - case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_UAV" : "texture UAV"; - case SHADER_RESOURCE_TYPE_BUFFER_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_UAV" : "buffer UAV"; - case SHADER_RESOURCE_TYPE_SAMPLER: return bGetFullName ? "SHADER_RESOURCE_TYPE_SAMPLER" : "sampler"; + case SHADER_RESOURCE_TYPE_UNKNOWN: return bGetFullName ? "SHADER_RESOURCE_TYPE_UNKNOWN" : "unknown"; + case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return bGetFullName ? "SHADER_RESOURCE_TYPE_CONSTANT_BUFFER" : "constant buffer"; + case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_SRV" : "texture SRV"; + case SHADER_RESOURCE_TYPE_BUFFER_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_SRV" : "buffer SRV"; + case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_UAV" : "texture UAV"; + case SHADER_RESOURCE_TYPE_BUFFER_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_UAV" : "buffer UAV"; + case SHADER_RESOURCE_TYPE_SAMPLER: return bGetFullName ? "SHADER_RESOURCE_TYPE_SAMPLER" : "sampler"; + case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return bGetFullName ? "SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT" : "input attachment"; + case SHADER_RESOURCE_TYPE_ACCEL_STRUCT: return bGetFullName ? "SHADER_RESOURCE_TYPE_ACCEL_STRUCT" : "acceleration structure"; // clang-format on default: UNEXPECTED("Unexepcted resource type (", Uint32{ResourceType}, ")"); @@ -569,6 +572,7 @@ const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, const Char* GetFilterTypeLiteralName(FILTER_TYPE FilterType, bool bGetFullName) { + static_assert(FILTER_TYPE_NUM_FILTERS == 13, "Please update the switch below to handle the new filter type"); switch (FilterType) { // clang-format off @@ -594,6 +598,7 @@ const Char* GetFilterTypeLiteralName(FILTER_TYPE FilterType, bool bGetFullName) const Char* GetTextureAddressModeLiteralName(TEXTURE_ADDRESS_MODE AddressMode, bool bGetFullName) { + static_assert(TEXTURE_ADDRESS_NUM_MODES == 6, "Please update the switch below to handle the new texture address mode"); switch (AddressMode) { // clang-format off @@ -612,6 +617,7 @@ const Char* GetTextureAddressModeLiteralName(TEXTURE_ADDRESS_MODE AddressMode, b const Char* GetComparisonFunctionLiteralName(COMPARISON_FUNCTION ComparisonFunc, bool bGetFullName) { + static_assert(COMPARISON_FUNC_NUM_FUNCTIONS == 9, "Please update the switch below to handle the new comparison function"); switch (ComparisonFunc) { // clang-format off @@ -636,6 +642,7 @@ const Char* GetStencilOpLiteralName(STENCIL_OP StencilOp) #define STENCIL_OP_TO_STR(Op) \ case Op: return #Op + static_assert(STENCIL_OP_NUM_OPS == 9, "Please update the switch below to handle the new stencil op"); switch (StencilOp) { STENCIL_OP_TO_STR(STENCIL_OP_UNDEFINED); @@ -660,6 +667,7 @@ const Char* GetBlendFactorLiteralName(BLEND_FACTOR BlendFactor) #define BLEND_FACTOR_TO_STR(Factor) \ case Factor: return #Factor + static_assert(BLEND_FACTOR_NUM_FACTORS == 18, "Please update the switch below to handle the new blend factor"); switch (BlendFactor) { BLEND_FACTOR_TO_STR(BLEND_FACTOR_UNDEFINED); @@ -693,6 +701,7 @@ const Char* GetBlendOperationLiteralName(BLEND_OPERATION BlendOp) #define BLEND_OP_TO_STR(BlendOp) \ case BlendOp: return #BlendOp + static_assert(BLEND_OPERATION_NUM_OPERATIONS == 6, "Please update the switch below to handle the new blend op"); switch (BlendOp) { BLEND_OP_TO_STR(BLEND_OPERATION_UNDEFINED); @@ -714,6 +723,7 @@ const Char* GetFillModeLiteralName(FILL_MODE FillMode) #define FILL_MODE_TO_STR(Mode) \ case Mode: return #Mode + static_assert(FILL_MODE_NUM_MODES == 3, "Please update the switch below to handle the new filter mode"); switch (FillMode) { FILL_MODE_TO_STR(FILL_MODE_UNDEFINED); @@ -732,6 +742,7 @@ const Char* GetCullModeLiteralName(CULL_MODE CullMode) #define CULL_MODE_TO_STR(Mode) \ case Mode: return #Mode + static_assert(CULL_MODE_NUM_MODES == 4, "Please update the switch below to handle the new cull mode"); switch (CullMode) { CULL_MODE_TO_STR(CULL_MODE_UNDEFINED); diff --git a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp index 6578e0d1..0913f5d7 100644 --- a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp @@ -93,6 +93,7 @@ public: bool IsUsingSeparateSamplers() const { return !IsUsingCombinedSamplers(); } Uint32 GetTotalResourceCount() const { return this->m_Desc.NumResources; } + Uint32 GetImmutableSamplerCount() const { return this->m_Desc.NumImmutableSamplers; } std::pair<Uint32, Uint32> GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE VarType) const { 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<Uint32>(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<ISampler> 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<ISampler>; - - 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<ResourceAttribs>(std::max(1u, Desc.NumResources)); - MemPool.AddSpace<ImmutableSamplerPtrType>(Desc.NumImmutableSamplers); + MemPool.AddSpace<ImmutableSamplerAttribs>(Desc.NumImmutableSamplers); ReserveSpaceForDescription(MemPool, Desc); @@ -335,7 +335,7 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount MemPool.Reserve(); m_pResourceAttribs = MemPool.Allocate<ResourceAttribs>(std::max(1u, m_Desc.NumResources)); - m_ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerPtrType>(m_Desc.NumImmutableSamplers); + m_ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerAttribs>(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<VkSampler>(ResDesc.ArraySize, ImmutableSampler.RawPtr<SamplerVkImpl>()->GetVkSampler()); + pVkImmutableSamplers = TempAllocator.ConstructArray<VkSampler>(ResDesc.ArraySize, ImmutableSampler.Ptr.RawPtr<SamplerVkImpl>()->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<VkSampler>(ImmutableSampler.Ptr.RawPtr<SamplerVkImpl>()->GetVkSampler()); + } + if (m_Desc.SRBAllocationGranularity > 1) { std::array<size_t, MAX_SHADERS_IN_PIPELINE> 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; }); |
