diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-01-26 04:46:39 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-01-26 04:46:39 +0000 |
| commit | a688d74134cdb976009e1a62168f2642ca4f0745 (patch) | |
| tree | 9576ef715e303ee0a93535ddd4d44f09bd2e143d /Graphics/GraphicsEngineVulkan | |
| parent | Basic math: reworked ExtractBit and renamed to ExtractLSB; added tests (diff) | |
| download | DiligentCore-a688d74134cdb976009e1a62168f2642ca4f0745.tar.gz DiligentCore-a688d74134cdb976009e1a62168f2642ca4f0745.zip | |
Refactored PipelineResourceSignatureVkImpl
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
6 files changed, 325 insertions, 287 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp index 409cca1a..4bdb1865 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp @@ -83,52 +83,73 @@ public: Uint32 GetDynamicStorageBufferCount() const { return m_DynamicStorageBufferCount; } Uint32 GetNumDescriptorSets() const; - Uint32 GetNumShaderStages() const { return m_NumShaders; } + Uint32 GetNumShaderStages() const { return m_NumShaderStages; } SHADER_TYPE GetShaderStageType(Uint32 StageIndex) const; - static constexpr Uint32 InvalidSamplerInd = (1u << 16) - 1; - enum class CacheContentType { Signature = 0, // only static resources SRB = 1 // in SRB }; - // sizeof(ResourceAttribs) == 16, x64 + // sizeof(ResourceAttribs) == 12, x64 struct ResourceAttribs { private: static constexpr Uint32 _DescrTypeBits = 4; static constexpr Uint32 _DescrSetBits = 1; static constexpr Uint32 _BindingIndexBits = 16; - static constexpr Uint32 _SamplerIndBits = 16; + static constexpr Uint32 _SamplerIndBits = 10; static constexpr Uint32 _SamplerAssignedBits = 1; - static constexpr Uint32 _BitsSumm = ((sizeof(Uint32) * 8 * 2) + _DescrTypeBits + _DescrSetBits + _BindingIndexBits + _SamplerIndBits + _SamplerAssignedBits + 31) & ~31; + static_assert((_DescrTypeBits + _DescrSetBits + _BindingIndexBits + _SamplerIndBits + _SamplerAssignedBits) % 8 == 0, "Fields are not properly packed"); - static_assert((1u << _DescrTypeBits) >= static_cast<Uint32>(DescriptorType::Count), "not enought bits to store DescriptorType values"); - static_assert((1u << _SamplerIndBits) - 1 == InvalidSamplerInd, "InvalidSamplerInd is incorrect"); - static_assert((1u << _DescrSetBits) == MAX_DESCR_SET_PER_SIGNATURE, "not enoght bits to store descriptor set index"); - static_assert((1u << _BindingIndexBits) >= MAX_RESOURCES_IN_SIGNATURE, "not enoght bits to store resource binding index"); + 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"); + static_assert((1u << _BindingIndexBits) >= MAX_RESOURCES_IN_SIGNATURE, "Not enough bits to store resource binding index"); public: + static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1; + // clang-format off - Uint32 BindingIndex : _BindingIndexBits; - Uint32 SamplerInd : _SamplerIndBits; // index in m_Desc.Resources and m_pResourceAttribs - Uint32 DescrType : _DescrTypeBits; - Uint32 DescrSet : _DescrSetBits; - Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; - Uint32 CacheOffsets[2]; // static and static/mutable/dynamic offsets for ShaderResourceCacheVk - - ResourceAttribs() + const Uint32 BindingIndex : _BindingIndexBits; // Binding in the descriptor set + const Uint32 SamplerInd : _SamplerIndBits; // Index in m_Desc.Resources and m_pResourceAttribs + const Uint32 DescrType : _DescrTypeBits; // Descriptor type (DescriptorType) + const Uint32 DescrSet : _DescrSetBits; // Descriptor set (0 or 1) + const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag + const Uint32 SRBCacheOffset; // Offset in the SRB resource cache + const Uint32 StaticCacheOffset; // Offset in the static resource cache + // clang-format on + + ResourceAttribs(Uint32 _BindingIndex, + Uint32 _SamplerInd, + DescriptorType _DescrType, + Uint32 _DescrSet, + bool ImtblSamplerAssigned, + Uint32 _SRBCacheOffset, + Uint32 _StaticCacheOffset) noexcept : + // clang-format off + BindingIndex {_BindingIndex }, + SamplerInd {_SamplerInd }, + DescrType {static_cast<Uint32>(_DescrType)}, + DescrSet {_DescrSet }, + ImtblSamplerAssigned {ImtblSamplerAssigned ? 1u : 0u }, + SRBCacheOffset {_SRBCacheOffset }, + StaticCacheOffset {_StaticCacheOffset } + // clang-format on { - static_assert(_BitsSumm == sizeof(ResourceAttribs) * 8, "fields is not properly packed"); + VERIFY(BindingIndex == _BindingIndex, "Binding index (", _BindingIndex, ") exceeds maximum representable value"); + VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value"); + VERIFY(Type() == _DescrType, "Descriptor type (", static_cast<Uint32>(_DescrType), ") exceeds maximum representable value"); + VERIFY(DescrSet == _DescrSet, "Descriptor set (", _DescrSet, ") exceeds maximum representable value"); } - Uint32 CacheOffset(CacheContentType CacheType) const { return CacheOffsets[static_cast<Uint32>(CacheType)]; } + Uint32 CacheOffset(CacheContentType CacheType) const + { + return CacheType == CacheContentType::SRB ? SRBCacheOffset : StaticCacheOffset; + } - DescriptorType Type() const { return static_cast<DescriptorType>(DescrType); } - bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned; } - // clang-format on + DescriptorType Type() const { return static_cast<DescriptorType>(DescrType); } + bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; } }; const ResourceAttribs& GetAttribs(Uint32 ResIndex) const @@ -137,7 +158,7 @@ public: return m_pResourceAttribs[ResIndex]; } - const PipelineResourceDesc& GetResource(Uint32 ResIndex) const + const PipelineResourceDesc& GetResourceDesc(Uint32 ResIndex) const { VERIFY_EXPR(ResIndex < m_Desc.NumResources); return m_Desc.Resources[ResIndex]; @@ -199,22 +220,31 @@ public: } private: - using ImmutableSamplerPtrType = RefCntAutoPtr<ISampler>; - using CacheOffsetsType = std::array<Uint32, 3 * MAX_DESCR_SET_PER_SIGNATURE>; // [dynamic uniform buffers, dynamic storage buffers, other] * [descriptor sets] includes ArraySize - using BindingCountType = std::array<Uint32, 3 * MAX_DESCR_SET_PER_SIGNATURE>; // [dynamic uniform buffers, dynamic storage buffers, other] * [descriptor sets] without ArraySize + enum CACHE_GROUP : size_t + { + CACHE_GROUP_DYN_UB = 0, // Uniform buffer with dynamic offset + CACHE_GROUP_DYN_SB, // Storage buffer with dynamic offset + CACHE_GROUP_OTHER, // Other resource type - void Destruct(); + CACHE_GROUP_DYN_UB_STAT_VAR = CACHE_GROUP_DYN_UB, // Uniform buffer with dynamic offset, static variable + CACHE_GROUP_DYN_SB_STAT_VAR = CACHE_GROUP_DYN_SB, // Storage buffer with dynamic offset, static variable + CACHE_GROUP_OTHER_STAT_VAR = CACHE_GROUP_OTHER, // Other resource type, static variable + + CACHE_GROUP_DYN_UB_DYN_VAR, // Uniform buffer with dynamic offset, dynamic variable + CACHE_GROUP_DYN_SB_DYN_VAR, // Storage buffer with dynamic offset, dynamic variable + CACHE_GROUP_OTHER_DYN_VAR, // Other resource type, dynamic variable + + CACHE_GROUP_COUNT + }; + static_assert(CACHE_GROUP_COUNT == 3 * MAX_DESCR_SET_PER_SIGNATURE, "Inconsistent cache group count"); + + using CacheOffsetsType = std::array<Uint32, CACHE_GROUP_COUNT>; // [dynamic uniform buffers, dynamic storage buffers, other] x [descriptor sets] including ArraySize + using BindingCountType = std::array<Uint32, CACHE_GROUP_COUNT>; // [dynamic uniform buffers, dynamic storage buffers, other] x [descriptor sets] not counting ArraySize - void ReserveSpaceForStaticVarsMgrs(const PipelineResourceSignatureDesc& Desc, - Int8& StaticVarStageCount, - Uint32& StaticVarCount, - CacheOffsetsType& CacheSizes, - BindingCountType& BindingCount, - Uint8 DSMapping[MAX_DESCR_SET_PER_SIGNATURE]); + void Destruct(); void CreateLayout(const CacheOffsetsType& CacheSizes, - const BindingCountType& BindingCount, - const Uint8 DSMapping[MAX_DESCR_SET_PER_SIGNATURE]); + const BindingCountType& BindingCount); size_t CalculateHash() const; @@ -224,6 +254,8 @@ private: Uint32 GetStaticDescrSetIndex() const; Uint32 GetDynamicDescrSetIndex() const; + static CACHE_GROUP ResourceToCacheGroup(const PipelineResourceDesc& Res); + private: VulkanUtilities::DescriptorSetLayoutWrapper m_VkDescSetLayouts[MAX_DESCR_SET_PER_SIGNATURE]; @@ -237,10 +269,14 @@ private: std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_StaticVarIndex = {-1, -1, -1, -1, -1, -1}; static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above"); - Uint8 m_NumShaders = 0; + // The number of shader stages that have resources. + Uint8 m_NumShaderStages = 0; ShaderResourceCacheVk* m_pResourceCache = nullptr; - ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaders] + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages] + + + using ImmutableSamplerPtrType = RefCntAutoPtr<ISampler>; ImmutableSamplerPtrType* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers] SRBMemoryAllocator m_SRBMemAllocator; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp index 68dd7807..831542f6 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp @@ -109,10 +109,10 @@ private: Uint32 GetVariableIndex(const ShaderVariableVkImpl& Variable); - const PipelineResourceDesc& GetResource(Uint32 Index) const + const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const { VERIFY_EXPR(m_pSignature); - return m_pSignature->GetResource(Index); + return m_pSignature->GetResourceDesc(Index); } const ResourceAttribs& GetAttribs(Uint32 Index) const { @@ -218,7 +218,7 @@ private: friend ShaderVariableManagerVk; using ResourceAttribs = PipelineResourceSignatureVkImpl::ResourceAttribs; - const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResource(m_ResIndex); } + const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); } const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); } void BindResource(IDeviceObject* pObj, Uint32 ArrayIndex) const; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp index f2245d34..50f1c5c8 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp @@ -171,12 +171,12 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso for (Uint32 r = 0, ResCount = pSignature->GetTotalResourceCount(); r < ResCount; ++r) { - const auto& Res = pSignature->GetResource(r); - const auto& Attr = pSignature->GetAttribs(r); + const auto& ResDesc = pSignature->GetResourceDesc(r); + const auto& Attr = pSignature->GetAttribs(r); - if ((Res.ShaderStages & Stage) && strcmp(Res.Name, Name) == 0) + if ((ResDesc.ShaderStages & Stage) && strcmp(ResDesc.Name, Name) == 0) { - Info.Type = Res.ResourceType; + Info.Type = ResDesc.ResourceType; Info.BindingIndex = Attr.BindingIndex; Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet; return true; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp index 60631b9f..d3426240 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp @@ -38,48 +38,37 @@ namespace Diligent { + namespace { -bool operator==(const PipelineResourceDesc& lhs, const PipelineResourceDesc& rhs) +bool ResourcesCompatible(const PipelineResourceSignatureVkImpl::ResourceAttribs& lhs, + const PipelineResourceSignatureVkImpl::ResourceAttribs& rhs) { + // Ignore sampler index and cache offsets. // clang-format off - return lhs.ShaderStages == rhs.ShaderStages && - lhs.ArraySize == rhs.ArraySize && - lhs.ResourceType == rhs.ResourceType && - lhs.VarType == rhs.VarType && - lhs.Flags == lhs.Flags; + return lhs.BindingIndex == rhs.BindingIndex && + lhs.DescrType == rhs.DescrType && + lhs.DescrSet == rhs.DescrSet && + lhs.ImtblSamplerAssigned == rhs.ImtblSamplerAssigned; // clang-format on } -bool operator==(const PipelineResourceSignatureVkImpl::ResourceAttribs& lhs, - const PipelineResourceSignatureVkImpl::ResourceAttribs& rhs) +bool ResourcesCompatible(const PipelineResourceDesc& lhs, const PipelineResourceDesc& rhs) { + // Ignore resource names. // clang-format off - return lhs.DescrType == rhs.DescrType && - lhs.BindingIndex == rhs.BindingIndex && - lhs.DescrSet == rhs.DescrSet && - //lhs.CacheOffset== rhs.CacheOffset && - //lhs.SamplerInd == rhs.SamplerInd && - lhs.ImtblSamplerAssigned == rhs.ImtblSamplerAssigned; + return lhs.ShaderStages == rhs.ShaderStages && + lhs.ArraySize == rhs.ArraySize && + lhs.ResourceType == rhs.ResourceType && + lhs.VarType == rhs.VarType && + lhs.Flags == lhs.Flags; // clang-format on } -__forceinline Uint32 ResourceToCacheOffsetIndex(const PipelineResourceDesc& Res) +inline Uint32 GetDescriptorSetIdx(SHADER_RESOURCE_VARIABLE_TYPE VarType) { - const Uint32 SetIdx = (Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0) * 3; - const bool WithDynamicOffset = !(Res.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS); - const bool UseTexelBuffer = (Res.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER); - - if (WithDynamicOffset && !UseTexelBuffer) - { - if (Res.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER) - return SetIdx; - - if (Res.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV || Res.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV) - return SetIdx + 1; - } - return SetIdx + 2; + return VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0; } VkDescriptorType GetVkDescriptorType(DescriptorType Type) @@ -105,56 +94,56 @@ VkDescriptorType GetVkDescriptorType(DescriptorType Type) case DescriptorType::AccelerationStructure: return VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; // clang-format on default: - UNEXPECTED("unknown descriptor type"); + UNEXPECTED("Unknown descriptor type"); return VK_DESCRIPTOR_TYPE_MAX_ENUM; } } DescriptorType GetDescriptorType(const PipelineResourceDesc& Res) { - const bool WithDynamicOffset = !(Res.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS); - const bool CombinedSampler = (Res.Flags & PIPELINE_RESOURCE_FLAG_COMBINED_IMAGE); - const bool UseTexelBuffer = (Res.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER); + const bool WithDynamicOffset = (Res.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0; + const bool CombinedSampler = (Res.Flags & PIPELINE_RESOURCE_FLAG_COMBINED_IMAGE) != 0; + const bool UseTexelBuffer = (Res.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0; static_assert(SHADER_RESOURCE_TYPE_LAST == SHADER_RESOURCE_TYPE_ACCEL_STRUCT, "Please update the switch below to handle the new shader resource type"); switch (Res.ResourceType) { case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: - VERIFY_EXPR(!(Res.Flags & ~PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS)); + VERIFY_EXPR((Res.Flags & ~PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0); return WithDynamicOffset ? DescriptorType::UniformBufferDynamic : DescriptorType::UniformBuffer; case SHADER_RESOURCE_TYPE_BUFFER_UAV: - VERIFY_EXPR(!(Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER))); + VERIFY_EXPR((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) == 0); return UseTexelBuffer ? DescriptorType::StorageTexelBuffer : (WithDynamicOffset ? DescriptorType::StorageBufferDynamic : DescriptorType::StorageBuffer); case SHADER_RESOURCE_TYPE_TEXTURE_SRV: - VERIFY_EXPR(!(Res.Flags & ~PIPELINE_RESOURCE_FLAG_COMBINED_IMAGE)); + VERIFY_EXPR((Res.Flags & ~PIPELINE_RESOURCE_FLAG_COMBINED_IMAGE) == 0); return CombinedSampler ? DescriptorType::CombinedImageSampler : DescriptorType::SeparateImage; case SHADER_RESOURCE_TYPE_BUFFER_SRV: - VERIFY_EXPR(!(Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER))); + VERIFY_EXPR((Res.Flags & ~(PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS | PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER)) == 0); return UseTexelBuffer ? DescriptorType::UniformTexelBuffer : (WithDynamicOffset ? DescriptorType::StorageBufferDynamic_ReadOnly : DescriptorType::StorageBuffer_ReadOnly); case SHADER_RESOURCE_TYPE_TEXTURE_UAV: - VERIFY_EXPR(!Res.Flags); + VERIFY_EXPR(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN); return DescriptorType::StorageImage; case SHADER_RESOURCE_TYPE_SAMPLER: - VERIFY_EXPR(!Res.Flags); + VERIFY_EXPR(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN); return DescriptorType::Sampler; case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: - VERIFY_EXPR(!Res.Flags); + VERIFY_EXPR(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN); return DescriptorType::InputAttachment; case SHADER_RESOURCE_TYPE_ACCEL_STRUCT: - VERIFY_EXPR(!Res.Flags); + VERIFY_EXPR(Res.Flags == PIPELINE_RESOURCE_FLAG_UNKNOWN); return DescriptorType::AccelerationStructure; default: - UNEXPECTED("unknown resource type"); + UNEXPECTED("Unknown resource type"); return DescriptorType::Unknown; } } @@ -174,7 +163,7 @@ BUFFER_VIEW_TYPE DescriptorTypeToBufferView(DescriptorType Type) case DescriptorType::StorageBufferDynamic: return BUFFER_VIEW_UNORDERED_ACCESS; // clang-format on default: - UNEXPECTED("unsupported descriptor type for buffer view"); + UNEXPECTED("Unsupported descriptor type for buffer view"); return BUFFER_VIEW_UNDEFINED; } } @@ -191,7 +180,7 @@ TEXTURE_VIEW_TYPE DescriptorTypeToTextureView(DescriptorType Type) case DescriptorType::InputAttachment: return TEXTURE_VIEW_SHADER_RESOURCE; // clang-format on default: - UNEXPECTED("unsupported descriptor type for texture view"); + UNEXPECTED("Unsupported descriptor type for texture view"); return TEXTURE_VIEW_UNDEFINED; } } @@ -221,15 +210,34 @@ Int32 FindImmutableSampler(const PipelineResourceDesc& Res, const auto& ImtblSam = Desc.ImmutableSamplers[s]; if (((ImtblSam.ShaderStages & Res.ShaderStages) != 0) && StreqSuff(Res.Name, ImtblSam.SamplerOrTextureName, SamplerSuffix)) { - VERIFY_EXPR((ImtblSam.ShaderStages & Res.ShaderStages) == Res.ShaderStages); + DEV_CHECK_ERR((ImtblSam.ShaderStages & Res.ShaderStages) == Res.ShaderStages, + "Immutable sampler '", ImtblSam.SamplerOrTextureName, + "' is specified for only some of the shader stages that resource '", Res.Name, "' is defined for."); return s; } } return -1; } + } // namespace +inline PipelineResourceSignatureVkImpl::CACHE_GROUP PipelineResourceSignatureVkImpl::ResourceToCacheGroup(const PipelineResourceDesc& Res) +{ + const Uint32 SetIdx = GetDescriptorSetIdx(Res.VarType); + const bool WithDynamicOffset = (Res.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0; + const bool UseTexelBuffer = (Res.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0; + + if (WithDynamicOffset && !UseTexelBuffer) + { + if (Res.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER) + return static_cast<CACHE_GROUP>(SetIdx * 3 + CACHE_GROUP_DYN_UB); + + if (Res.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV || Res.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV) + return static_cast<CACHE_GROUP>(SetIdx * 3 + CACHE_GROUP_DYN_SB); + } + return static_cast<CACHE_GROUP>(SetIdx * 3 + CACHE_GROUP_OTHER); +} RESOURCE_STATE DescriptorTypeToResourceState(DescriptorType Type) { @@ -260,8 +268,6 @@ RESOURCE_STATE DescriptorTypeToResourceState(DescriptorType Type) } -#define LOG_PRS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of a pipeline resource signature '", m_Desc.Name, "' is invalid: ", ##__VA_ARGS__) - PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDevice, const PipelineResourceSignatureDesc& Desc, @@ -269,23 +275,57 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount TPipelineResourceSignatureBase{pRefCounters, pDevice, Desc, bIsDeviceInternal}, m_SRBMemAllocator{GetRawAllocator()} { + m_StaticVarIndex.fill(-1); + try { FixedLinearAllocator MemPool{GetRawAllocator()}; - // reserve at least 1 element because m_pResourceAttribs must hold pointer to memory + // 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); ReserveSpaceForDescription(MemPool, Desc); - Int8 StaticVarStageCount = 0; - Uint32 StaticVarCount = 0; - Uint8 DSMapping[MAX_DESCR_SET_PER_SIGNATURE] = {}; - CacheOffsetsType CacheSizes = {}; - BindingCountType BindingCount = {}; - ReserveSpaceForStaticVarsMgrs(Desc, StaticVarStageCount, StaticVarCount, CacheSizes, BindingCount, DSMapping); + Uint32 StaticResourceCount = 0; // The total number of static resources in all stages + // accounting for array sizes. + + CacheOffsetsType CacheSizes = {}; + BindingCountType BindingCount = {}; + + SHADER_TYPE StaticResStages = SHADER_TYPE_UNKNOWN; // Shader stages that have static resources + for (Uint32 i = 0; i < Desc.NumResources; ++i) + { + const auto& ResDesc = Desc.Resources[i]; + const auto SetIdx = GetDescriptorSetIdx(ResDesc.VarType); + const auto CacheGroup = ResourceToCacheGroup(ResDesc); + + m_ShaderStages |= ResDesc.ShaderStages; + + if (ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC) + { + StaticResStages |= ResDesc.ShaderStages; + StaticResourceCount += ResDesc.ArraySize; + } + + BindingCount[CacheGroup] += 1; + CacheSizes[CacheGroup] += ResDesc.ArraySize; + } + + m_NumShaderStages = static_cast<Uint8>(PlatformMisc::CountOneBits(static_cast<Uint32>(m_ShaderStages))); + if (m_ShaderStages != SHADER_TYPE_UNKNOWN) + { + m_PipelineType = PipelineTypeFromShaderStages(m_ShaderStages); + DEV_CHECK_ERR(m_PipelineType != PIPELINE_TYPE_INVALID, "Failed to deduce pipeline type from shader stages"); + } + int StaticVarStageCount = 0; // The number of shader stages that have static variables + for (; StaticResStages != SHADER_TYPE_UNKNOWN; ++StaticVarStageCount) + { + const auto StageBit = ExtractLSB(StaticResStages); + const auto ShaderTypeInd = GetShaderTypePipelineIndex(StageBit, m_PipelineType); + m_StaticVarIndex[ShaderTypeInd] = static_cast<Int8>(StaticVarStageCount); + } if (StaticVarStageCount > 0) { MemPool.AddSpace<ShaderResourceCacheVk>(1); @@ -309,10 +349,10 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount m_pResourceCache = MemPool.Construct<ShaderResourceCacheVk>(CacheContentType::Signature); m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(StaticVarStageCount); - m_pResourceCache->InitializeSets(GetRawAllocator(), 1, &StaticVarCount); + m_pResourceCache->InitializeSets(GetRawAllocator(), 1, &StaticResourceCount); } - CreateLayout(CacheSizes, BindingCount, DSMapping); + CreateLayout(CacheSizes, BindingCount); if (StaticVarStageCount > 0) { @@ -340,143 +380,79 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount } } -void PipelineResourceSignatureVkImpl::ReserveSpaceForStaticVarsMgrs(const PipelineResourceSignatureDesc& Desc, - Int8& StaticVarStageCount, - Uint32& StaticVarCount, - CacheOffsetsType& CacheSizes, - BindingCountType& BindingCount, - Uint8 DSMapping[MAX_DESCR_SET_PER_SIGNATURE]) +void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& CacheSizes, + const BindingCountType& BindingCount) { - // get active shader stages - SHADER_TYPE Stages = SHADER_TYPE_UNKNOWN; - SHADER_TYPE StaticResStages = SHADER_TYPE_UNKNOWN; - - for (Uint32 i = 0; i < Desc.NumResources; ++i) - { - const auto& Res = Desc.Resources[i]; - const Uint32 SetIdx = (Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0); - const Uint32 COIdx = ResourceToCacheOffsetIndex(Res); - - Stages |= Res.ShaderStages; - - if (Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC) - { - StaticResStages |= Res.ShaderStages; - StaticVarCount += Res.ArraySize; - } - - ++BindingCount[COIdx]; - CacheSizes[COIdx] += Res.ArraySize; - } - - // initialize descriptor set mapping table + // Descriptor set mapping (static/mutable (0) or dynamic (1) -> set index) + std::array<Uint32, MAX_DESCR_SET_PER_SIGNATURE> DSMapping = {}; { - Uint8 Idx = 0; - DSMapping[0] = (BindingCount[0] + BindingCount[1] + BindingCount[2] ? Idx++ : 0xFF); - DSMapping[1] = (BindingCount[3] + BindingCount[4] + BindingCount[5] ? Idx++ : 0xFF); + const auto TotalStaticBindings = + BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR] + + BindingCount[CACHE_GROUP_DYN_SB_STAT_VAR] + + BindingCount[CACHE_GROUP_OTHER_STAT_VAR]; + const auto TotalDynamicBindings = + BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR] + + BindingCount[CACHE_GROUP_OTHER_DYN_VAR]; + + Uint32 Idx = 0; + DSMapping[0] = (TotalStaticBindings != 0 ? Idx++ : 0xFF); + DSMapping[1] = (TotalDynamicBindings != 0 ? Idx++ : 0xFF); VERIFY_EXPR(Idx <= MAX_DESCR_SET_PER_SIGNATURE); } - m_ShaderStages = Stages; - m_NumShaders = static_cast<Uint8>(PlatformMisc::CountOneBits(static_cast<Uint32>(Stages))); - - if (Stages == SHADER_TYPE_COMPUTE) - { - m_PipelineType = PIPELINE_TYPE_COMPUTE; - } - else if (Stages & (SHADER_TYPE_AMPLIFICATION | SHADER_TYPE_MESH)) - { - m_PipelineType = PIPELINE_TYPE_MESH; - } - else if (Stages < SHADER_TYPE_COMPUTE) - { - m_PipelineType = PIPELINE_TYPE_GRAPHICS; - } - else if (Stages >= SHADER_TYPE_RAY_GEN) - { - m_PipelineType = PIPELINE_TYPE_RAY_TRACING; - } - else - { - LOG_PRS_ERROR_AND_THROW("can not deduce pipeline type - used incompatible shader stages"); - } - - m_StaticVarIndex.fill(-1); - - for (; StaticResStages != SHADER_TYPE_UNKNOWN; ++StaticVarStageCount) - { - const auto StageBit = ExtractBit(StaticResStages); - const auto ShaderTypeInd = GetShaderTypePipelineIndex(StageBit, m_PipelineType); - m_StaticVarIndex[ShaderTypeInd] = StaticVarStageCount; - } -} -#undef LOG_PRS_ERROR_AND_THROW - -void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& CacheSizes, - const BindingCountType& BindingCount, - const Uint8 DSMapping[MAX_DESCR_SET_PER_SIGNATURE]) -{ - std::vector<VkDescriptorSetLayoutBinding> LayoutBindings[MAX_DESCR_SET_PER_SIGNATURE]; + CacheOffsetsType CacheOffsets = + { + // static/mutable set + 0, + CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR], + CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR], + // dynamic set + 0, + CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR], + CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR] // + }; + BindingCountType BindingIndices = + { + // static/mutable set + 0, + BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR], + BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR] + BindingCount[CACHE_GROUP_DYN_SB_STAT_VAR], + // dynamic set + 0, + BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR], + BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR] // + }; + Uint32 StaticCacheOffset = 0; + + std::vector<VkDescriptorSetLayoutBinding> vkSetLayoutBindings[MAX_DESCR_SET_PER_SIGNATURE]; DynamicLinearAllocator TempAllocator{GetRawAllocator()}; - // clang-format off - CacheOffsetsType CacheOffsets = {0, CacheSizes[0], CacheSizes[0] + CacheSizes[1], // static/mutable set - 0, CacheSizes[3], CacheSizes[3] + CacheSizes[4]}; // dynamic set - BindingCountType BindingIndices = {0, BindingCount[0], BindingCount[0] + BindingCount[1], // static/mutable set - 0, BindingCount[3], BindingCount[3] + BindingCount[4]}; // dynamic set - Uint32 StaticCacheOffset = 0; - // clang-format on - for (Uint32 i = 0; i < m_Desc.NumResources; ++i) { - const auto& Res = m_Desc.Resources[i]; - const auto DescrType = GetDescriptorType(Res); - auto& Attribs = m_pResourceAttribs[i]; - const Uint32 SetIdx = (Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0); - const Uint32 COIdx = ResourceToCacheOffsetIndex(Res); - auto& CacheOffset = CacheOffsets[COIdx]; - - // If all resources are dynamic then signature contains only one descriptor set layout with index 0, - // so remap SetIdx to actual descriptor set index. - VERIFY_EXPR(DSMapping[SetIdx] < MAX_DESCR_SET_PER_SIGNATURE); - - Attribs.CacheOffsets[static_cast<Uint32>(CacheContentType::Signature)] = ~0u; - Attribs.CacheOffsets[static_cast<Uint32>(CacheContentType::SRB)] = CacheOffset; - - Attribs.DescrType = static_cast<Uint32>(DescrType); - Attribs.DescrSet = DSMapping[SetIdx]; - Attribs.BindingIndex = BindingIndices[COIdx]; - Attribs.SamplerInd = InvalidSamplerInd; - Attribs.ImtblSamplerAssigned = false; + const auto& ResDesc = m_Desc.Resources[i]; + const auto DescrType = GetDescriptorType(ResDesc); + const auto SetIdx = GetDescriptorSetIdx(ResDesc.VarType); + const auto CacheGroup = ResourceToCacheGroup(ResDesc); - // verify that data is not missed during bit packing - VERIFY_EXPR(Attribs.CacheOffsets[static_cast<Uint32>(CacheContentType::SRB)] == CacheOffset); - VERIFY_EXPR(Attribs.DescrType == static_cast<Uint32>(DescrType)); - VERIFY_EXPR(Attribs.DescrSet == DSMapping[SetIdx]); - VERIFY_EXPR(Attribs.BindingIndex == BindingIndices[COIdx]); + VERIFY(i == 0 || ResDesc.VarType >= m_Desc.Resources[i - 1].VarType, "Resources must be sorted by variable type"); - CacheOffset += Res.ArraySize; - ++BindingIndices[COIdx]; - - LayoutBindings[SetIdx].emplace_back(); - auto& LayoutBinding = LayoutBindings[SetIdx].back(); + // If all resources are dynamic, then the signature contains only one descriptor set layout with index 0, + // so remap SetIdx to the actual descriptor set index. + VERIFY_EXPR(DSMapping[SetIdx] < MAX_DESCR_SET_PER_SIGNATURE); - LayoutBinding.binding = Attribs.BindingIndex; - LayoutBinding.descriptorCount = Res.ArraySize; - LayoutBinding.stageFlags = ShaderTypesToVkShaderStageFlags(Res.ShaderStages); - LayoutBinding.pImmutableSamplers = nullptr; - LayoutBinding.descriptorType = GetVkDescriptorType(Attribs.Type()); + // The sampler may not be yet initialized, but this is OK as all resources are initialized + // in the same order as in m_Desc.Resources + const auto AssignedSamplerInd = DescrType == DescriptorType::SeparateImage ? + FindAssignedSampler(ResDesc) : + ResourceAttribs::InvalidSamplerInd; - if (Attribs.Type() == DescriptorType::SeparateImage) + VkSampler* pVkImmutableSamplers = nullptr; + if (DescrType == DescriptorType::CombinedImageSampler || + DescrType == DescriptorType::Sampler) { - Attribs.SamplerInd = FindAssignedSampler(Res); - } - - if (Attribs.Type() == DescriptorType::CombinedImageSampler || - Attribs.Type() == DescriptorType::Sampler) - { - // Only search for the immutable sampler for combined image samplers and separate samplers - Int32 SrcImmutableSamplerInd = FindImmutableSampler(Res, Attribs.Type(), m_Desc, GetCombinedSamplerSuffix()); + // Only search for immutable sampler for combined image samplers and separate samplers + Int32 SrcImmutableSamplerInd = FindImmutableSampler(ResDesc, DescrType, m_Desc, GetCombinedSamplerSuffix()); if (SrcImmutableSamplerInd >= 0) { auto& ImmutableSampler = m_ImmutableSamplers[SrcImmutableSamplerInd]; @@ -484,37 +460,57 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache if (!ImmutableSampler) GetDevice()->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); - LayoutBinding.pImmutableSamplers = TempAllocator.ConstructArray<VkSampler>(Res.ArraySize, ImmutableSampler.RawPtr<SamplerVkImpl>()->GetVkSampler()); - Attribs.ImtblSamplerAssigned = true; + pVkImmutableSamplers = TempAllocator.ConstructArray<VkSampler>(ResDesc.ArraySize, ImmutableSampler.RawPtr<SamplerVkImpl>()->GetVkSampler()); } } - if (Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC) + const auto* const pAttribs = new (m_pResourceAttribs + i) ResourceAttribs // + { + BindingIndices[CacheGroup], + AssignedSamplerInd, + DescrType, + DSMapping[SetIdx], + pVkImmutableSamplers != nullptr, + CacheOffsets[CacheGroup], + ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC ? StaticCacheOffset : ~0u // + }; + BindingIndices[CacheGroup] += 1; + CacheOffsets[CacheGroup] += ResDesc.ArraySize; + + vkSetLayoutBindings[SetIdx].emplace_back(); + auto& vkSetLayoutBinding = vkSetLayoutBindings[SetIdx].back(); + + vkSetLayoutBinding.binding = pAttribs->BindingIndex; + vkSetLayoutBinding.descriptorCount = ResDesc.ArraySize; + vkSetLayoutBinding.stageFlags = ShaderTypesToVkShaderStageFlags(ResDesc.ShaderStages); + vkSetLayoutBinding.pImmutableSamplers = pVkImmutableSamplers; + vkSetLayoutBinding.descriptorType = GetVkDescriptorType(pAttribs->Type()); + + if (ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC) { - Attribs.CacheOffsets[static_cast<Uint32>(CacheContentType::Signature)] = StaticCacheOffset; - m_pResourceCache->InitializeResources(Attribs.DescrSet, StaticCacheOffset, Res.ArraySize, Attribs.Type()); - StaticCacheOffset += Res.ArraySize; + m_pResourceCache->InitializeResources(pAttribs->DescrSet, StaticCacheOffset, ResDesc.ArraySize, pAttribs->Type()); + StaticCacheOffset += ResDesc.ArraySize; } } - m_DynamicUniformBufferCount = static_cast<Uint16>(CacheSizes[0] + CacheSizes[3]); - m_DynamicStorageBufferCount = static_cast<Uint16>(CacheSizes[1] + CacheSizes[4]); + m_DynamicUniformBufferCount = static_cast<Uint16>(CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR]); + m_DynamicStorageBufferCount = static_cast<Uint16>(CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR]); + VERIFY_EXPR(m_DynamicUniformBufferCount == CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR]); + VERIFY_EXPR(m_DynamicStorageBufferCount == CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR]); VERIFY_EXPR(m_pResourceCache == nullptr || m_pResourceCache->GetDescriptorSet(0).GetSize() == StaticCacheOffset); - VERIFY_EXPR(m_DynamicUniformBufferCount == CacheSizes[0] + CacheSizes[3]); - VERIFY_EXPR(m_DynamicStorageBufferCount == CacheSizes[1] + CacheSizes[4]); - VERIFY_EXPR(CacheOffsets[0] == CacheSizes[0]); - VERIFY_EXPR(CacheOffsets[1] == CacheSizes[0] + CacheSizes[1]); - VERIFY_EXPR(CacheOffsets[2] == CacheSizes[0] + CacheSizes[1] + CacheSizes[2]); - VERIFY_EXPR(CacheOffsets[3] == CacheSizes[3]); - VERIFY_EXPR(CacheOffsets[4] == CacheSizes[3] + CacheSizes[4]); - VERIFY_EXPR(CacheOffsets[5] == CacheSizes[3] + CacheSizes[4] + CacheSizes[5]); - VERIFY_EXPR(BindingIndices[0] == BindingCount[0]); - VERIFY_EXPR(BindingIndices[1] == BindingCount[0] + BindingCount[1]); - VERIFY_EXPR(BindingIndices[2] == BindingCount[0] + BindingCount[1] + BindingCount[2]); - VERIFY_EXPR(BindingIndices[3] == BindingCount[3]); - VERIFY_EXPR(BindingIndices[4] == BindingCount[3] + BindingCount[4]); - VERIFY_EXPR(BindingIndices[5] == BindingCount[3] + BindingCount[4] + BindingCount[5]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_DYN_UB_STAT_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_DYN_SB_STAT_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_OTHER_STAT_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR] + CacheSizes[CACHE_GROUP_OTHER_STAT_VAR]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_DYN_UB_DYN_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_DYN_SB_DYN_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR]); + VERIFY_EXPR(CacheOffsets[CACHE_GROUP_OTHER_DYN_VAR] == CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR] + CacheSizes[CACHE_GROUP_OTHER_DYN_VAR]); + VERIFY_EXPR(BindingIndices[CACHE_GROUP_DYN_UB_STAT_VAR] == BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR]); + VERIFY_EXPR(BindingIndices[CACHE_GROUP_DYN_SB_STAT_VAR] == BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR] + BindingCount[CACHE_GROUP_DYN_SB_STAT_VAR]); + VERIFY_EXPR(BindingIndices[CACHE_GROUP_OTHER_STAT_VAR] == BindingCount[CACHE_GROUP_DYN_UB_STAT_VAR] + BindingCount[CACHE_GROUP_DYN_SB_STAT_VAR] + BindingCount[CACHE_GROUP_OTHER_STAT_VAR]); + VERIFY_EXPR(BindingIndices[CACHE_GROUP_DYN_UB_DYN_VAR] == BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR]); + 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]); if (m_Desc.SRBAllocationGranularity > 1) { @@ -527,10 +523,14 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetShaderStageType(s), UnusedNumVars); } - Uint32 DescriptorSetSizes[2] = {CacheSizes[0] + CacheSizes[1] + CacheSizes[2], CacheSizes[3] + CacheSizes[4] + CacheSizes[5]}; - const Uint32 NumSets = !!DescriptorSetSizes[0] + !!DescriptorSetSizes[1]; - static_assert(_countof(DescriptorSetSizes) == MAX_DESCR_SET_PER_SIGNATURE, "MAX_DESCR_SET_PER_SIGNATURE was changed, update code above"); + Uint32 DescriptorSetSizes[2] = // + { + CacheSizes[CACHE_GROUP_DYN_UB_STAT_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_STAT_VAR] + CacheSizes[CACHE_GROUP_OTHER_STAT_VAR], + CacheSizes[CACHE_GROUP_DYN_UB_DYN_VAR] + CacheSizes[CACHE_GROUP_DYN_SB_DYN_VAR] + CacheSizes[CACHE_GROUP_OTHER_DYN_VAR] // + }; + static_assert(_countof(DescriptorSetSizes) == MAX_DESCR_SET_PER_SIGNATURE, "MAX_DESCR_SET_PER_SIGNATURE was changed, update the code above"); + const Uint32 NumSets = (DescriptorSetSizes[0] != 0 ? 1 : 0) + (DescriptorSetSizes[1] != 0 ? 1 : 0); if (DescriptorSetSizes[0] == 0) DescriptorSetSizes[0] = DescriptorSetSizes[1]; @@ -547,21 +547,21 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache const auto& LogicalDevice = GetDevice()->GetLogicalDevice(); - for (Uint32 i = 0; i < _countof(LayoutBindings); ++i) + for (Uint32 i = 0; i < _countof(vkSetLayoutBindings); ++i) { - auto& LayoutBinding = LayoutBindings[i]; - if (LayoutBinding.empty()) + auto& vkSetLayoutBinding = vkSetLayoutBindings[i]; + if (vkSetLayoutBinding.empty()) continue; - SetLayoutCI.bindingCount = static_cast<Uint32>(LayoutBinding.size()); - SetLayoutCI.pBindings = LayoutBinding.data(); + SetLayoutCI.bindingCount = static_cast<Uint32>(vkSetLayoutBinding.size()); + SetLayoutCI.pBindings = vkSetLayoutBinding.data(); m_VkDescSetLayouts[i] = LogicalDevice.CreateDescriptorSetLayout(SetLayoutCI); } } Uint32 PipelineResourceSignatureVkImpl::FindAssignedSampler(const PipelineResourceDesc& SepImg) const { - Uint32 SamplerInd = InvalidSamplerInd; + Uint32 SamplerInd = ResourceAttribs::InvalidSamplerInd; if (IsUsingCombinedSamplers()) { const auto IdxRange = GetResourceIndexRange(SepImg.VarType); @@ -628,7 +628,7 @@ void PipelineResourceSignatureVkImpl::Destruct() { for (size_t i = 0; i < m_StaticVarIndex.size(); ++i) { - Int8 Idx = m_StaticVarIndex[i]; + auto Idx = m_StaticVarIndex[i]; if (Idx >= 0) { m_StaticVarsMgrs[Idx].DestroyVariables(RawAllocator); @@ -669,16 +669,16 @@ bool PipelineResourceSignatureVkImpl::IsCompatibleWith(const PipelineResourceSig if (GetDesc().BindingIndex != Other.GetDesc().BindingIndex) return false; - const Uint32 LCount = GetTotalResourceCount(); - const Uint32 RCount = Other.GetTotalResourceCount(); + const Uint32 LResCount = GetTotalResourceCount(); + const Uint32 RResCount = Other.GetTotalResourceCount(); - if (LCount != RCount) + if (LResCount != RResCount) return false; - for (Uint32 r = 0; r < LCount; ++r) + for (Uint32 r = 0; r < LResCount; ++r) { - if (!(GetAttribs(r) == Other.GetAttribs(r)) || - !(GetResource(r) == Other.GetResource(r))) + if (!ResourcesCompatible(GetAttribs(r), Other.GetAttribs(r)) || + !ResourcesCompatible(GetResourceDesc(r), Other.GetResourceDesc(r))) return false; } @@ -771,9 +771,9 @@ void PipelineResourceSignatureVkImpl::InitResourceCache(ShaderResourceCacheVk& R for (Uint32 r = 0; r < m_Desc.NumResources; ++r) { - const auto& Res = GetResource(r); - const auto& Attr = GetAttribs(r); - VarCount[Attr.DescrSet] += Res.ArraySize; + const auto& ResDesc = GetResourceDesc(r); + const auto& Attr = GetAttribs(r); + VarCount[Attr.DescrSet] += ResDesc.ArraySize; } if (VarCount[1] == 0) @@ -800,16 +800,18 @@ void PipelineResourceSignatureVkImpl::InitResourceCache(ShaderResourceCacheVk& R SHADER_TYPE PipelineResourceSignatureVkImpl::GetShaderStageType(Uint32 StageIndex) const { + VERIFY_EXPR(StageIndex < m_NumShaderStages); + SHADER_TYPE Stages = m_ShaderStages; for (Uint32 Index = 0; Stages != SHADER_TYPE_UNKNOWN; ++Index) { - auto StageBit = ExtractBit(Stages); + auto StageBit = ExtractLSB(Stages); if (Index == StageIndex) return StageBit; } - UNEXPECTED("index is out of range"); + UNEXPECTED("Index is out of range"); return SHADER_TYPE_UNKNOWN; } @@ -824,9 +826,9 @@ void PipelineResourceSignatureVkImpl::InitializeResourceMemoryInCache(ShaderReso const auto CacheType = ResourceCache.GetContentType(); for (Uint32 r = 0; r < TotalResources; ++r) { - const auto& Res = GetResource(r); - const auto& Attr = GetAttribs(r); - ResourceCache.InitializeResources(Attr.DescrSet, Attr.CacheOffset(CacheType), Res.ArraySize, Attr.Type()); + const auto& ResDesc = GetResourceDesc(r); + const auto& Attr = GetAttribs(r); + ResourceCache.InitializeResources(Attr.DescrSet, Attr.CacheOffset(CacheType), ResDesc.ArraySize, Attr.Type()); } } @@ -846,20 +848,20 @@ void PipelineResourceSignatureVkImpl::InitializeStaticSRBResources(ShaderResourc for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) { - const auto& Res = GetResource(r); - const auto& Attr = GetAttribs(r); - VERIFY_EXPR(Res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC); + const auto& ResDesc = GetResourceDesc(r); + const auto& Attr = GetAttribs(r); + VERIFY_EXPR(ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC); - if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && Attr.IsImmutableSamplerAssigned()) + if (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && Attr.IsImmutableSamplerAssigned()) continue; // Skip immutable separate samplers - for (Uint32 ArrInd = 0; ArrInd < Res.ArraySize; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd) { auto SrcCacheOffset = Attr.CacheOffset(SrcCacheType) + ArrInd; const auto& SrcCachedRes = SrcDescrSet.GetResource(SrcCacheOffset); IDeviceObject* pObject = SrcCachedRes.pObject.RawPtr<IDeviceObject>(); if (!pObject) - LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetPrintName(Res, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'."); + LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetPrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'."); auto DstCacheOffset = Attr.CacheOffset(DstCacheType) + ArrInd; IDeviceObject* pCachedResource = DstDescrSet.GetResource(DstCacheOffset).pObject; @@ -927,7 +929,7 @@ void PipelineResourceSignatureVkImpl::CommitDynamicResources(const ShaderResourc for (Uint32 ResNum = ResIdxRange.first, ArrElem = 0; ResNum < ResIdxRange.second;) { - const auto& Res = GetResource(ResNum); + const auto& Res = GetResourceDesc(ResNum); const auto& Attr = GetAttribs(ResNum); const auto CacheOffset = Attr.CacheOffset(CacheType); @@ -1464,13 +1466,13 @@ void BindResourceHelper::CacheImage(IDeviceObject* pTexView) const UpdateDescriptorHandle(&DescrImgInfo, nullptr, nullptr); } - if (Attribs.SamplerInd != PipelineResourceSignatureVkImpl::InvalidSamplerInd) + if (Attribs.SamplerInd != PipelineResourceSignatureVkImpl::ResourceAttribs::InvalidSamplerInd) { VERIFY(DstRes.Type == DescriptorType::SeparateImage, "Only separate images can be assigned separate samplers when using HLSL-style combined samplers."); VERIFY(!IsImmutableSamplerAssigned(), "Separate image can't be assigned an immutable sampler."); - auto& SamplerResDesc = Signature.GetResource(Attribs.SamplerInd); + auto& SamplerResDesc = Signature.GetResourceDesc(Attribs.SamplerInd); auto& SamplerAttribs = Signature.GetAttribs(Attribs.SamplerInd); VERIFY_EXPR(SamplerResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER); @@ -1631,7 +1633,7 @@ void PipelineResourceSignatureVkImpl::BindResource(IDeviceObject* pObj, Uint32 ResIndex, ShaderResourceCacheVk& ResourceCache) const { - auto& ResDesc = GetResource(ResIndex); + auto& ResDesc = GetResourceDesc(ResIndex); auto& Attribs = GetAttribs(ResIndex); const auto CacheType = ResourceCache.GetContentType(); auto& DstDescrSet = ResourceCache.GetDescriptorSet(Attribs.DescrSet); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index c700fb97..50a173a7 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -51,7 +51,7 @@ size_t ShaderVariableManagerVk::GetRequiredMemorySize(const PipelineResourceSign const auto ResIdxRange = Layout.GetResourceIndexRange(VarType); for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) { - const auto& Res = Layout.GetResource(r); + const auto& Res = Layout.GetResourceDesc(r); const auto& Attr = Layout.GetAttribs(r); VERIFY_EXPR(Res.VarType == VarType); @@ -105,7 +105,7 @@ void ShaderVariableManagerVk::Initialize(const PipelineResourceSignatureVkImpl& const auto ResIdxRange = SrcLayout.GetResourceIndexRange(VarType); for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) { - const auto& Res = SrcLayout.GetResource(r); + const auto& Res = SrcLayout.GetResourceDesc(r); const auto& Attr = SrcLayout.GetAttribs(r); VERIFY_EXPR(Res.VarType == VarType); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index c2ac34a3..56a4a871 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1195,7 +1195,7 @@ VkPipelineStageFlags ResourceStateFlagsToVkPipelineStageFlags(RESOURCE_STATE Sta VkPipelineStageFlags vkPipelineStages = 0; while (StateFlags != RESOURCE_STATE_UNKNOWN) { - auto StateBit = ExtractBit(StateFlags); + auto StateBit = ExtractLSB(StateFlags); vkPipelineStages |= ResourceStateFlagToVkPipelineStage(StateBit, vkShaderStages); } return vkPipelineStages; @@ -1299,7 +1299,7 @@ VkAccessFlags AccelStructStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags) Uint32 Bits = StateFlags; while (Bits != 0) { - auto Bit = ExtractBit(Bits); + auto Bit = ExtractLSB(Bits); switch (Bit) { // clang-format off @@ -1636,7 +1636,7 @@ VkShaderStageFlags ShaderTypesToVkShaderStageFlags(SHADER_TYPE ShaderTypes) VkShaderStageFlags Result = 0; while (ShaderTypes != SHADER_TYPE_UNKNOWN) { - auto Type = ExtractBit(ShaderTypes); + auto Type = ExtractLSB(ShaderTypes); Result |= ShaderTypeToVkShaderStageFlagBit(Type); } return Result; @@ -1650,7 +1650,7 @@ VkBuildAccelerationStructureFlagsKHR BuildASFlagsToVkBuildAccelerationStructureF VkBuildAccelerationStructureFlagsKHR Result = 0; while (Flags != RAYTRACING_BUILD_AS_NONE) { - auto FlagBit = ExtractBit(Flags); + auto FlagBit = ExtractLSB(Flags); switch (FlagBit) { // clang-format off @@ -1674,7 +1674,7 @@ VkGeometryFlagsKHR GeometryFlagsToVkGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flag VkGeometryFlagsKHR Result = 0; while (Flags != RAYTRACING_GEOMETRY_FLAG_NONE) { - auto FlagBit = ExtractBit(Flags); + auto FlagBit = ExtractLSB(Flags); switch (FlagBit) { // clang-format off @@ -1695,7 +1695,7 @@ VkGeometryInstanceFlagsKHR InstanceFlagsToVkGeometryInstanceFlags(RAYTRACING_INS VkGeometryInstanceFlagsKHR Result = 0; while (Flags != RAYTRACING_INSTANCE_NONE) { - auto FlagBit = ExtractBit(Flags); + auto FlagBit = ExtractLSB(Flags); switch (FlagBit) { // clang-format off |
