diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-05-06 22:04:05 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-05-06 22:04:05 +0000 |
| commit | 9978d8d7422de1dc3532f872c8b937f0be25d7cc (patch) | |
| tree | affa0c4aa98b6b635f56f00a58ef942d0281aab5 /Graphics/GraphicsEngineVulkan | |
| parent | Improved SPIRV shader resource loading (diff) | |
| download | DiligentCore-9978d8d7422de1dc3532f872c8b937f0be25d7cc.tar.gz DiligentCore-9978d8d7422de1dc3532f872c8b937f0be25d7cc.zip | |
First working implementation of pipeline layout initialization in Vulkan
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
4 files changed, 66 insertions, 74 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index 625e1f3d..b382f0f3 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -57,7 +57,11 @@ public: void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs); #endif - void AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType, SHADER_TYPE ShaderType, VkDescriptorType DescriptorType, Uint32 DescriptorCount, Uint32 &DescriptorSet, Uint32 &OffsetFromSetStart); + void AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs, + SHADER_TYPE ShaderType, + Uint32 &DescriptorSet, + Uint32 &Binding, + std::vector<uint32_t> &SPIRV); #if 0 // This method should be thread-safe as it does not modify any object state @@ -138,24 +142,22 @@ private: void Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice); void Release(RenderDeviceVkImpl *pRenderDeviceVk); - DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType){return m_DescriptorSetLayouts[VarType];} - const DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType)const { return m_DescriptorSetLayouts[VarType]; } + DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType){return m_DescriptorSetLayouts[VarType == SHADER_VARIABLE_TYPE_DYNAMIC ? 1 : 0];} + const DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType)const { return m_DescriptorSetLayouts[VarType == SHADER_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } bool operator == (const DescriptorSetLayoutManager& rhs)const; bool operator != (const DescriptorSetLayoutManager& rhs)const {return !(*this == rhs);} size_t GetHash()const; VkPipelineLayout GetVkPipelineLayout()const{return m_VkPipelineLayout;} - void AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType, + void AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs, SHADER_TYPE ShaderType, - VkDescriptorType DescriptorType, - Uint32 DescriptorCount, Uint32 &DescriptorSet, - Uint32 &OffsetFromSetStart); + Uint32 &Binding); private: IMemoryAllocator &m_MemAllocator; VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout; - std::array<DescriptorSetLayout, 3> m_DescriptorSetLayouts; + std::array<DescriptorSetLayout, 2> m_DescriptorSetLayouts; std::vector<VkDescriptorSetLayoutBinding, STDAllocatorRawMem<VkDescriptorSetLayoutBinding>> m_LayoutBindings; uint8_t m_ActiveSets = 0; }; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h index a118cc6c..07332660 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h @@ -144,13 +144,6 @@ public: inline Uint32 GetSize()const{return m_NumResources; } -#ifdef _DEBUG - void SetDebugAttribs(Uint32 MaxOffset) - { - VERIFY_EXPR(m_NumResources == MaxOffset); - } -#endif - const Uint32 m_NumResources = 0; private: diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index c7a80ace..eb54d855 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -54,6 +54,29 @@ static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE Shader } } +class ResourceTypeToVkDescriptorType +{ +public: + ResourceTypeToVkDescriptorType() + { + m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageImage] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + m_Map[SPIRVShaderResourceAttribs::ResourceType::SampledImage] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + m_Map[SPIRVShaderResourceAttribs::ResourceType::AtomicCounter] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateImage] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateSampler] = VK_DESCRIPTOR_TYPE_SAMPLER; + } + + VkDescriptorType operator[](SPIRVShaderResourceAttribs::ResourceType ResType)const + { + return m_Map[static_cast<int>(ResType)]; + } + +private: + std::array<VkDescriptorType, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes> m_Map = {}; +}; + PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayoutManager(IMemoryAllocator &MemAllocator): m_MemAllocator(MemAllocator), m_LayoutBindings(STD_ALLOCATOR_RAW_MEM(VkDescriptorSetLayoutBinding, MemAllocator, "Allocator for Layout Bindings")) @@ -98,9 +121,9 @@ size_t PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::GetMemor // msb = n // MemSize = 2^(n+1) - MemSize = Uint32{1U << PlatformMisc::GetMSB(NumBindings-1)}; + MemSize = Uint32{2U << PlatformMisc::GetMSB(NumBindings-1)}; } - VERIFY_EXPR(NumBindings <= MemSize); + VERIFY_EXPR( ((NumBindings & (NumBindings-1)) == 0) && NumBindings == MemSize || NumBindings < MemSize); #ifdef _DEBUG static constexpr size_t MinMemSize = 1; @@ -108,7 +131,7 @@ size_t PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::GetMemor static constexpr size_t MinMemSize = 16; #endif MemSize = std::max(MemSize, MinMemSize); - return MemSize; + return MemSize * sizeof(VkDescriptorSetLayoutBinding); } void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::ReserveMemory(Uint32 NumBindings, IMemoryAllocator &MemAllocator) @@ -271,14 +294,12 @@ size_t PipelineLayout::DescriptorSetLayoutManager::GetHash()const return Hash; } -void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType, +void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs, SHADER_TYPE ShaderType, - VkDescriptorType DescriptorType, - Uint32 DescriptorCount, Uint32 &DescriptorSet, - Uint32 &OffsetFromSetStart) + Uint32 &Binding) { - auto& DescrSet = GetDescriptorSet(VarType); + auto& DescrSet = GetDescriptorSet(ResAttribs.VarType); if (DescrSet.SetIndex < 0) { DescrSet.SetIndex = m_ActiveSets++; @@ -287,9 +308,10 @@ void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(SHADER_VAR VkDescriptorSetLayoutBinding VkBinding = {}; VkBinding.binding = DescrSet.TotalDescriptors; - OffsetFromSetStart = DescrSet.TotalDescriptors; - VkBinding.descriptorType = DescriptorType; - VkBinding.descriptorCount = DescriptorCount; + Binding = DescrSet.TotalDescriptors; + static const ResourceTypeToVkDescriptorType ResTypeToVkDescrType; + VkBinding.descriptorType = ResTypeToVkDescrType[ResAttribs.Type]; + VkBinding.descriptorCount = ResAttribs.ArraySize; VkBinding.stageFlags = ShaderTypeToVkShaderStageFlagBit(ShaderType); VkBinding.pImmutableSamplers = nullptr; DescrSet.AddBinding(VkBinding, m_MemAllocator); @@ -417,15 +439,15 @@ void PipelineLayout::InitStaticSampler(SHADER_TYPE ShaderType, const String &Tex #endif -void PipelineLayout::AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType, +void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs, SHADER_TYPE ShaderType, - VkDescriptorType DescriptorType, - Uint32 DescriptorCount, Uint32 &DescriptorSet, // Output parameter - Uint32 &OffsetFromSetStart // Output parameter - ) + Uint32 &Binding, // Output parameter + std::vector<uint32_t> &SPIRV) { - m_LayoutMgr.AllocateResourceSlot(VarType, ShaderType, DescriptorType, DescriptorCount, DescriptorSet, OffsetFromSetStart); + m_LayoutMgr.AllocateResourceSlot(ResAttribs, ShaderType, DescriptorSet, Binding); + SPIRV[ResAttribs.BindingDecorationOffset] = Binding; + SPIRV[ResAttribs.DescriptorSetDecorationOffset] = DescriptorSet; #if 0 auto ShaderInd = GetShaderTypeIndex(ShaderType); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 7787ef38..fe5a6fa7 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -54,29 +54,6 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() Resources[r].~VkResource(); } -class ResourceTypeToVkDescriptorType -{ -public: - ResourceTypeToVkDescriptorType() - { - m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageImage] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - m_Map[SPIRVShaderResourceAttribs::ResourceType::SampledImage] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - m_Map[SPIRVShaderResourceAttribs::ResourceType::AtomicCounter] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateImage] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateSampler] = VK_DESCRIPTOR_TYPE_SAMPLER; - } - - VkDescriptorType operator[](SPIRVShaderResourceAttribs::ResourceType ResType)const - { - return m_Map[static_cast<int>(ResType)]; - } - -private: - std::array<VkDescriptorType, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes> m_Map = {}; -}; - void ShaderResourceLayoutVk::AllocateMemory(IMemoryAllocator &Allocator) { VERIFY( &m_ResourceBuffer.get_deleter().m_Allocator == &Allocator, "Inconsistent memory allocators" ); @@ -176,7 +153,7 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi m_pResourceCache = pResourceCache; m_pLogicalDevice = LogicalDevice.GetSharedPtr(); - VERIFY_EXPR( (pResourceCache != nullptr) ^ (pPipelineLayout != nullptr) ); + VERIFY_EXPR( (pResourceCache != nullptr) ^ (pPipelineLayout != nullptr && pSPIRV != nullptr) ); Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); @@ -214,7 +191,7 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi VERIFY_EXPR(IsAllowedType(SepImg.VarType, AllowedTypeBits)); ++m_NumResources[SepImg.VarType]; }, - [&](const SPIRVShaderResourceAttribs &SepSmpl, Uint32) + [&](const SPIRVShaderResourceAttribs &SepSmpl, Uint32) { VERIFY_EXPR(IsAllowedType(SepSmpl.VarType, AllowedTypeBits)); ++m_NumResources[SepSmpl.VarType]; @@ -225,17 +202,16 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi AllocateMemory(LayoutDataAllocator); std::array<Uint32, SHADER_VARIABLE_TYPE_NUM_TYPES> CurrResInd = {}; - std::array<Uint32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC + 1> StaticResCacheSetSizes = {}; + std::array<Uint32, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes > StaticResCacheSetSizes = {}; auto AddResource = [&](const SPIRVShaderResourceAttribs &Attribs) { Uint32 Binding = 0; Uint32 DescriptorSet = 0; - static const ResourceTypeToVkDescriptorType ResTypeToVkDescType; - VkDescriptorType DescriptorType = ResTypeToVkDescType[Attribs.Type]; if (pPipelineLayout) { - pPipelineLayout->AllocateResourceSlot(Attribs.VarType, m_pResources->GetShaderType(), DescriptorType, Attribs.ArraySize, DescriptorSet, Binding); + VERIFY_EXPR(pSPIRV != nullptr); + pPipelineLayout->AllocateResourceSlot(Attribs, m_pResources->GetShaderType(), DescriptorSet, Binding, *pSPIRV); VERIFY(DescriptorSet <= std::numeric_limits<decltype(VkResource::DescriptorSet)>::max(), "Descriptor set (", DescriptorSet, ") excceeds representable max value"); VERIFY(Binding <= std::numeric_limits<decltype(VkResource::Binding)>::max(), "Binding (", Binding, ") excceeds representable max value"); } @@ -243,19 +219,16 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi { // If pipeline layout is not provided - use artifial layout to store // static shader resources: - // Separate samplers at index VK_DESCRIPTOR_TYPE_SAMPLER (0) - // SampledImages at index VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER (1) - // Separate images at index VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE (2) - // Storage images at index VK_DESCRIPTOR_TYPE_STORAGE_IMAGE (3) - // Index VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER (4) is unused - // Index VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER (5) is unused - // Uniform buffers at index VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER (6) - // Storage buffers at index VK_DESCRIPTOR_TYPE_STORAGE_BUFFER (7) - // Index VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC (8) is unused - // Index VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC (9) is unused + // Uniform buffers at index SPIRVShaderResourceAttribs::ResourceType::UniformBuffer (0) + // Storage buffers at index SPIRVShaderResourceAttribs::ResourceType::StorageBuffer (1) + // Storage images at index SPIRVShaderResourceAttribs::ResourceType::StorageImage (2) + // Sampled images at index SPIRVShaderResourceAttribs::ResourceType::SampledImage (3) + // Atomic counters at index SPIRVShaderResourceAttribs::ResourceType::AtomicCounter (4) + // Separate images at index SPIRVShaderResourceAttribs::ResourceType::SeparateImage (5) + // Separate samplers at index SPIRVShaderResourceAttribs::ResourceType::SeparateSampler(6) VERIFY_EXPR(m_pResourceCache != nullptr); - DescriptorSet = DescriptorType; + DescriptorSet = Attribs.Type; Binding = StaticResCacheSetSizes[DescriptorSet]; StaticResCacheSetSizes[DescriptorSet] += Attribs.ArraySize; } @@ -318,9 +291,11 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi VERIFY_EXPR(pPipelineLayout == nullptr && pSPIRV == nullptr); m_pResourceCache->Initialize(GetRawAllocator(), static_cast<Uint32>(StaticResCacheSetSizes.size()), StaticResCacheSetSizes.data()); #ifdef _DEBUG - for(VkDescriptorType DescriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; DescriptorType <= VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; DescriptorType = static_cast<VkDescriptorType>(DescriptorType+1)) + for(SPIRVShaderResourceAttribs::ResourceType ResType = SPIRVShaderResourceAttribs::ResourceType::UniformBuffer; + ResType < SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes; + ResType = static_cast<SPIRVShaderResourceAttribs::ResourceType>(ResType +1)) { - m_pResourceCache->GetDescriptorSet(DescriptorType).SetDebugAttribs(StaticResCacheSetSizes[DescriptorType]); + VERIFY_EXPR(m_pResourceCache->GetDescriptorSet(ResType).GetSize() == StaticResCacheSetSizes[ResType]); } #endif } |
