diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-05-03 06:34:03 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-05-03 06:34:03 +0000 |
| commit | 0fcb4700020a59f70bd31fbb1de2220e2a2306a3 (patch) | |
| tree | 1c1a36827baad089c34968ff613d0fa0bb0d608f /Graphics/GraphicsEngineVulkan | |
| parent | Added .sType member assertions to create functions in VulkanLogicalDevice (diff) | |
| download | DiligentCore-0fcb4700020a59f70bd31fbb1de2220e2a2306a3.tar.gz DiligentCore-0fcb4700020a59f70bd31fbb1de2220e2a2306a3.zip | |
Working on pipeline layout initialization in Vulkan
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/PipelineLayout.h | 486 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h | 2 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/RootSignature.h | 433 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp (renamed from Graphics/GraphicsEngineVulkan/src/RootSignature.cpp) | 286 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 26 |
6 files changed, 738 insertions, 499 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index a340fedd..b501730a 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -16,9 +16,9 @@ set(INCLUDE include/FramebufferCache.h include/GenerateMips.h include/pch.h + include/PipelineLayout.h include/PipelineStateVkImpl.h include/RenderDeviceVkImpl.h - include/RootSignature.h include/SamplerVkImpl.h include/ShaderVkImpl.h include/ShaderResourceBindingVkImpl.h @@ -72,10 +72,10 @@ set(SRC src/DynamicUploadHeap.cpp src/FramebufferCache.cpp src/GenerateMips.cpp + src/PipelineLayout.cpp src/PipelineStateVkImpl.cpp src/RenderDeviceVkImpl.cpp src/RenderDeviceFactoryVk.cpp - src/RootSignature.cpp src/SamplerVkImpl.cpp src/ShaderVkImpl.cpp src/ShaderResourceBindingVkImpl.cpp diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h new file mode 100644 index 00000000..89e9dc5f --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -0,0 +1,486 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RootSignature class +#include "ShaderBase.h" +#include "ShaderResourceLayoutVk.h" +#include "VulkanUtilities/VulkanObjectWrappers.h" +#include "VulkanUtilities/VulkanLogicalDevice.h" + +namespace Diligent +{ + +class RenderDeviceVkImpl; + +//SHADER_TYPE ShaderTypeFromShaderVisibility(Vk_SHADER_VISIBILITY ShaderVisibility); +//Vk_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); +//Vk_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(Vk_DESCRIPTOR_RANGE_TYPE RangeType); + +#if 0 +class DescriptorSetLayout +{ +public: + + + RootParameter(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_CBV || ParameterType == Vk_ROOT_PARAMETER_TYPE_SRV || ParameterType == Vk_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Descriptor.ShaderRegister = Register; + m_RootParam.Descriptor.RegisterSpace = RegisterSpace; + } + + RootParameter(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, UINT NumDwords, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Constants.Num32BitValues = NumDwords; + m_RootParam.Constants.ShaderRegister = Register; + m_RootParam.Constants.RegisterSpace = RegisterSpace; + } + + RootParameter(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT NumRanges, Vk_DESCRIPTOR_RANGE *pRanges, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : + m_RootIndex(RootIndex), + m_ShaderVarType(VarType) + { + VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list"); + VERIFY_EXPR(pRanges != nullptr); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges; + m_RootParam.DescriptorTable.pDescriptorRanges = pRanges; +#ifdef _DEBUG + for (Uint32 r = 0; r < NumRanges; ++r) + pRanges[r].RangeType = static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1); +#endif + } + + RootParameter(const RootParameter &RP) : + m_RootParam(RP.m_RootParam), + m_DescriptorTableSize(RP.m_DescriptorTableSize), + m_ShaderVarType(RP.m_ShaderVarType), + m_RootIndex(RP.m_RootIndex) + { + VERIFY(m_RootParam.ParameterType != Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table"); + } + + RootParameter(const RootParameter &RP, UINT NumRanges, Vk_DESCRIPTOR_RANGE *pRanges) : + m_RootParam(RP.m_RootParam), + m_DescriptorTableSize(RP.m_DescriptorTableSize), + m_ShaderVarType(RP.m_ShaderVarType), + m_RootIndex(RP.m_RootIndex) + { + VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); + VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one"); + auto &DstTbl = m_RootParam.DescriptorTable; + DstTbl.NumDescriptorRanges = NumRanges; + DstTbl.pDescriptorRanges = pRanges; + const auto &SrcTbl = RP.m_RootParam.DescriptorTable; + memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(Vk_DESCRIPTOR_RANGE)); +#ifdef _DEBUG + { + Uint32 dbgTableSize = 0; + for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r) + { + const auto &Range = SrcTbl.pDescriptorRanges[r]; + dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors); + } + VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size"); + + for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r) + pRanges[r].RangeType = static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1); + } +#endif +} + + RootParameter& operator = (const RootParameter &RP) = delete; + RootParameter& operator = (RootParameter &&RP) = delete; + + void SetDescriptorRange(UINT RangeIndex, Vk_DESCRIPTOR_RANGE_TYPE Type, UINT Register, UINT Count, UINT Space = 0, UINT OffsetFromTableStart = Vk_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + auto &Tbl = m_RootParam.DescriptorTable; + VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index"); + Vk_DESCRIPTOR_RANGE &range = const_cast<Vk_DESCRIPTOR_RANGE &>(Tbl.pDescriptorRanges[RangeIndex]); + VERIFY(range.RangeType == static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly"); + range.RangeType = Type; + range.NumDescriptors = Count; + range.BaseShaderRegister = Register; + range.RegisterSpace = Space; + range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart; + m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count); + } + + SHADER_VARIABLE_TYPE GetShaderVariableType()const { return m_ShaderVarType; } + Uint32 GetDescriptorTableSize()const + { + VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + return m_DescriptorTableSize; + } + Vk_SHADER_VISIBILITY GetShaderVisibility()const { return m_RootParam.ShaderVisibility; } + Vk_ROOT_PARAMETER_TYPE GetParameterType()const { return m_RootParam.ParameterType; } + + Uint32 GetRootIndex()const { return m_RootIndex; } + + operator const Vk_ROOT_PARAMETER&()const { return m_RootParam; } + + bool operator == (const RootParameter&rhs)const + { + if (m_ShaderVarType != rhs.m_ShaderVarType || + m_DescriptorTableSize != rhs.m_DescriptorTableSize || + m_RootIndex != rhs.m_RootIndex) + return false; + + if (m_RootParam.ParameterType != rhs.m_RootParam.ParameterType || + m_RootParam.ShaderVisibility != rhs.m_RootParam.ShaderVisibility) + return false; + + switch (m_RootParam.ParameterType) + { + case Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + const auto &tbl0 = m_RootParam.DescriptorTable; + const auto &tbl1 = rhs.m_RootParam.DescriptorTable; + if (tbl0.NumDescriptorRanges != tbl1.NumDescriptorRanges) + return false; + for (UINT r = 0; r < tbl0.NumDescriptorRanges; ++r) + { + const auto &rng0 = tbl0.pDescriptorRanges[r]; + const auto &rng1 = tbl1.pDescriptorRanges[r]; + if (memcmp(&rng0, &rng1, sizeof(rng0)) != 0) + return false; + } + } + break; + + case Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + { + const auto &cnst0 = m_RootParam.Constants; + const auto &cnst1 = rhs.m_RootParam.Constants; + if (memcmp(&cnst0, &cnst1, sizeof(cnst0)) != 0) + return false; + } + break; + + case Vk_ROOT_PARAMETER_TYPE_CBV: + case Vk_ROOT_PARAMETER_TYPE_SRV: + case Vk_ROOT_PARAMETER_TYPE_UAV: + { + const auto &dscr0 = m_RootParam.Descriptor; + const auto &dscr1 = rhs.m_RootParam.Descriptor; + if (memcmp(&dscr0, &dscr1, sizeof(dscr0)) != 0) + return false; + } + break; + + default: UNEXPECTED("Unexpected root parameter type"); + } + + return true; + } + + bool operator != (const RootParameter&rhs)const + { + return !(*this == rhs); + } + + size_t GetHash()const + { + size_t hash = ComputeHash(m_ShaderVarType, m_DescriptorTableSize, m_RootIndex); + HashCombine(hash, m_RootParam.ParameterType, m_RootParam.ShaderVisibility); + + switch (m_RootParam.ParameterType) + { + case Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + const auto &tbl = m_RootParam.DescriptorTable; + HashCombine(hash, tbl.NumDescriptorRanges); + for (UINT r = 0; r < tbl.NumDescriptorRanges; ++r) + { + const auto &rng = tbl.pDescriptorRanges[r]; + HashCombine(hash, rng.BaseShaderRegister, rng.NumDescriptors, rng.OffsetInDescriptorsFromTableStart, rng.RangeType, rng.RegisterSpace); + } + } + break; + + case Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + { + const auto &cnst = m_RootParam.Constants; + HashCombine(hash, cnst.Num32BitValues, cnst.RegisterSpace, cnst.ShaderRegister); + } + break; + + case Vk_ROOT_PARAMETER_TYPE_CBV: + case Vk_ROOT_PARAMETER_TYPE_SRV: + case Vk_ROOT_PARAMETER_TYPE_UAV: + { + const auto &dscr = m_RootParam.Descriptor; + HashCombine(hash, dscr.RegisterSpace, dscr.ShaderRegister); + } + break; + + default: UNEXPECTED("Unexpected root parameter type"); + } + + return hash; + } + +private: + + SHADER_VARIABLE_TYPE m_ShaderVarType = static_cast<SHADER_VARIABLE_TYPE>(-1); + Vk_ROOT_PARAMETER m_RootParam = {}; + Uint32 m_DescriptorTableSize = 0; + Uint32 m_RootIndex = static_cast<Uint32>(-1); + + +}; +#endif + + +/// Implementation of the Diligent::RootSignature class +class PipelineLayout +{ +public: +#if 0 + RootSignature(); + + void AllocateStaticSamplers(IShader* const *ppShaders, Uint32 NumShaders); + + void Finalize(IVkDevice *pVkDevice); + + IVkRootSignature* GetVkRootSignature()const{return m_pVkRootSignature;} + void InitResourceCache(RenderDeviceVkImpl *pDeviceVkImpl, class ShaderResourceCacheVk& ResourceCache, IMemoryAllocator &CacheMemAllocator)const; + + void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs); +#endif + + //void AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, Vk_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, Uint32 &OffsetFromTableStart); + +#if 0 + // This method should be thread-safe as it does not modify any object state + void (RootSignature::*CommitDescriptorHandles)(RenderDeviceVkImpl *pRenderDeviceVk, + ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const = nullptr; + + void (RootSignature::*TransitionAndCommitDescriptorHandles)(RenderDeviceVkImpl *pRenderDeviceVk, + ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const = nullptr; + + void TransitionResources(ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx)const; + + void CommitRootViews(ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx, + bool IsCompute, + Uint32 ContextId)const; + + Uint32 GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE VarType)const + { + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); + return m_TotalSrvCbvUavSlots[VarType]; + } + Uint32 GetTotalSamplerSlots(SHADER_VARIABLE_TYPE VarType)const + { + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); + return m_TotalSamplerSlots[VarType]; + } + + bool IsSameAs(const RootSignature& RS)const + { + return m_RootParams == RS.m_RootParams; + } + size_t GetHash()const + { + return m_RootParams.GetHash(); + } + +private: +#ifdef _DEBUG + void dbgVerifyRootParameters()const; +#endif + + Uint32 m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; + Uint32 m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; + + CComPtr<IVkRootSignature> m_pVkRootSignature; +#endif + + class DescriptorSetLayoutManager + { + public: + struct DescriptorSetLayout + { + DescriptorSetLayout(SHADER_VARIABLE_TYPE VarType) : + ShaderVarType(VarType) + {} + DescriptorSetLayout(DescriptorSetLayout&&) = default; + DescriptorSetLayout(const DescriptorSetLayout&) = delete; + DescriptorSetLayout& operator = (const DescriptorSetLayout&) = delete; + DescriptorSetLayout& operator = (DescriptorSetLayout&&) = delete; + + const SHADER_VARIABLE_TYPE ShaderVarType; + uint32_t BindingCount = 0; + VkDescriptorSetLayoutBinding* pBindings = nullptr; + VulkanUtilities::DescriptorSetLayoutWrapper VkLayout; + + ~DescriptorSetLayout(); + void AddBinding(const VkDescriptorSetLayoutBinding &Binding, IMemoryAllocator &MemAllocator); + void Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice, IMemoryAllocator &MemAllocator, VkDescriptorSetLayoutBinding* pNewBindings); + void Release(RenderDeviceVkImpl *pRenderDeviceVk); + + bool operator == (const DescriptorSetLayout& rhs)const; + bool operator != (const DescriptorSetLayout& rhs)const{return !(*this == rhs);} + + private: + void ReserveMemory(Uint32 NumBindings, IMemoryAllocator &MemAllocator); + static size_t GetMemorySize(Uint32 NumBindings); + }; + + DescriptorSetLayoutManager(IMemoryAllocator &MemAllocator); + ~DescriptorSetLayoutManager(); + + DescriptorSetLayoutManager(const DescriptorSetLayoutManager&) = delete; + DescriptorSetLayoutManager& operator= (const DescriptorSetLayoutManager&) = delete; + DescriptorSetLayoutManager(DescriptorSetLayoutManager&&) = delete; + DescriptorSetLayoutManager& operator= (DescriptorSetLayoutManager&&) = delete; + + void Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice); + void Release(RenderDeviceVkImpl *pRenderDeviceVk); + + //Uint32 GetNumRootTables()const{return m_NumRootTables;} + //Uint32 GetNumRootViews()const{return m_NumRootViews;} + // + //const RootParameter& GetRootTable(Uint32 TableInd)const + //{ + // VERIFY_EXPR(TableInd < m_NumRootTables); + // return m_pRootTables[TableInd]; + //} + + //RootParameter& GetRootTable(Uint32 TableInd) + //{ + // VERIFY_EXPR(TableInd < m_NumRootTables); + // return m_pRootTables[TableInd]; + //} + + //const RootParameter& GetRootView(Uint32 ViewInd)const + //{ + // VERIFY_EXPR(ViewInd < m_NumRootViews); + // return m_pRootViews[ViewInd]; + //} + + //RootParameter& GetRootView(Uint32 ViewInd) + //{ + // VERIFY_EXPR(ViewInd < m_NumRootViews); + // return m_pRootViews[ViewInd]; + //} + + DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType); + DescriptorSetLayout& GetDescriptorSetByInd(size_t Ind){return m_DescriptorSetLayouts[Ind];} + const DescriptorSetLayout& GetDescriptorSetByInd(size_t Ind)const { return m_DescriptorSetLayouts[Ind]; } + size_t GetNumDescriptorSetLayouts()const { return m_DescriptorSetLayouts.size(); } + + //void AddDescriptorSet(SHADER_VARIABLE_TYPE VarType); + //void AddRootTable(Uint32 RootIndex, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable = 1); + //void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1); + + //template<class TOperation> + //void ProcessDescriptorSets(TOperation)const; + + bool operator == (const DescriptorSetLayoutManager& rhs)const; + bool operator != (const DescriptorSetLayoutManager& rhs)const {return !(*this == rhs);} + //size_t GetHash()const; + + private: + + IMemoryAllocator &m_MemAllocator; + //std::unique_ptr<void, STDDeleter<void, IMemoryAllocator>> m_pMemory; + //Uint32 m_NumRootTables = 0; + //Uint32 m_NumRootViews = 0; + //Uint32 m_TotalDescriptorRanges = 0; + //RootParameter *m_pRootTables = nullptr; + //RootParameter *m_pRootViews = nullptr; + VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout; + std::vector<DescriptorSetLayout, STDAllocatorRawMem<DescriptorSetLayout>> m_DescriptorSetLayouts; + std::vector<VkDescriptorSetLayoutBinding, STDAllocatorRawMem<VkDescriptorSetLayoutBinding>> m_LayoutBindings; + Int8 m_VarTypeToDescrSetLayout[SHADER_VARIABLE_TYPE_NUM_TYPES] = {-1, -1, -1}; + }; + +#if 0 + static constexpr Uint8 InvalidRootTableIndex = static_cast<Uint8>(-1); + + // The array below contains array index of a CBV/SRV/UAV root table + // in m_RootParams (NOT the Root Index!), for every variable type + // (static, mutable, dynamic) and every shader type, + // or -1, if the table is not yet assigned to the combination + Uint8 m_SrvCbvUavRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; + // This array contains the same data for Sampler root table + Uint8 m_SamplerRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; + + RootParamsManager m_RootParams; + + struct StaticSamplerAttribs + { + StaticSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast<UINT>(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + Vk_SHADER_VISIBILITY ShaderVisibility = static_cast<Vk_SHADER_VISIBILITY>(-1); + + StaticSamplerAttribs(){} + StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, Vk_SHADER_VISIBILITY Visibility) : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility) + {} + }; + // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) + std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > m_StaticSamplers; + + IMemoryAllocator &m_MemAllocator; + + // Commits descriptor handles for static and mutable variables + template<bool PerformResourceTransitions> + void CommitDescriptorHandlesInternal_SM(RenderDeviceVkImpl *pRenderDeviceVk, + ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const; + template<bool PerformResourceTransitions> + // Commits descriptor handles for static, mutable, and dynamic variables + void CommitDescriptorHandlesInternal_SMD(RenderDeviceVkImpl *pRenderDeviceVk, + ShaderResourceCacheVk& ResourceCache, + class CommandContext &Ctx, + bool IsCompute)const; +#endif +}; + +} diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index e90cd69a..0ebfe80c 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -29,7 +29,7 @@ #include "RenderDeviceVk.h" #include "PipelineStateVk.h" #include "PipelineStateBase.h" -#include "RootSignature.h" +#include "PipelineLayout.h" #include "ShaderResourceLayoutVk.h" #include "AdaptiveFixedBlockAllocator.h" #include "VulkanUtilities/VulkanObjectWrappers.h" diff --git a/Graphics/GraphicsEngineVulkan/include/RootSignature.h b/Graphics/GraphicsEngineVulkan/include/RootSignature.h deleted file mode 100644 index 7545f54b..00000000 --- a/Graphics/GraphicsEngineVulkan/include/RootSignature.h +++ /dev/null @@ -1,433 +0,0 @@ -/* Copyright 2015-2018 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::RootSignature class -#include "ShaderBase.h" -#include "ShaderResourceLayoutVk.h" - -namespace Diligent -{ - -#if 0 -SHADER_TYPE ShaderTypeFromShaderVisibility(Vk_SHADER_VISIBILITY ShaderVisibility); -Vk_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); -Vk_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(Vk_DESCRIPTOR_RANGE_TYPE RangeType); - -class RootParameter -{ -public: - - RootParameter(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : - m_RootIndex(RootIndex), - m_ShaderVarType(VarType) - { - VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_CBV || ParameterType == Vk_ROOT_PARAMETER_TYPE_SRV || ParameterType == Vk_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list"); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.Descriptor.ShaderRegister = Register; - m_RootParam.Descriptor.RegisterSpace = RegisterSpace; - } - - RootParameter( Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, UINT NumDwords, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : - m_RootIndex(RootIndex), - m_ShaderVarType(VarType) - { - VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list"); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.Constants.Num32BitValues = NumDwords; - m_RootParam.Constants.ShaderRegister = Register; - m_RootParam.Constants.RegisterSpace = RegisterSpace; - } - - RootParameter( Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT NumRanges, Vk_DESCRIPTOR_RANGE *pRanges, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) : - m_RootIndex(RootIndex), - m_ShaderVarType(VarType) - { - VERIFY(ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list"); - VERIFY_EXPR(pRanges != nullptr); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges; - m_RootParam.DescriptorTable.pDescriptorRanges = pRanges; -#ifdef _DEBUG - for(Uint32 r=0; r < NumRanges; ++r) - pRanges[r].RangeType = static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1); -#endif - } - - RootParameter(const RootParameter &RP): - m_RootParam( RP.m_RootParam), - m_DescriptorTableSize(RP.m_DescriptorTableSize), - m_ShaderVarType(RP.m_ShaderVarType), - m_RootIndex(RP.m_RootIndex) - { - VERIFY(m_RootParam.ParameterType != Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table"); - } - - RootParameter(const RootParameter &RP, UINT NumRanges, Vk_DESCRIPTOR_RANGE *pRanges): - m_RootParam( RP.m_RootParam), - m_DescriptorTableSize(RP.m_DescriptorTableSize), - m_ShaderVarType(RP.m_ShaderVarType), - m_RootIndex(RP.m_RootIndex) - { - VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); - VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one"); - auto &DstTbl = m_RootParam.DescriptorTable; - DstTbl.NumDescriptorRanges = NumRanges; - DstTbl.pDescriptorRanges = pRanges; - const auto &SrcTbl = RP.m_RootParam.DescriptorTable; - memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(Vk_DESCRIPTOR_RANGE)); -#ifdef _DEBUG - { - Uint32 dbgTableSize = 0; - for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r) - { - const auto &Range = SrcTbl.pDescriptorRanges[r]; - dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors); - } - VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size"); - - for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r) - pRanges[r].RangeType = static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1); - } -#endif - } - - RootParameter& operator = (const RootParameter &RP) = delete; - RootParameter& operator = (RootParameter &&RP) = delete; - - void SetDescriptorRange( UINT RangeIndex, Vk_DESCRIPTOR_RANGE_TYPE Type, UINT Register, UINT Count, UINT Space = 0, UINT OffsetFromTableStart = Vk_DESCRIPTOR_RANGE_OFFSET_APPEND) - { - VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); - auto &Tbl = m_RootParam.DescriptorTable; - VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index"); - Vk_DESCRIPTOR_RANGE &range = const_cast<Vk_DESCRIPTOR_RANGE &>(Tbl.pDescriptorRanges[RangeIndex]); - VERIFY(range.RangeType == static_cast<Vk_DESCRIPTOR_RANGE_TYPE>(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly"); - range.RangeType = Type; - range.NumDescriptors = Count; - range.BaseShaderRegister = Register; - range.RegisterSpace = Space; - range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart; - m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count); - } - - SHADER_VARIABLE_TYPE GetShaderVariableType()const{ return m_ShaderVarType; } - Uint32 GetDescriptorTableSize()const - { - VERIFY(m_RootParam.ParameterType == Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); - return m_DescriptorTableSize; - } - Vk_SHADER_VISIBILITY GetShaderVisibility()const{return m_RootParam.ShaderVisibility;} - Vk_ROOT_PARAMETER_TYPE GetParameterType()const{return m_RootParam.ParameterType;} - - Uint32 GetRootIndex()const{return m_RootIndex;} - - operator const Vk_ROOT_PARAMETER&()const{return m_RootParam;} - - bool operator == (const RootParameter&rhs)const - { - if (m_ShaderVarType != rhs.m_ShaderVarType || - m_DescriptorTableSize != rhs.m_DescriptorTableSize || - m_RootIndex != rhs.m_RootIndex) - return false; - - if (m_RootParam.ParameterType != rhs.m_RootParam.ParameterType || - m_RootParam.ShaderVisibility != rhs.m_RootParam.ShaderVisibility) - return false; - - switch(m_RootParam.ParameterType) - { - case Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - { - const auto &tbl0 = m_RootParam.DescriptorTable; - const auto &tbl1 = rhs.m_RootParam.DescriptorTable; - if(tbl0.NumDescriptorRanges != tbl1.NumDescriptorRanges) - return false; - for(UINT r=0; r < tbl0.NumDescriptorRanges; ++r) - { - const auto &rng0 = tbl0.pDescriptorRanges[r]; - const auto &rng1 = tbl1.pDescriptorRanges[r]; - if( memcmp(&rng0, &rng1, sizeof(rng0)) != 0) - return false; - } - } - break; - - case Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: - { - const auto &cnst0 = m_RootParam.Constants; - const auto &cnst1 = rhs.m_RootParam.Constants; - if (memcmp(&cnst0, &cnst1, sizeof(cnst0)) != 0) - return false; - } - break; - - case Vk_ROOT_PARAMETER_TYPE_CBV: - case Vk_ROOT_PARAMETER_TYPE_SRV: - case Vk_ROOT_PARAMETER_TYPE_UAV: - { - const auto &dscr0 = m_RootParam.Descriptor; - const auto &dscr1 = rhs.m_RootParam.Descriptor; - if (memcmp(&dscr0, &dscr1, sizeof(dscr0)) != 0) - return false; - } - break; - - default: UNEXPECTED("Unexpected root parameter type"); - } - - return true; - } - - bool operator != (const RootParameter&rhs)const - { - return !(*this == rhs); - } - - size_t GetHash()const - { - size_t hash = ComputeHash(m_ShaderVarType, m_DescriptorTableSize, m_RootIndex); - HashCombine(hash, m_RootParam.ParameterType, m_RootParam.ShaderVisibility); - - switch (m_RootParam.ParameterType) - { - case Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - { - const auto &tbl = m_RootParam.DescriptorTable; - HashCombine(hash, tbl.NumDescriptorRanges); - for (UINT r = 0; r < tbl.NumDescriptorRanges; ++r) - { - const auto &rng = tbl.pDescriptorRanges[r]; - HashCombine(hash, rng.BaseShaderRegister, rng.NumDescriptors, rng.OffsetInDescriptorsFromTableStart, rng.RangeType, rng.RegisterSpace); - } - } - break; - - case Vk_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: - { - const auto &cnst = m_RootParam.Constants; - HashCombine(hash, cnst.Num32BitValues, cnst.RegisterSpace, cnst.ShaderRegister); - } - break; - - case Vk_ROOT_PARAMETER_TYPE_CBV: - case Vk_ROOT_PARAMETER_TYPE_SRV: - case Vk_ROOT_PARAMETER_TYPE_UAV: - { - const auto &dscr = m_RootParam.Descriptor; - HashCombine(hash, dscr.RegisterSpace, dscr.ShaderRegister); - } - break; - - default: UNEXPECTED("Unexpected root parameter type"); - } - - return hash; - } - -private: - - SHADER_VARIABLE_TYPE m_ShaderVarType = static_cast<SHADER_VARIABLE_TYPE>(-1); - Vk_ROOT_PARAMETER m_RootParam = {}; - Uint32 m_DescriptorTableSize = 0; - Uint32 m_RootIndex = static_cast<Uint32>(-1); -}; - - - -/// Implementation of the Diligent::RootSignature class -class RootSignature -{ -public: - RootSignature(); - - void AllocateStaticSamplers(IShader* const *ppShaders, Uint32 NumShaders); - - void Finalize(IVkDevice *pVkDevice); - - IVkRootSignature* GetVkRootSignature()const{return m_pVkRootSignature;} - void InitResourceCache(class RenderDeviceVkImpl *pDeviceVkImpl, class ShaderResourceCacheVk& ResourceCache, IMemoryAllocator &CacheMemAllocator)const; - - void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs); - - void AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, Vk_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, Uint32 &OffsetFromTableStart); - - // This method should be thread-safe as it does not modify any object state - void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceVkImpl *pRenderDeviceVk, - ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx, - bool IsCompute)const = nullptr; - - void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceVkImpl *pRenderDeviceVk, - ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx, - bool IsCompute)const = nullptr; - - void TransitionResources(ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx)const; - - void CommitRootViews(ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx, - bool IsCompute, - Uint32 ContextId)const; - - Uint32 GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE VarType)const - { - VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); - return m_TotalSrvCbvUavSlots[VarType]; - } - Uint32 GetTotalSamplerSlots(SHADER_VARIABLE_TYPE VarType)const - { - VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); - return m_TotalSamplerSlots[VarType]; - } - - bool IsSameAs(const RootSignature& RS)const - { - return m_RootParams == RS.m_RootParams; - } - size_t GetHash()const - { - return m_RootParams.GetHash(); - } - -private: -#ifdef _DEBUG - void dbgVerifyRootParameters()const; -#endif - - Uint32 m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; - Uint32 m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_NUM_TYPES]; - - CComPtr<IVkRootSignature> m_pVkRootSignature; - - class RootParamsManager - { - public: - RootParamsManager(IMemoryAllocator &MemAllocator); - - RootParamsManager(const RootParamsManager&) = delete; - RootParamsManager& operator= (const RootParamsManager&) = delete; - RootParamsManager(RootParamsManager&&) = delete; - RootParamsManager& operator= (RootParamsManager&&) = delete; - - Uint32 GetNumRootTables()const{return m_NumRootTables;} - Uint32 GetNumRootViews()const{return m_NumRootViews;} - - const RootParameter& GetRootTable(Uint32 TableInd)const - { - VERIFY_EXPR(TableInd < m_NumRootTables); - return m_pRootTables[TableInd]; - } - - RootParameter& GetRootTable(Uint32 TableInd) - { - VERIFY_EXPR(TableInd < m_NumRootTables); - return m_pRootTables[TableInd]; - } - - const RootParameter& GetRootView(Uint32 ViewInd)const - { - VERIFY_EXPR(ViewInd < m_NumRootViews); - return m_pRootViews[ViewInd]; - } - - RootParameter& GetRootView(Uint32 ViewInd) - { - VERIFY_EXPR(ViewInd < m_NumRootViews); - return m_pRootViews[ViewInd]; - } - - void AddRootView(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType); - void AddRootTable(Uint32 RootIndex, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable = 1); - void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1); - - template<class TOperation> - void ProcessRootTables(TOperation)const; - - bool operator == (const RootParamsManager& RootParams)const; - size_t GetHash()const; - - private: - size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const; - Vk_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges = static_cast<Uint32>(-1)); - - IMemoryAllocator &m_MemAllocator; - std::unique_ptr<void, STDDeleter<void, IMemoryAllocator>> m_pMemory; - Uint32 m_NumRootTables = 0; - Uint32 m_NumRootViews = 0; - Uint32 m_TotalDescriptorRanges = 0; - RootParameter *m_pRootTables = nullptr; - RootParameter *m_pRootViews = nullptr; - }; - - static constexpr Uint8 InvalidRootTableIndex = static_cast<Uint8>(-1); - - // The array below contains array index of a CBV/SRV/UAV root table - // in m_RootParams (NOT the Root Index!), for every variable type - // (static, mutable, dynamic) and every shader type, - // or -1, if the table is not yet assigned to the combination - Uint8 m_SrvCbvUavRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; - // This array contains the same data for Sampler root table - Uint8 m_SamplerRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6]; - - RootParamsManager m_RootParams; - - struct StaticSamplerAttribs - { - StaticSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast<UINT>(-1); - UINT ArraySize = 0; - UINT RegisterSpace = 0; - Vk_SHADER_VISIBILITY ShaderVisibility = static_cast<Vk_SHADER_VISIBILITY>(-1); - - StaticSamplerAttribs(){} - StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, Vk_SHADER_VISIBILITY Visibility) : - SamplerDesc(SamDesc), - ShaderVisibility(Visibility) - {} - }; - // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) - std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > m_StaticSamplers; - - IMemoryAllocator &m_MemAllocator; - - // Commits descriptor handles for static and mutable variables - template<bool PerformResourceTransitions> - void CommitDescriptorHandlesInternal_SM(class RenderDeviceVkImpl *pRenderDeviceVk, - ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx, - bool IsCompute)const; - template<bool PerformResourceTransitions> - // Commits descriptor handles for static, mutable, and dynamic variables - void CommitDescriptorHandlesInternal_SMD(class RenderDeviceVkImpl *pRenderDeviceVk, - ShaderResourceCacheVk& ResourceCache, - class CommandContext &Ctx, - bool IsCompute)const; -}; -#endif -} diff --git a/Graphics/GraphicsEngineVulkan/src/RootSignature.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index f357a860..8c3ec83a 100644 --- a/Graphics/GraphicsEngineVulkan/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -23,7 +23,7 @@ #include "pch.h" -#include "RootSignature.h" +#include "PipelineLayout.h" #include "ShaderResourceLayoutVk.h" #include "ShaderVkImpl.h" #include "CommandContext.h" @@ -36,18 +36,211 @@ namespace Diligent { -#if 0 -RootSignature::RootParamsManager::RootParamsManager(IMemoryAllocator &MemAllocator): + +PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayoutManager(IMemoryAllocator &MemAllocator): m_MemAllocator(MemAllocator), - m_pMemory(nullptr, STDDeleter<void, IMemoryAllocator>(MemAllocator)) + m_DescriptorSetLayouts(STD_ALLOCATOR_RAW_MEM(DescriptorSetLayout, MemAllocator, "Allocator for Decriptor Set Layouts")), + m_LayoutBindings(STD_ALLOCATOR_RAW_MEM(VkDescriptorSetLayoutBinding, MemAllocator, "Allocator for Layout Bindings")) {} -size_t RootSignature::RootParamsManager::GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const + +void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::AddBinding(const VkDescriptorSetLayoutBinding &Binding, IMemoryAllocator &MemAllocator) +{ + VERIFY(VkLayout == VK_NULL_HANDLE, "Descriptor set must not be finalized"); + ReserveMemory(BindingCount + 1, MemAllocator); + pBindings[BindingCount++] = Binding; +} + +size_t PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::GetMemorySize(Uint32 NumBindings) +{ + if(NumBindings == 0) + return 0; + + // Align up to the nearest power of two + size_t MemSize = 0; + if(NumBindings == 1) + MemSize = 1; + else if(NumBindings > 1) + { + // NumBindings = 2^n + // n n-1 2 1 0 + // 2^n = 1 0 ... 0 0 0 + // + // n n-1 2 1 0 + // 2^n-1 = 0 1 ... 1 1 1 + // msb = n-1 + // MemSize = 2^n + + + // NumBindings = 2^n + [1 .. 2^n-1] + // n n-1 + // 2^n = 1 0 ... 1 ... + // + // n n-1 + // 2^n-1 = 1 0 ... + // msb = n + // MemSize = 2^(n+1) + + MemSize = Uint32{1U << PlatformMisc::GetMSB(NumBindings-1)}; + } + VERIFY_EXPR(NumBindings <= MemSize); + +#ifdef _DEBUG + static constexpr size_t MinMemSize = 1; +#else + static constexpr size_t MinMemSize = 16; +#endif + MemSize = std::max(MemSize, MinMemSize); + return MemSize; +} + +void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::ReserveMemory(Uint32 NumBindings, IMemoryAllocator &MemAllocator) +{ + size_t ReservedMemory = GetMemorySize(BindingCount); + size_t RequiredMemory = GetMemorySize(NumBindings); + if(RequiredMemory > ReservedMemory) + { + void *pNewBindings = ALLOCATE(MemAllocator, "Memory buffer for descriptor set layout bindings", RequiredMemory); + if(pBindings != nullptr) + { + memcpy(pNewBindings, pBindings, sizeof(VkDescriptorSetLayoutBinding) * BindingCount); + MemAllocator.Free(pBindings); + } + pBindings = reinterpret_cast<VkDescriptorSetLayoutBinding*>(pNewBindings); + } +} + +void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice, + IMemoryAllocator &MemAllocator, + VkDescriptorSetLayoutBinding* pNewBindings) +{ + VERIFY_EXPR( memcmp(pBindings, pNewBindings, sizeof(VkDescriptorSetLayoutBinding)*BindingCount) == 0 ); + + VkDescriptorSetLayoutCreateInfo SetLayoutCI = {}; + SetLayoutCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + SetLayoutCI.pNext = nullptr; + SetLayoutCI.flags = 0; + SetLayoutCI.bindingCount = BindingCount; + SetLayoutCI.pBindings = pBindings; + VkLayout = LogicalDevice.CreateDescriptorSetLayout(SetLayoutCI); + + MemAllocator.Free(pBindings); + pBindings = pNewBindings; +} + +void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::Release(RenderDeviceVkImpl *pRenderDeviceVk) +{ + pRenderDeviceVk->SafeReleaseVkObject(std::move(VkLayout)); + pBindings = nullptr; + BindingCount = 0; +} + +PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::~DescriptorSetLayout() +{ + VERIFY(VkLayout == VK_NULL_HANDLE, "Vulkan descriptor set layout has not been released. Did you forget to call Release()?"); +} + +bool PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::operator == (const DescriptorSetLayout& rhs)const +{ + if(ShaderVarType != rhs.ShaderVarType || + BindingCount != rhs.BindingCount) + return false; + + for(uint32_t b=0; b < BindingCount; ++b) + { + const auto &B0 = pBindings[b]; + const auto &B1 = rhs.pBindings[b]; + if(B0.binding != B1.binding || + B0.descriptorType != B1.descriptorType || + B0.descriptorCount != B1.descriptorCount || + B0.stageFlags != B1.stageFlags) + return false; + + if( B0.pImmutableSamplers != nullptr && B1.pImmutableSamplers == nullptr || + B0.pImmutableSamplers == nullptr && B1.pImmutableSamplers != nullptr) + return false; + if(B0.pImmutableSamplers != nullptr && B1.pImmutableSamplers != nullptr) + { + // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + // and descriptorCount is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a + // valid pointer to an array of descriptorCount valid VkSampler handles (13.2.1) + if(memcmp(B0.pImmutableSamplers, B1.pImmutableSamplers, sizeof(VkSampler) * B0.descriptorCount) != 0) + return false; + } + } + return true; +} + +void PipelineLayout::DescriptorSetLayoutManager::Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice) +{ + size_t TotalBindings = 0; + for (const auto &Layout : m_DescriptorSetLayouts) + { + TotalBindings += Layout.BindingCount; + } + m_LayoutBindings.resize(TotalBindings); + size_t BindingOffset = 0; + for(size_t i=0; i < m_DescriptorSetLayouts.size(); ++i) + { + auto &Layout = m_DescriptorSetLayouts[i]; + std::copy(Layout.pBindings, Layout.pBindings + Layout.BindingCount, m_LayoutBindings.begin() + BindingOffset); + Layout.Finalize(LogicalDevice, m_MemAllocator, &m_LayoutBindings[BindingOffset]); + BindingOffset += Layout.BindingCount; + } + + VkPipelineLayoutCreateInfo PipelineLayoutCI = {}; + PipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + PipelineLayoutCI.pNext = nullptr; + PipelineLayoutCI.flags = 0; // reserved for future use + PipelineLayoutCI.setLayoutCount = static_cast<uint32_t>(m_DescriptorSetLayouts.size()); + + std::vector<VkDescriptorSetLayout, STDAllocatorRawMem<VkDescriptorSetLayout> > + VkDescrSetLayout(m_DescriptorSetLayouts.size(), + VK_NULL_HANDLE, + STD_ALLOCATOR_RAW_MEM(VkDescriptorSetLayout, m_MemAllocator, "Allocator for vector<VkDescriptorSetLayout>")); + for(size_t i=0; i < m_DescriptorSetLayouts.size(); ++i) + VkDescrSetLayout[i] = m_DescriptorSetLayouts[i].VkLayout; + PipelineLayoutCI.pSetLayouts = !VkDescrSetLayout.empty() ? VkDescrSetLayout.data() : nullptr; + PipelineLayoutCI.pushConstantRangeCount = 0; + PipelineLayoutCI.pPushConstantRanges = nullptr; + m_VkPipelineLayout = LogicalDevice.CreatePipelineLayout(PipelineLayoutCI); + + VERIFY_EXPR(BindingOffset == TotalBindings); +} + +void PipelineLayout::DescriptorSetLayoutManager::Release(RenderDeviceVkImpl *pRenderDeviceVk) +{ + for (auto &Layout : m_DescriptorSetLayouts) + Layout.Release(pRenderDeviceVk); + + pRenderDeviceVk->SafeReleaseVkObject(std::move(m_VkPipelineLayout)); +} + +PipelineLayout::DescriptorSetLayoutManager::~DescriptorSetLayoutManager() +{ + VERIFY(m_VkPipelineLayout == VK_NULL_HANDLE, "Vulkan pipeline layout has not been released. Did you forget to call Release()?"); +} + +bool PipelineLayout::DescriptorSetLayoutManager::operator == (const DescriptorSetLayoutManager& rhs)const +{ + if(m_DescriptorSetLayouts.size() != rhs.m_DescriptorSetLayouts.size()) + return false; + + for(size_t i=0; i < m_DescriptorSetLayouts.size(); ++i) + if(m_DescriptorSetLayouts[i] != rhs.m_DescriptorSetLayouts[i]) + return false; + + return m_VarTypeToDescrSetLayout == rhs.m_VarTypeToDescrSetLayout; +} + + +#if 0 +size_t PipelineLayout::DescriptorSetLayoutManager::GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const { return sizeof(RootParameter) * (m_NumRootTables + NumExtraRootTables + m_NumRootViews + NumExtraRootViews) + sizeof(Vk_DESCRIPTOR_RANGE) * (m_TotalDescriptorRanges + NumExtraDescriptorRanges); } -Vk_DESCRIPTOR_RANGE* RootSignature::RootParamsManager::Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges) +Vk_DESCRIPTOR_RANGE* PipelineLayout::DescriptorSetLayoutManager::Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges) { VERIFY(NumExtraRootTables > 0 || NumExtraRootViews > 0 || NumExtraDescriptorRanges > 0, "At least one root table, root view or descriptor range must be added" ); auto MemorySize = GetRequiredMemorySize(NumExtraRootTables, NumExtraRootViews, NumExtraDescriptorRanges); @@ -92,27 +285,42 @@ Vk_DESCRIPTOR_RANGE* RootSignature::RootParamsManager::Extend(Uint32 NumExtraRoo return pCurrDescriptorRangePtr; } -void RootSignature::RootParamsManager::AddRootView(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) +void PipelineLayout::DescriptorSetLayoutManager::AddRootView(Vk_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) { auto *pRangePtr = Extend(0, 1, 0); VERIFY_EXPR((char*)pRangePtr == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); new(m_pRootViews + m_NumRootViews-1) RootParameter(ParameterType, RootIndex, Register, 0u, Visibility, VarType); } +#endif -void RootSignature::RootParamsManager::AddRootTable(Uint32 RootIndex, Vk_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable) +PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout& PipelineLayout::DescriptorSetLayoutManager::GetDescriptorSet(SHADER_VARIABLE_TYPE VarType) { - auto *pRangePtr = Extend(1, 0, NumRangesInNewTable); - VERIFY_EXPR( (char*)(pRangePtr + NumRangesInNewTable) == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); - new(m_pRootTables + m_NumRootTables-1) RootParameter(Vk_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, RootIndex, NumRangesInNewTable, pRangePtr, Visibility, VarType); + auto DescrSetLayoutInd = m_VarTypeToDescrSetLayout[VarType]; + if(DescrSetLayoutInd < 0) + { + DescrSetLayoutInd = static_cast<Int8>(m_DescriptorSetLayouts.size()); + m_DescriptorSetLayouts.emplace_back(VarType); + m_VarTypeToDescrSetLayout[VarType] = DescrSetLayoutInd; + } + + return m_DescriptorSetLayouts[DescrSetLayoutInd]; } -void RootSignature::RootParamsManager::AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges) +#if 0 +void PipelineLayout::DescriptorSetLayoutManager::AddDescriptorSet(SHADER_VARIABLE_TYPE VarType) +{ + VERIFY(m_VkPipelineLayout == VK_NULL_HANDLE, "Pipeline layout must not be finalized to add descriptor set"); + m_DescriptorSetLayouts.emplace_back(VarType); +} + + +void PipelineLayout::DescriptorSetLayoutManager::AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges) { auto *pRangePtr = Extend(0, 0, NumExtraRanges, RootTableInd); VERIFY_EXPR( (char*)pRangePtr == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0)); } -bool RootSignature::RootParamsManager::operator == (const RootParamsManager& RootParams)const +bool PipelineLayout::DescriptorSetLayoutManager::operator == (const DescriptorSetLayoutManager& RootParams)const { if (m_NumRootTables != RootParams.m_NumRootTables || m_NumRootViews != RootParams.m_NumRootViews) @@ -137,7 +345,7 @@ bool RootSignature::RootParamsManager::operator == (const RootParamsManager& Roo return true; } -size_t RootSignature::RootParamsManager::GetHash()const +size_t PipelineLayout::DescriptorSetLayoutManager::GetHash()const { size_t hash = ComputeHash(m_NumRootTables, m_NumRootViews); for (Uint32 rv = 0; rv < m_NumRootViews; ++rv) @@ -149,7 +357,7 @@ size_t RootSignature::RootParamsManager::GetHash()const return hash; } -RootSignature::RootSignature() : +PipelineLayout::PipelineLayout() : m_RootParams(GetRawAllocator()), m_MemAllocator(GetRawAllocator()), m_StaticSamplers( STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector<StaticSamplerAttribs>") ) @@ -250,7 +458,7 @@ Vk_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(Vk_DESCRIPTOR_RANGE_TYPE RangeType } -void RootSignature::InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &SamplerAttribs) +void PipelineLayout::InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &SamplerAttribs) { auto ShaderVisibility = GetShaderVisibility(ShaderType); auto SamplerFound = false; @@ -274,7 +482,7 @@ void RootSignature::InitStaticSampler(SHADER_TYPE ShaderType, const String &Text } // http://diligentgraphics.com/diligent-engine/architecture/Vk/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object -void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderType, +void PipelineLayout::AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, Vk_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, // Output parameter @@ -344,7 +552,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderType, #ifdef _DEBUG -void RootSignature::dbgVerifyRootParameters()const +void PipelineLayout::dbgVerifyRootParameters()const { Uint32 dbgTotalSrvCbvUavSlots = 0; Uint32 dbgTotalSamplerSlots = 0; @@ -398,7 +606,7 @@ void RootSignature::dbgVerifyRootParameters()const } #endif -void RootSignature::AllocateStaticSamplers(IShader* const*ppShaders, Uint32 NumShaders) +void PipelineLayout::AllocateStaticSamplers(IShader* const*ppShaders, Uint32 NumShaders) { Uint32 TotalSamplers = 0; for(Uint32 s=0;s < NumShaders; ++s) @@ -418,7 +626,7 @@ void RootSignature::AllocateStaticSamplers(IShader* const*ppShaders, Uint32 NumS } } -void RootSignature::Finalize(IVkDevice *pVkDevice) +void PipelineLayout::Finalize(IVkDevice *pVkDevice) { for(Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) { @@ -437,8 +645,8 @@ void RootSignature::Finalize(IVkDevice *pVkDevice) dbgVerifyRootParameters(); #endif - Vk_ROOT_SIGNATURE_DESC rootSignatureDesc; - rootSignatureDesc.Flags = Vk_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + Vk_ROOT_SIGNATURE_DESC PipelineLayoutDesc; + PipelineLayoutDesc.Flags = Vk_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; auto TotalParams = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); std::vector<Vk_ROOT_PARAMETER, STDAllocatorRawMem<Vk_ROOT_PARAMETER> > VkParameters( TotalParams, Vk_ROOT_PARAMETER(), STD_ALLOCATOR_RAW_MEM(Vk_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector<Vk_ROOT_PARAMETER>") ); @@ -458,14 +666,14 @@ void RootSignature::Finalize(IVkDevice *pVkDevice) } - rootSignatureDesc.NumParameters = static_cast<UINT>(VkParameters.size()); - rootSignatureDesc.pParameters = VkParameters.size() ? VkParameters.data() : nullptr; + PipelineLayoutDesc.NumParameters = static_cast<UINT>(VkParameters.size()); + PipelineLayoutDesc.pParameters = VkParameters.size() ? VkParameters.data() : nullptr; UINT TotalVkStaticSamplers = 0; for(const auto &StSam : m_StaticSamplers) TotalVkStaticSamplers += StSam.ArraySize; - rootSignatureDesc.NumStaticSamplers = TotalVkStaticSamplers; - rootSignatureDesc.pStaticSamplers = nullptr; + PipelineLayoutDesc.NumStaticSamplers = TotalVkStaticSamplers; + PipelineLayoutDesc.pStaticSamplers = nullptr; std::vector<Vk_STATIC_SAMPLER_DESC, STDAllocatorRawMem<Vk_STATIC_SAMPLER_DESC> > VkStaticSamplers( STD_ALLOCATOR_RAW_MEM(Vk_STATIC_SAMPLER_DESC, GetRawAllocator(), "Allocator for vector<Vk_STATIC_SAMPLER_DESC>") ); VkStaticSamplers.reserve(TotalVkStaticSamplers); if ( !m_StaticSamplers.empty() ) @@ -495,7 +703,7 @@ void RootSignature::Finalize(IVkDevice *pVkDevice) ); } } - rootSignatureDesc.pStaticSamplers = VkStaticSamplers.data(); + PipelineLayoutDesc.pStaticSamplers = VkStaticSamplers.data(); // Release static samplers array, we no longer need it std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > EmptySamplers( STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector<StaticSamplerAttribs>") ); @@ -507,25 +715,25 @@ void RootSignature::Finalize(IVkDevice *pVkDevice) CComPtr<ID3DBlob> signature; CComPtr<ID3DBlob> error; - HRESULT hr = VkSerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); - hr = pVkDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pVkRootSignature), reinterpret_cast<void**>( static_cast<IVkRootSignature**>(&m_pVkRootSignature))); + HRESULT hr = VkSerializePipelineLayout(&PipelineLayoutDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); + hr = pVkDevice->CreatePipelineLayout(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pVkPipelineLayout), reinterpret_cast<void**>( static_cast<IVkPipelineLayout**>(&m_pVkPipelineLayout))); CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); bool bHasDynamicResources = m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC]!=0 || m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC]!=0; if(bHasDynamicResources) { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<false>; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<true>; + CommitDescriptorHandles = &PipelineLayout::CommitDescriptorHandlesInternal_SMD<false>; + TransitionAndCommitDescriptorHandles = &PipelineLayout::CommitDescriptorHandlesInternal_SMD<true>; } else { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<false>; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<true>; + CommitDescriptorHandles = &PipelineLayout::CommitDescriptorHandlesInternal_SM<false>; + TransitionAndCommitDescriptorHandles = &PipelineLayout::CommitDescriptorHandlesInternal_SM<true>; } } //http://diligentgraphics.com/diligent-engine/architecture/Vk/shader-resource-cache#Initializing-the-Cache-for-Shader-Resource-Binding-Object -void RootSignature::InitResourceCache(RenderDeviceVkImpl *pDeviceVkImpl, ShaderResourceCacheVk& ResourceCache, IMemoryAllocator &CacheMemAllocator)const +void PipelineLayout::InitResourceCache(RenderDeviceVkImpl *pDeviceVkImpl, ShaderResourceCacheVk& ResourceCache, IMemoryAllocator &CacheMemAllocator)const { // Get root table size for every root index // m_RootParams keeps root tables sorted by the array index, not the root index @@ -775,7 +983,7 @@ void DbgVerifyResourceState(ShaderResourceCacheVk::Resource &Res, #endif template<class TOperation> -__forceinline void RootSignature::RootParamsManager::ProcessRootTables(TOperation Operation)const +__forceinline void PipelineLayout::DescriptorSetLayoutManager::ProcessRootTables(TOperation Operation)const { for(Uint32 rt = 0; rt < m_NumRootTables; ++rt) { @@ -823,7 +1031,7 @@ __forceinline void ProcessCachedTableResources(Uint32 RootInd, template<bool PerformResourceTransitions> -void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceVkImpl *pRenderDeviceVk, +void PipelineLayout::CommitDescriptorHandlesInternal_SMD(RenderDeviceVkImpl *pRenderDeviceVk, ShaderResourceCacheVk& ResourceCache, CommandContext &Ctx, bool IsCompute)const @@ -932,7 +1140,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceVkImpl *pRen } template<bool PerformResourceTransitions> -void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceVkImpl *pRenderDeviceVk, +void PipelineLayout::CommitDescriptorHandlesInternal_SM(RenderDeviceVkImpl *pRenderDeviceVk, ShaderResourceCacheVk& ResourceCache, CommandContext &Ctx, bool IsCompute)const @@ -983,7 +1191,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceVkImpl *pRend } -void RootSignature::TransitionResources(ShaderResourceCacheVk& ResourceCache, +void PipelineLayout::TransitionResources(ShaderResourceCacheVk& ResourceCache, class CommandContext &Ctx)const { m_RootParams.ProcessRootTables( @@ -1000,7 +1208,7 @@ void RootSignature::TransitionResources(ShaderResourceCacheVk& ResourceCache, } -void RootSignature::CommitRootViews(ShaderResourceCacheVk& ResourceCache, +void PipelineLayout::CommitRootViews(ShaderResourceCacheVk& ResourceCache, CommandContext &Ctx, bool IsCompute, Uint32 ContextId)const diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 611d814a..8fccd1e8 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -177,35 +177,13 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren CSStage.pName = "main"; CSStage.pSpecializationInfo = nullptr; - m_Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, m_Desc.Name); - #if 0 - Vk_COMPUTE_PIPELINE_STATE_DESC VkPSODesc = {}; - VkPSODesc.pRootSignature = nullptr; - - auto *pByteCode = ValidatedCast<ShaderVkImpl>(ComputePipeline.pCS)->GetShaderByteCode(); - VkPSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); - VkPSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); - - // For single GPU operation, set this to zero. If there are multiple GPU nodes, - // set bits to identify the nodes (the device's physical adapters) for which the - // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node. - VkPSODesc.NodeMask = 0; - - VkPSODesc.CachedPSO.pCachedBlob = nullptr; - VkPSODesc.CachedPSO.CachedBlobSizeInBytes = 0; - - // The only valid bit is Vk_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. - VkPSODesc.Flags = Vk_PIPELINE_STATE_FLAG_NONE; - ParseShaderResourceLayout(ComputePipeline.pCS); m_RootSig.Finalize(pVkDevice); VkPSODesc.pRootSignature = m_RootSig.GetVkRootSignature(); - - HRESULT hr = pVkDevice->CreateComputePipelineState(&VkPSODesc, __uuidof(IVkPipelineState), reinterpret_cast<void**>( static_cast<IVkPipelineState**>(&m_pVkPSO)) ); - if(FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create pipeline state"); #endif + + m_Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, m_Desc.Name); } else { |
