From cc11a1af8e1a0f8582914aa888b53e53883fdfaf Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 5 Oct 2020 10:03:34 -0700 Subject: Fixed typo --- Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 6a81faba..81d6753c 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -238,7 +238,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E VK_KHR_MAINTENANCE1_EXTENSION_NAME // To allow negative viewport height }; - const auto& DeiceExtFeatures = PhysicalDevice->GetExtFeatures(); + const auto& DeviceExtFeatures = PhysicalDevice->GetExtFeatures(); #define ENABLE_FEATURE(IsFeatureSupported, Feature, FeatureName) \ do \ @@ -248,23 +248,23 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E } while (false) - auto MeshShaderFeats = DeiceExtFeatures.MeshShader; + auto MeshShaderFeats = DeviceExtFeatures.MeshShader; ENABLE_FEATURE(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are"); - auto ShaderFloat16Int8 = DeiceExtFeatures.ShaderFloat16Int8; + auto ShaderFloat16Int8 = DeviceExtFeatures.ShaderFloat16Int8; // clang-format off ENABLE_FEATURE(ShaderFloat16Int8.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are"); ENABLE_FEATURE(ShaderFloat16Int8.shaderInt8 != VK_FALSE, ShaderInt8, "8-bit int shader operations are"); // clang-format on - auto Storage16BitFeats = DeiceExtFeatures.Storage16Bit; + auto Storage16BitFeats = DeviceExtFeatures.Storage16Bit; // clang-format off ENABLE_FEATURE(Storage16BitFeats.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is"); ENABLE_FEATURE(Storage16BitFeats.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is"); ENABLE_FEATURE(Storage16BitFeats.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are"); // clang-format on - auto Storage8BitFeats = DeiceExtFeatures.Storage8Bit; + auto Storage8BitFeats = DeviceExtFeatures.Storage8Bit; // clang-format off ENABLE_FEATURE(Storage8BitFeats.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); ENABLE_FEATURE(Storage8BitFeats.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is"); -- cgit v1.2.3 From c75307ce6d2d3d18b9ad7ba0bbcf2e2e59ba5a2c Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 7 Oct 2020 14:12:45 -0700 Subject: Few minor updates --- Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 6e6c142f..53a92a59 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -87,10 +87,9 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR ShaderResourceBindingVkImpl::~ShaderResourceBindingVkImpl() { - PipelineStateVkImpl* pPSO = ValidatedCast(m_pPSO); for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + auto& VarDataAllocator = m_pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); m_pShaderVarMgrs[s].DestroyVariables(VarDataAllocator); m_pShaderVarMgrs[s].~ShaderVariableManagerVk(); } -- cgit v1.2.3 From 2250c36e3570a949104a3a49b02546a3dd8f1917 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 7 Oct 2020 14:57:33 -0700 Subject: Updated PipelineState[D3D11,D3D12,Vk]Impl to allocate single chunk of memory for resource layout, resource cache and var managers objects --- .../src/PipelineStateVkImpl.cpp | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 5c165e32..75dd3263 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -159,15 +159,21 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - // Initialize shader resource layouts - auto& ShaderResLayoutAllocator = GetRawAllocator(); - std::array, MAX_SHADERS_IN_PIPELINE> ShaderResources; std::array, MAX_SHADERS_IN_PIPELINE> ShaderSPIRVs; - m_ShaderResourceLayouts = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", ShaderResourceLayoutVk, m_NumShaders * 2); - m_StaticResCaches = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheVk", ShaderResourceCacheVk, m_NumShaders); - m_StaticVarsMgrs = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", ShaderVariableManagerVk, m_NumShaders); + // clang-format off + static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); + // clang-format on + const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * m_NumShaders; + auto* const pRawMem = + ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); + + m_ShaderResourceLayouts = reinterpret_cast(pRawMem); + m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + m_NumShaders * 2); + m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + m_NumShaders); for (Uint32 s = 0; s < m_NumShaders; ++s) { @@ -182,7 +188,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk{LogicalDevice}; auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; - pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, m_Desc.ResourceLayout, m_StaticResCaches[s]); + pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; } @@ -507,9 +513,10 @@ PipelineStateVkImpl::~PipelineStateVkImpl() m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); } - RawAllocator.Free(m_ShaderResourceLayouts); - RawAllocator.Free(m_StaticResCaches); - RawAllocator.Free(m_StaticVarsMgrs); + // m_ShaderResourceLayouts, m_StaticResCaches and m_StaticVarsMgrs are allocted in + // contiguous chunks of memory. + void* pRawMem = m_ShaderResourceLayouts; + RawAllocator.Free(pRawMem); } IMPLEMENT_QUERY_INTERFACE(PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase) -- cgit v1.2.3 From 2b396d236ab33dfe9c0defbe401d354ed3fb34f9 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 21:45:01 +0300 Subject: removed strong references to shaders in PSO --- .../include/PipelineStateVkImpl.hpp | 15 +- .../include/ShaderResourceBindingVkImpl.hpp | 2 +- .../include/ShaderResourceLayoutVk.hpp | 118 ++-- .../include/VulkanTypeConversions.hpp | 3 + .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 22 - .../src/PipelineStateVkImpl.cpp | 602 +++++++++++---------- .../src/ShaderResourceBindingVkImpl.cpp | 8 +- .../src/ShaderResourceLayoutVk.cpp | 346 +++++++----- .../src/VulkanTypeConversions.cpp | 23 + 9 files changed, 595 insertions(+), 544 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index d1732211..303496bb 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -56,6 +56,7 @@ class PipelineStateVkImpl final : public PipelineStateBase; + using ShaderSPIRVs_t = std::vector>; PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateCreateInfo& CreateInfo); ~PipelineStateVkImpl(); @@ -104,7 +105,7 @@ public: const ShaderResourceLayoutVk& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); + VERIFY_EXPR(ShaderInd < m_NumShaderTypes); return m_ShaderResourceLayouts[ShaderInd]; } @@ -127,19 +128,19 @@ public: private: const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_ShaderResourceLayouts[m_NumShaders + ShaderInd]; + VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + return m_ShaderResourceLayouts[m_NumShaderTypes + ShaderInd]; } const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); + VERIFY_EXPR(ShaderInd < m_NumShaderTypes); return m_StaticResCaches[ShaderInd]; } ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); + VERIFY_EXPR(ShaderInd < m_NumShaderTypes); return m_StaticVarsMgrs[ShaderInd]; } @@ -150,14 +151,12 @@ private: // SRB memory allocator must be declared before m_pDefaultShaderResBinding SRBMemoryAllocator m_SRBMemAllocator; - std::array m_ShaderModules = {}; - VulkanUtilities::PipelineWrapper m_Pipeline; PipelineLayout m_PipelineLayout; // Resource layout index in m_ShaderResourceLayouts array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; + std::array m_ResourceLayoutIndex; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp index 026bb9da..85230b02 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -81,7 +81,7 @@ private: // Resource layout index in m_ShaderResourceCache array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; + std::array m_ResourceLayoutIndex; bool m_bStaticResourcesInitialized = false; Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index a6d20641..28defd0f 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -115,6 +115,9 @@ namespace Diligent class ShaderResourceLayoutVk { public: + using ShaderStages_t = std::vector>; + using ShaderSPIRVs_t = std::vector>; + ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : m_LogicalDevice{LogicalDevice} { @@ -131,23 +134,22 @@ public: // This method is called by PipelineStateVkImpl class instance to initialize static // shader resource layout and the cache - void InitializeStaticResourceLayout(std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderResourceCacheVk& StaticResourceCache); + void InitializeStaticResourceLayout(IShader* pShader, + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + ShaderResourceCacheVk& StaticResourceCache); // This method is called by PipelineStateVkImpl class instance to initialize resource // layouts for all shader stages in the pipeline. - static void Initialize(IRenderDevice* pRenderDevice, - Uint32 NumShaders, - ShaderResourceLayoutVk Layouts[], - std::shared_ptr pShaderResources[], - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - std::vector SPIRVs[], - class PipelineLayout& PipelineLayout, - bool VerifyVariables, - bool VerifyStaticSamplers); + static void Initialize(IRenderDevice* pRenderDevice, + const ShaderStages_t& ShaderStages, + ShaderResourceLayoutVk Layouts[], + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + ShaderSPIRVs_t& SPIRVs, + class PipelineLayout& PipelineLayout, + bool VerifyVariables, + bool VerifyStaticSamplers); // sizeof(VkResource) == 24 (x64) struct VkResource @@ -175,33 +177,21 @@ public: /* 7.5 */ const Uint32 VariableType : VariableTypeBits; /* 7.7 */ const Uint32 ImmutableSamplerAssigned : ImmutableSamplerFlagBits; -/* 8 */ const SPIRVShaderResourceAttribs& SpirvAttribs; -/* 16 */ const ShaderResourceLayoutVk& ParentResLayout; - - VkResource(const ShaderResourceLayoutVk& _ParentLayout, - const SPIRVShaderResourceAttribs& _SpirvAttribs, - SHADER_RESOURCE_VARIABLE_TYPE _VariableType, - uint32_t _Binding, - uint32_t _DescriptorSet, - Uint32 _CacheOffset, - Uint32 _SamplerInd, - bool _ImmutableSamplerAssigned = false)noexcept : - Binding {static_cast(_Binding) }, - DescriptorSet {static_cast(_DescriptorSet)}, - CacheOffset {_CacheOffset }, - SamplerInd {_SamplerInd }, - VariableType {_VariableType }, - ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, - SpirvAttribs {_SpirvAttribs }, - ParentResLayout {_ParentLayout } - { - VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) ); - VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) ); - VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max() ); - VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); - } +/* 8 */ const SPIRVShaderResourceAttribs SpirvAttribs; +/* 16 */ const ShaderResourceLayoutVk& ParentResLayout; // clang-format on + VkResource(const ShaderResourceLayoutVk& _ParentLayout, + const SPIRVShaderResourceAttribs& _SpirvAttribs, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + uint32_t _Binding, + uint32_t _DescriptorSet, + Uint32 _CacheOffset, + Uint32 _SamplerInd, + bool _ImmutableSamplerAssigned = false) noexcept; + + ~VkResource(); + // Checks if a resource is bound in ResourceCache at the given ArrayIndex bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const; @@ -279,11 +269,10 @@ public: #ifdef DILIGENT_DEVELOPMENT bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache) const; - static void dvpVerifyResourceLayoutDesc(Uint32 NumShaders, - const std::shared_ptr pShaderResources[], - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - bool VerifyVariables, - bool VerifyStaticSamplers); + static void dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + bool VerifyVariables, + bool VerifyStaticSamplers); #endif Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const @@ -300,13 +289,10 @@ public: const Char* GetShaderName() const { - return m_pResources->GetShaderName(); + return ""; // AZ TODO } - SHADER_TYPE GetShaderType() const - { - return m_pResources->GetShaderType(); - } + SHADER_TYPE GetShaderType() const { return m_ShaderType; } const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const { @@ -315,7 +301,7 @@ public: return Resources[GetResourceOffset(VarType, r)]; } - bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedSamplers(); } + bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; } private: Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const @@ -346,16 +332,12 @@ private: return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; } - void AllocateMemory(std::shared_ptr pSrcResources, - IMemoryAllocator& Allocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - bool AllocateImmutableSamplers); - - Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, - Uint32 CurrResourceCount, - SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) const; + void AllocateMemory(IShader* pShader, + IMemoryAllocator& Allocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + bool AllocateImmutableSamplers); using ImmutableSamplerPtrType = RefCntAutoPtr; ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n) noexcept @@ -366,16 +348,16 @@ private: } // clang-format off -/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; -/* 8 */ std::unique_ptr > m_ResourceBuffer; +/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; +/* 8 */ std::unique_ptr > m_ResourceBuffer; + +/*24 */ std::array m_NumResources = {}; - // We must use shared_ptr to reference ShaderResources instance, because - // there may be multiple objects referencing the same set of resources -/*24 */ std::shared_ptr m_pResources; +/*32 */ Uint32 m_NumImmutableSamplers = 0; +/*36 */ bool m_IsUsingSeparateSamplers = false; +/*37 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; -/*40 */ std::array m_NumResources = {}; -/*48 */ Uint32 m_NumImmutableSamplers = 0; -/*56*/ // End of class +/*40 */ // End of class // clang-format on }; diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp index dbba5b7e..1e6749f1 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp @@ -82,4 +82,7 @@ ATTACHMENT_STORE_OP VkAttachmentStoreOpToAttachmentStoreOp(VkAttachmentStoreOp V VkPipelineStageFlags PipelineStageFlagsToVkPipelineStageFlags(PIPELINE_STAGE_FLAGS PipelineStageFlags); VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags); + +VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType); + } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 2fd063c9..6ed84171 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -40,28 +40,6 @@ namespace Diligent { - -static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType) -{ - static_assert(SHADER_TYPE_LAST == 0x080, "Please update the switch below to handle the new shader type"); - switch (ShaderType) - { - // clang-format off - case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT; - case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT; - case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT; - case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT; - case SHADER_TYPE_AMPLIFICATION: return VK_SHADER_STAGE_TASK_BIT_NV; - case SHADER_TYPE_MESH: return VK_SHADER_STAGE_MESH_BIT_NV; - // clang-format on - default: - UNEXPECTED("Unknown shader type"); - return VK_SHADER_STAGE_VERTEX_BIT; - } -} - class ResourceTypeToVkDescriptorType { public: diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 75dd3263..29d16239 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -129,352 +129,376 @@ RenderPassDesc PipelineStateVkImpl::GetImplicitRenderPassDesc( return RPDesc; } -static std::vector StripReflection(const std::vector& OriginalSPIRV) +static bool StripReflection(std::vector& SPIRV) { #if DILIGENT_NO_HLSL - return OriginalSPIRV; + return false; #else std::vector StrippedSPIRV; spvtools::Optimizer SpirvOptimizer(SPV_ENV_VULKAN_1_0); // Decorations defined in SPV_GOOGLE_hlsl_functionality1 are the only instructions // removed by strip-reflect-info pass. SPIRV offsets become INVALID after this operation. SpirvOptimizer.RegisterPass(spvtools::CreateStripReflectInfoPass()); - auto res = SpirvOptimizer.Run(OriginalSPIRV.data(), OriginalSPIRV.size(), &StrippedSPIRV); - if (!res) + if (SpirvOptimizer.Run(SPIRV.data(), SPIRV.size(), &StrippedSPIRV)) { - // Optimized SPIRV may be invalid - StrippedSPIRV.clear(); + SPIRV = std::move(StrippedSPIRV); + return true; } - return StrippedSPIRV; + else + return false; #endif } -PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDeviceVk, - const PipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, - m_SRBMemAllocator{GetRawAllocator()} +static void InitializeShaderStages(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, + const PipelineStateVkImpl::ShaderStages_t& ShaderStages, + PipelineStateVkImpl::ShaderSPIRVs_t& ShaderSPIRVs, + std::vector& ShaderModules, + std::vector& Stages) { - m_ResourceLayoutIndex.fill(-1); - - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); + VERIFY_EXPR(ShaderStages.size() == ShaderSPIRVs.size()); - std::array, MAX_SHADERS_IN_PIPELINE> ShaderResources; - std::array, MAX_SHADERS_IN_PIPELINE> ShaderSPIRVs; - - // clang-format off - static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); - // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * m_NumShaders; - auto* const pRawMem = - ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); - - m_ShaderResourceLayouts = reinterpret_cast(pRawMem); - m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + m_NumShaders * 2); - m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + m_NumShaders); - - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - auto* pShaderVk = GetShader(s); - ShaderResources[s] = pShaderVk->GetShaderResources(); - ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); - - const auto ShaderType = pShaderVk->GetDesc().ShaderType; - const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); - m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); - - auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk{LogicalDevice}; - auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; - pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); - - new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; - } - ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), - m_Desc.ResourceLayout, ShaderSPIRVs.data(), m_PipelineLayout, - (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, - (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); - m_PipelineLayout.Finalize(LogicalDevice); + auto* pShaderVk = ValidatedCast(ShaderStages[s].second); + auto& SPIRV = ShaderSPIRVs[s]; + const auto ShaderType = ShaderStages[s].first; - if (m_Desc.SRBAllocationGranularity > 1) - { - std::array ShaderVariableDataSizes = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + VkPipelineShaderStageCreateInfo StageCI = {}; - Uint32 UnusedNumVars = 0; - ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(m_ShaderResourceLayouts[s], AllowedVarTypes, _countof(AllowedVarTypes), UnusedNumVars); - } - - Uint32 NumSets = 0; - auto DescriptorSetSizes = m_PipelineLayout.GetDescriptorSetSizes(NumSets); - auto CacheMemorySize = ShaderResourceCacheVk::GetRequiredMemorySize(NumSets, DescriptorSetSizes.data()); - - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, m_NumShaders, ShaderVariableDataSizes.data(), 1, &CacheMemorySize); - } - - // Create shader modules and initialize shader stages - std::array ShaderStages = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - auto* pShaderVk = GetShader(s); - auto ShaderType = pShaderVk->GetDesc().ShaderType; - - auto& StageCI = ShaderStages[s]; StageCI.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; StageCI.pNext = nullptr; StageCI.flags = 0; // reserved for future use - switch (ShaderType) - { - // clang-format off - case SHADER_TYPE_VERTEX: StageCI.stage = VK_SHADER_STAGE_VERTEX_BIT; break; - case SHADER_TYPE_HULL: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; break; - case SHADER_TYPE_DOMAIN: StageCI.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; break; - case SHADER_TYPE_GEOMETRY: StageCI.stage = VK_SHADER_STAGE_GEOMETRY_BIT; break; - case SHADER_TYPE_PIXEL: StageCI.stage = VK_SHADER_STAGE_FRAGMENT_BIT; break; - case SHADER_TYPE_COMPUTE: StageCI.stage = VK_SHADER_STAGE_COMPUTE_BIT; break; - case SHADER_TYPE_AMPLIFICATION: StageCI.stage = VK_SHADER_STAGE_TASK_BIT_NV; break; - case SHADER_TYPE_MESH: StageCI.stage = VK_SHADER_STAGE_MESH_BIT_NV; break; - default: UNEXPECTED("Unknown shader type"); - // clang-format on - } + StageCI.stage = ShaderTypeToVkShaderStageFlagBit(ShaderType); VkShaderModuleCreateInfo ShaderModuleCI = {}; ShaderModuleCI.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; ShaderModuleCI.pNext = nullptr; ShaderModuleCI.flags = 0; - const auto& SPIRV = ShaderSPIRVs[s]; // We have to strip reflection instructions to fix the follownig validation error: // SPIR-V module not valid: DecorateStringGOOGLE requires one of the following extensions: SPV_GOOGLE_decorate_string // Optimizer also performs validation and may catch problems with the byte code. - auto StrippedSPIRV = StripReflection(SPIRV); - if (!StrippedSPIRV.empty()) - { - ShaderModuleCI.codeSize = StrippedSPIRV.size() * sizeof(uint32_t); - ShaderModuleCI.pCode = StrippedSPIRV.data(); - } - else - { + if (!StripReflection(SPIRV)) LOG_ERROR("Failed to strip reflection information from shader '", pShaderVk->GetDesc().Name, "'. This may indicate a problem with the byte code."); - ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); - ShaderModuleCI.pCode = SPIRV.data(); - } - m_ShaderModules[s] = LogicalDevice.CreateShaderModule(ShaderModuleCI, pShaderVk->GetDesc().Name); + ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); + ShaderModuleCI.pCode = SPIRV.data(); + + ShaderModules.push_back(LogicalDevice.CreateShaderModule(ShaderModuleCI, pShaderVk->GetDesc().Name)); - StageCI.module = m_ShaderModules[s]; + StageCI.module = ShaderModules.back(); StageCI.pName = pShaderVk->GetEntryPoint(); StageCI.pSpecializationInfo = nullptr; + + Stages.push_back(StageCI); } - // Create pipeline - if (m_Desc.IsComputePipeline()) - { - auto& ComputePipeline = m_Desc.ComputePipeline; + VERIFY_EXPR(ShaderModules.size() == Stages.size()); +} + + +static void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk, + std::vector& Stages, + const PipelineLayout& Layout, + const PipelineStateDesc& Desc, + VulkanUtilities::PipelineWrapper& Pipeline) +{ + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); + + VkComputePipelineCreateInfo PipelineCI = {}; + + PipelineCI.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + PipelineCI.pNext = nullptr; +#ifdef DILIGENT_DEBUG + PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; +#endif + PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from + PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from - if (ComputePipeline.pCS == nullptr) - LOG_ERROR_AND_THROW("Compute shader is not set in the pipeline desc"); + PipelineCI.stage = Stages[0]; + PipelineCI.layout = Layout.GetVkPipelineLayout(); - VkComputePipelineCreateInfo PipelineCI = {}; + Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); +} + + +static void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk, + std::vector& Stages, + const PipelineLayout& Layout, + const PipelineStateDesc& Desc, + VulkanUtilities::PipelineWrapper& Pipeline, + RefCntAutoPtr& pRenderPass) +{ + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); + const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); + auto& GraphicsPipeline = Desc.GraphicsPipeline; + auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); + + if (pRenderPass == nullptr) + { + RenderPassCache::RenderPassCacheKey Key{ + GraphicsPipeline.NumRenderTargets, + GraphicsPipeline.SmplDesc.Count, + GraphicsPipeline.RTVFormats, + GraphicsPipeline.DSVFormat}; + pRenderPass = RPCache.GetRenderPass(Key); + } + + VkGraphicsPipelineCreateInfo PipelineCI = {}; - PipelineCI.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - PipelineCI.pNext = nullptr; + PipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + PipelineCI.pNext = nullptr; #ifdef DILIGENT_DEBUG - PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; + PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; #endif - PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from - PipelineCI.basePipelineIndex = 0; // an index into the pCreateInfos parameter to use as a pipeline to derive from - PipelineCI.stage = ShaderStages[0]; - PipelineCI.layout = m_PipelineLayout.GetVkPipelineLayout(); + PipelineCI.stageCount = static_cast(Stages.size()); + PipelineCI.pStages = Stages.data(); + PipelineCI.layout = Layout.GetVkPipelineLayout(); + + VkPipelineVertexInputStateCreateInfo VertexInputStateCI = {}; + + std::array BindingDescriptions; + std::array AttributeDescription; + InputLayoutDesc_To_VkVertexInputStateCI(GraphicsPipeline.InputLayout, VertexInputStateCI, BindingDescriptions, AttributeDescription); + PipelineCI.pVertexInputState = &VertexInputStateCI; - m_Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, m_Desc.Name); + + VkPipelineInputAssemblyStateCreateInfo InputAssemblyCI = {}; + + InputAssemblyCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + InputAssemblyCI.pNext = nullptr; + InputAssemblyCI.flags = 0; // reserved for future use + InputAssemblyCI.primitiveRestartEnable = VK_FALSE; + PipelineCI.pInputAssemblyState = &InputAssemblyCI; + + + VkPipelineTessellationStateCreateInfo TessStateCI = {}; + + TessStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; + TessStateCI.pNext = nullptr; + TessStateCI.flags = 0; // reserved for future use + PipelineCI.pTessellationState = &TessStateCI; + + if (Desc.PipelineType == PIPELINE_TYPE_MESH) + { + // Input assembly is not used in the mesh pipeline, so topology may contain any value. + // Validation layers may generate a warning if point_list topology is used, so use MAX_ENUM value. + InputAssemblyCI.topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + + // Vertex input state and tessellation state are ignored in a mesh pipeline and should be null. + PipelineCI.pVertexInputState = nullptr; + PipelineCI.pTessellationState = nullptr; } else { - const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); - auto& GraphicsPipeline = m_Desc.GraphicsPipeline; - auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); + PrimitiveTopology_To_VkPrimitiveTopologyAndPatchCPCount(GraphicsPipeline.PrimitiveTopology, InputAssemblyCI.topology, TessStateCI.patchControlPoints); + } - if (m_pRenderPass == nullptr) + VkPipelineViewportStateCreateInfo ViewPortStateCI = {}; + + ViewPortStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + ViewPortStateCI.pNext = nullptr; + ViewPortStateCI.flags = 0; // reserved for future use + ViewPortStateCI.viewportCount = + GraphicsPipeline.NumViewports; // Even though we use dynamic viewports, the number of viewports used + // by the pipeline is still specified by the viewportCount member (23.5) + ViewPortStateCI.pViewports = nullptr; // We will be using dynamic viewport & scissor states + ViewPortStateCI.scissorCount = ViewPortStateCI.viewportCount; // the number of scissors must match the number of viewports (23.5) + // (why the hell it is in the struct then?) + VkRect2D ScissorRect = {}; + if (GraphicsPipeline.RasterizerDesc.ScissorEnable) + { + ViewPortStateCI.pScissors = nullptr; // Ignored if the scissor state is dynamic + } + else + { + const auto& Props = PhysicalDevice.GetProperties(); + // There are limitiations on the viewport width and height (23.5), but + // it is not clear if there are limitations on the scissor rect width and + // height + ScissorRect.extent.width = Props.limits.maxViewportDimensions[0]; + ScissorRect.extent.height = Props.limits.maxViewportDimensions[1]; + ViewPortStateCI.pScissors = &ScissorRect; + } + PipelineCI.pViewportState = &ViewPortStateCI; + + VkPipelineRasterizationStateCreateInfo RasterizerStateCI = + RasterizerStateDesc_To_VkRasterizationStateCI(GraphicsPipeline.RasterizerDesc); + PipelineCI.pRasterizationState = &RasterizerStateCI; + + // Multisample state (24) + VkPipelineMultisampleStateCreateInfo MSStateCI = {}; + + MSStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + MSStateCI.pNext = nullptr; + MSStateCI.flags = 0; // reserved for future use + // If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of + // pMultisampleState must be the same as the sample count for those subpass attachments + MSStateCI.rasterizationSamples = static_cast(GraphicsPipeline.SmplDesc.Count); + MSStateCI.sampleShadingEnable = VK_FALSE; + MSStateCI.minSampleShading = 0; // a minimum fraction of sample shading if sampleShadingEnable is set to VK_TRUE. + uint32_t SampleMask[] = {GraphicsPipeline.SampleMask, 0}; // Vulkan spec allows up to 64 samples + MSStateCI.pSampleMask = SampleMask; // an array of static coverage information that is ANDed with + // the coverage information generated during rasterization (25.3) + MSStateCI.alphaToCoverageEnable = VK_FALSE; // whether a temporary coverage value is generated based on + // the alpha component of the fragment's first color output + MSStateCI.alphaToOneEnable = VK_FALSE; // whether the alpha component of the fragment's first color output is replaced with one + PipelineCI.pMultisampleState = &MSStateCI; + + VkPipelineDepthStencilStateCreateInfo DepthStencilStateCI = + DepthStencilStateDesc_To_VkDepthStencilStateCI(GraphicsPipeline.DepthStencilDesc); + PipelineCI.pDepthStencilState = &DepthStencilStateCI; + + const auto& RPDesc = pRenderPass->GetDesc(); + const auto NumRTAttachments = RPDesc.pSubpasses[GraphicsPipeline.SubpassIndex].RenderTargetAttachmentCount; + VERIFY_EXPR(GraphicsPipeline.pRenderPass != nullptr || GraphicsPipeline.NumRenderTargets == NumRTAttachments); + std::vector ColorBlendAttachmentStates(NumRTAttachments); + + VkPipelineColorBlendStateCreateInfo BlendStateCI = {}; + + BlendStateCI.pAttachments = !ColorBlendAttachmentStates.empty() ? ColorBlendAttachmentStates.data() : nullptr; + BlendStateCI.attachmentCount = NumRTAttachments; // must equal the colorAttachmentCount for the subpass + // in which this pipeline is used. + BlendStateDesc_To_VkBlendStateCI(GraphicsPipeline.BlendDesc, BlendStateCI, ColorBlendAttachmentStates); + PipelineCI.pColorBlendState = &BlendStateCI; + + + VkPipelineDynamicStateCreateInfo DynamicStateCI = {}; + + DynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + DynamicStateCI.pNext = nullptr; + DynamicStateCI.flags = 0; // reserved for future use + std::vector DynamicStates = { - RenderPassCache::RenderPassCacheKey Key{ - GraphicsPipeline.NumRenderTargets, - GraphicsPipeline.SmplDesc.Count, - GraphicsPipeline.RTVFormats, - GraphicsPipeline.DSVFormat}; - m_pRenderPass = RPCache.GetRenderPass(Key); - } + VK_DYNAMIC_STATE_VIEWPORT, // pViewports state in VkPipelineViewportStateCreateInfo will be ignored and must be + // set dynamically with vkCmdSetViewport before any draw commands. The number of viewports + // used by a pipeline is still specified by the viewportCount member of + // VkPipelineViewportStateCreateInfo. - VkGraphicsPipelineCreateInfo PipelineCI = {}; + VK_DYNAMIC_STATE_BLEND_CONSTANTS, // blendConstants state in VkPipelineColorBlendStateCreateInfo will be ignored + // and must be set dynamically with vkCmdSetBlendConstants - PipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - PipelineCI.pNext = nullptr; -#ifdef DILIGENT_DEBUG - PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; -#endif + VK_DYNAMIC_STATE_STENCIL_REFERENCE // pecifies that the reference state in VkPipelineDepthStencilStateCreateInfo + // for both front and back will be ignored and must be set dynamically + // with vkCmdSetStencilReference + }; - PipelineCI.stageCount = m_NumShaders; - PipelineCI.pStages = ShaderStages.data(); - PipelineCI.layout = m_PipelineLayout.GetVkPipelineLayout(); + if (GraphicsPipeline.RasterizerDesc.ScissorEnable) + { + // pScissors state in VkPipelineViewportStateCreateInfo will be ignored and must be set + // dynamically with vkCmdSetScissor before any draw commands. The number of scissor rectangles + // used by a pipeline is still specified by the scissorCount member of + // VkPipelineViewportStateCreateInfo. + DynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR); + } + DynamicStateCI.dynamicStateCount = static_cast(DynamicStates.size()); + DynamicStateCI.pDynamicStates = DynamicStates.data(); + PipelineCI.pDynamicState = &DynamicStateCI; - VkPipelineVertexInputStateCreateInfo VertexInputStateCI = {}; - std::array BindingDescriptions; - std::array AttributeDescription; - InputLayoutDesc_To_VkVertexInputStateCI(GraphicsPipeline.InputLayout, VertexInputStateCI, BindingDescriptions, AttributeDescription); - PipelineCI.pVertexInputState = &VertexInputStateCI; + PipelineCI.renderPass = pRenderPass.RawPtr()->GetVkRenderPass(); + PipelineCI.subpass = Desc.GraphicsPipeline.SubpassIndex; + PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from + PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from + Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); +} - VkPipelineInputAssemblyStateCreateInfo InputAssemblyCI = {}; - InputAssemblyCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - InputAssemblyCI.pNext = nullptr; - InputAssemblyCI.flags = 0; // reserved for future use - InputAssemblyCI.primitiveRestartEnable = VK_FALSE; - PipelineCI.pInputAssemblyState = &InputAssemblyCI; +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const PipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - VkPipelineTessellationStateCreateInfo TessStateCI = {}; + ShaderStages_t ShaderStages; + ShaderSPIRVs_t ShaderSPIRVs; + ExtractShaders(ShaderStages); - TessStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - TessStateCI.pNext = nullptr; - TessStateCI.flags = 0; // reserved for future use - PipelineCI.pTessellationState = &TessStateCI; + ShaderSPIRVs.resize(ShaderStages.size()); + for (size_t s = 0; s < ShaderSPIRVs.size(); ++s) + { + auto* pShaderVk = ValidatedCast(ShaderStages[s].second); + ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); + } - if (m_Desc.PipelineType == PIPELINE_TYPE_MESH) - { - // Input assembly is not used in the mesh pipeline, so topology may contain any value. - // Validation layers may generate a warning if point_list topology is used, so use MAX_ENUM value. - InputAssemblyCI.topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + // clang-format off + static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); + // clang-format on + const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderTypes(); + auto* const pRawMem = + ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); - // Vertex input state and tessellation state are ignored in a mesh pipeline and should be null. - PipelineCI.pVertexInputState = nullptr; - PipelineCI.pTessellationState = nullptr; - } - else - { - PrimitiveTopology_To_VkPrimitiveTopologyAndPatchCPCount(GraphicsPipeline.PrimitiveTopology, InputAssemblyCI.topology, TessStateCI.patchControlPoints); - } + m_ShaderResourceLayouts = reinterpret_cast(pRawMem); + m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + GetNumShaderTypes() * 2); + m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + GetNumShaderTypes()); - VkPipelineViewportStateCreateInfo ViewPortStateCI = {}; - - ViewPortStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - ViewPortStateCI.pNext = nullptr; - ViewPortStateCI.flags = 0; // reserved for future use - ViewPortStateCI.viewportCount = - GraphicsPipeline.NumViewports; // Even though we use dynamic viewports, the number of viewports used - // by the pipeline is still specified by the viewportCount member (23.5) - ViewPortStateCI.pViewports = nullptr; // We will be using dynamic viewport & scissor states - ViewPortStateCI.scissorCount = ViewPortStateCI.viewportCount; // the number of scissors must match the number of viewports (23.5) - // (why the hell it is in the struct then?) - VkRect2D ScissorRect = {}; - if (GraphicsPipeline.RasterizerDesc.ScissorEnable) - { - ViewPortStateCI.pScissors = nullptr; // Ignored if the scissor state is dynamic - } - else - { - const auto& Props = PhysicalDevice.GetProperties(); - // There are limitiations on the viewport width and height (23.5), but - // it is not clear if there are limitations on the scissor rect width and - // height - ScissorRect.extent.width = Props.limits.maxViewportDimensions[0]; - ScissorRect.extent.height = Props.limits.maxViewportDimensions[1]; - ViewPortStateCI.pScissors = &ScissorRect; - } - PipelineCI.pViewportState = &ViewPortStateCI; - - VkPipelineRasterizationStateCreateInfo RasterizerStateCI = - RasterizerStateDesc_To_VkRasterizationStateCI(GraphicsPipeline.RasterizerDesc); - PipelineCI.pRasterizationState = &RasterizerStateCI; - - // Multisample state (24) - VkPipelineMultisampleStateCreateInfo MSStateCI = {}; - - MSStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - MSStateCI.pNext = nullptr; - MSStateCI.flags = 0; // reserved for future use - // If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of - // pMultisampleState must be the same as the sample count for those subpass attachments - MSStateCI.rasterizationSamples = static_cast(GraphicsPipeline.SmplDesc.Count); - MSStateCI.sampleShadingEnable = VK_FALSE; - MSStateCI.minSampleShading = 0; // a minimum fraction of sample shading if sampleShadingEnable is set to VK_TRUE. - uint32_t SampleMask[] = {GraphicsPipeline.SampleMask, 0}; // Vulkan spec allows up to 64 samples - MSStateCI.pSampleMask = SampleMask; // an array of static coverage information that is ANDed with - // the coverage information generated during rasterization (25.3) - MSStateCI.alphaToCoverageEnable = VK_FALSE; // whether a temporary coverage value is generated based on - // the alpha component of the fragment's first color output - MSStateCI.alphaToOneEnable = VK_FALSE; // whether the alpha component of the fragment's first color output is replaced with one - PipelineCI.pMultisampleState = &MSStateCI; - - VkPipelineDepthStencilStateCreateInfo DepthStencilStateCI = - DepthStencilStateDesc_To_VkDepthStencilStateCI(GraphicsPipeline.DepthStencilDesc); - PipelineCI.pDepthStencilState = &DepthStencilStateCI; - - const auto& RPDesc = m_pRenderPass->GetDesc(); - const auto NumRTAttachments = RPDesc.pSubpasses[GraphicsPipeline.SubpassIndex].RenderTargetAttachmentCount; - VERIFY_EXPR(GraphicsPipeline.pRenderPass != nullptr || GraphicsPipeline.NumRenderTargets == NumRTAttachments); - std::vector ColorBlendAttachmentStates(NumRTAttachments); - - VkPipelineColorBlendStateCreateInfo BlendStateCI = {}; - - BlendStateCI.pAttachments = !ColorBlendAttachmentStates.empty() ? ColorBlendAttachmentStates.data() : nullptr; - BlendStateCI.attachmentCount = NumRTAttachments; // must equal the colorAttachmentCount for the subpass - // in which this pipeline is used. - BlendStateDesc_To_VkBlendStateCI(GraphicsPipeline.BlendDesc, BlendStateCI, ColorBlendAttachmentStates); - PipelineCI.pColorBlendState = &BlendStateCI; - - - VkPipelineDynamicStateCreateInfo DynamicStateCI = {}; - - DynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - DynamicStateCI.pNext = nullptr; - DynamicStateCI.flags = 0; // reserved for future use - std::vector DynamicStates = - { - VK_DYNAMIC_STATE_VIEWPORT, // pViewports state in VkPipelineViewportStateCreateInfo will be ignored and must be - // set dynamically with vkCmdSetViewport before any draw commands. The number of viewports - // used by a pipeline is still specified by the viewportCount member of - // VkPipelineViewportStateCreateInfo. + for (size_t s = 0; s < ShaderStages.size(); ++s) + { + new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; + + const auto ShaderType = ShaderStages[s].first; + auto& Shaders = ShaderStages[s].second; + const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); - VK_DYNAMIC_STATE_BLEND_CONSTANTS, // blendConstants state in VkPipelineColorBlendStateCreateInfo will be ignored - // and must be set dynamically with vkCmdSetBlendConstants + auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; + auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; + pStaticResLayout->InitializeStaticResourceLayout(Shaders, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); - VK_DYNAMIC_STATE_STENCIL_REFERENCE // pecifies that the reference state in VkPipelineDepthStencilStateCreateInfo - // for both front and back will be ignored and must be set dynamically - // with vkCmdSetStencilReference - }; + new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; + } + ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(), + m_Desc.ResourceLayout, ShaderSPIRVs, m_PipelineLayout, + (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, + (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); + m_PipelineLayout.Finalize(LogicalDevice); - if (GraphicsPipeline.RasterizerDesc.ScissorEnable) + if (m_Desc.SRBAllocationGranularity > 1) + { + std::array ShaderVariableDataSizes = {}; + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { - // pScissors state in VkPipelineViewportStateCreateInfo will be ignored and must be set - // dynamically with vkCmdSetScissor before any draw commands. The number of scissor rectangles - // used by a pipeline is still specified by the scissorCount member of - // VkPipelineViewportStateCreateInfo. - DynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR); + const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + + Uint32 UnusedNumVars = 0; + ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(m_ShaderResourceLayouts[s], AllowedVarTypes, _countof(AllowedVarTypes), UnusedNumVars); } - DynamicStateCI.dynamicStateCount = static_cast(DynamicStates.size()); - DynamicStateCI.pDynamicStates = DynamicStates.data(); - PipelineCI.pDynamicState = &DynamicStateCI; + Uint32 NumSets = 0; + auto DescriptorSetSizes = m_PipelineLayout.GetDescriptorSetSizes(NumSets); + auto CacheMemorySize = ShaderResourceCacheVk::GetRequiredMemorySize(NumSets, DescriptorSetSizes.data()); + + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); + } - PipelineCI.renderPass = GetRenderPass()->GetVkRenderPass(); - PipelineCI.subpass = m_Desc.GraphicsPipeline.SubpassIndex; - PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from - PipelineCI.basePipelineIndex = 0; // an index into the pCreateInfos parameter to use as a pipeline to derive from + // Create shader modules and initialize shader stages + std::vector VkShaderStages; + std::vector ShaderModules; + InitializeShaderStages(LogicalDevice, ShaderStages, ShaderSPIRVs, ShaderModules, VkShaderStages); - m_Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, m_Desc.Name); + // Create pipeline + switch (m_Desc.PipelineType) + { + // clang-format off + case PIPELINE_TYPE_GRAPHICS: + case PIPELINE_TYPE_MESH: CreateGraphicsPipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline, m_pRenderPass); break; + case PIPELINE_TYPE_COMPUTE: CreateComputePipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); break; + default: UNEXPECTED("unknown pipeline type"); + // clang-format on } m_HasStaticResources = false; m_HasNonStaticResources = false; - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) != 0) @@ -493,21 +517,13 @@ PipelineStateVkImpl::~PipelineStateVkImpl() m_pDevice->SafeReleaseDeviceObject(std::move(m_Pipeline), m_Desc.CommandQueueMask); m_PipelineLayout.Release(m_pDevice, m_Desc.CommandQueueMask); - for (auto& ShaderModule : m_ShaderModules) - { - if (ShaderModule != VK_NULL_HANDLE) - { - m_pDevice->SafeReleaseDeviceObject(std::move(ShaderModule), m_Desc.CommandQueueMask); - } - } - auto& RawAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < m_NumShaders * 2; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes() * 2; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); } - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { m_StaticResCaches[s].~ShaderResourceCacheVk(); m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); @@ -547,27 +563,27 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (m_NumShaders != pPSOVk->m_NumShaders) + if (GetNumShaderTypes() != pPSOVk->GetNumShaderTypes()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { - auto* pShader0 = GetShader(s); - auto* pShader1 = pPSOVk->GetShader(s); - if (pShader0->GetDesc().ShaderType != pShader1->GetDesc().ShaderType) + if (GetShaderTypes()[s] != pPSOVk->GetShaderTypes()[s]) { IsCompatibleShaders = false; break; } - const auto* pRes0 = pShader0->GetShaderResources().get(); + + // AZ TODO + /*const auto* pRes0 = pShader0->GetShaderResources().get(); const auto* pRes1 = pShader1->GetShaderResources().get(); if (!pRes0->IsCompatibleWith(*pRes1)) { IsCompatibleShaders = false; break; - } + }*/ } } @@ -621,7 +637,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind auto& ResourceCache = pResBindingVkImpl->GetResourceCache(); #ifdef DILIGENT_DEVELOPMENT - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { m_ShaderResourceLayouts[s].dvpVerifyBindings(ResourceCache); } @@ -656,7 +672,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind // Allocate vulkan descriptor set for dynamic resources DynamicDescrSet = pCtxVkImpl->AllocateDynamicDescriptorSet(DynamicDescriptorSetVkLayout, DynamicDescrSetName); // Commit all dynamic resource descriptors - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) @@ -673,7 +689,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind void PipelineStateVkImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderType & ShaderFlags) != 0) @@ -717,17 +733,17 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const { - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { const auto& StaticResLayout = GetStaticShaderResLayout(s); const auto& StaticResCache = GetStaticResCache(s); + #ifdef DILIGENT_DEVELOPMENT if (!StaticResLayout.dvpVerifyBindings(StaticResCache)) { - const auto* pShaderVk = GetShader(s); LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", GetDesc().Name, "' will not be successfully initialized because not all static resource bindings in shader '", - pShaderVk->GetDesc().Name, + GetShaderTypeLiteralName(GetShaderTypes()[s]), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 53a92a59..75f3bb37 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -49,8 +49,8 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); - auto* ppShaders = pPSO->GetShaders(); - m_NumShaders = static_cast(pPSO->GetNumShaders()); + auto* pShaderTypes = pPSO->GetShaderTypes(); + m_NumShaders = static_cast(pPSO->GetNumShaderTypes()); auto* pRenderDeviceVkImpl = pPSO->GetDevice(); // This will only allocate memory and initialize descriptor sets in the resource cache @@ -62,9 +62,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto* pShader = ppShaders[s]; - auto ShaderType = pShader->GetDesc().ShaderType; - auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); + auto ShaderInd = GetShaderTypePipelineIndex(pShaderTypes[s], pPSO->GetDesc().PipelineType); m_ResourceLayoutIndex[ShaderInd] = static_cast(s); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 4f28af80..1f798eb9 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -103,36 +103,40 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() GetImmutableSampler(s).~ImmutableSamplerPtrType(); } -void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr pSrcResources, - IMemoryAllocator& Allocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - bool AllocateImmutableSamplers) +void ShaderResourceLayoutVk::AllocateMemory(IShader* pShader, + IMemoryAllocator& Allocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + bool AllocateImmutableSamplers) { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); - VERIFY_EXPR(!m_pResources); - VERIFY_EXPR(pSrcResources); + VERIFY_EXPR(pShader != nullptr); + VERIFY_EXPR(m_ShaderType == SHADER_TYPE_UNKNOWN); - m_pResources = std::move(pSrcResources); - - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - const auto ShaderType = m_pResources->GetShaderType(); - const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + m_ShaderType = pShader->GetDesc().ShaderType; // Count the number of resources to allocate all needed memory - m_pResources->ProcessResources( - [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // - { - auto VarType = FindShaderVariableType(ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); - if (IsAllowedType(VarType, AllowedTypeBits)) + { + auto* pShaderVk = ValidatedCast(pShader); + auto pResources = pShaderVk->GetShaderResources(); + const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); + VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); + pResources->ProcessResources( + [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // { - // For immutable separate samplers we still allocate VkResource instances, but they are never exposed to the app + auto VarType = FindShaderVariableType(m_ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + // For immutable separate samplers we still allocate VkResource instances, but they are never exposed to the app - VERIFY(Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds Uint16 maximum representable value"); - ++m_NumResources[VarType]; - } - } // - ); + VERIFY(Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds Uint16 maximum representable value"); + ++m_NumResources[VarType]; + } + } // + ); + m_IsUsingSeparateSamplers = !pResources->IsUsingCombinedSamplers(); + } Uint32 TotalResources = 0; for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -148,7 +152,7 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderResourceCacheVk& StaticResourceCache) +Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, + const SPIRVShaderResources& Resources, + const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) +{ + using VkResource = ShaderResourceLayoutVk::VkResource; + VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); + + Uint32 SamplerInd = VkResource::InvalidSamplerInd; + if (Resources.IsUsingCombinedSamplers() && SepImg.IsValidSepSamplerAssigned()) + { + const auto& SepSampler = Resources.GetAssignedSepSampler(SepImg); + for (SamplerInd = 0; SamplerInd < CurrResourceCount; ++SamplerInd) + { + const auto& Res = Layout.GetResource(ImgVarType, SamplerInd); + if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && + strcmp(Res.SpirvAttribs.Name, SepSampler.Name) == 0) + { + VERIFY(ImgVarType == Res.GetVariableType(), + "The type (", GetShaderVariableTypeLiteralName(ImgVarType), ") of separate image variable '", SepImg.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(Res.GetVariableType()), + ") of the separate sampler '", SepSampler.Name, + "' that is assigned to it. " + "This should never happen as when HLSL-style combined texture samplers are used, the type of the sampler " + "is derived from the type of the corresponding separate image."); + break; + } + } + if (SamplerInd == CurrResourceCount) + { + LOG_ERROR("Unable to find separate sampler '", SepSampler.Name, "' assigned to separate image '", SepImg.Name, "' in the list of already created resources. This seems to be a bug."); + SamplerInd = VkResource::InvalidSamplerInd; + } + } + return SamplerInd; +} + + +void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* pShader, + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + ShaderResourceCacheVk& StaticResourceCache) { const auto AllowedVarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; // We do not need immutable samplers in static shader resource layout as they // are relevant only when the main layout is initialized constexpr bool AllocateImmutableSamplers = false; - AllocateMemory(std::move(pSrcResources), LayoutDataAllocator, ResourceLayoutDesc, &AllowedVarType, 1, AllocateImmutableSamplers); + AllocateMemory(pShader, LayoutDataAllocator, ResourceLayoutDesc, &AllowedVarType, 1, AllocateImmutableSamplers); std::array CurrResInd = {}; Uint32 StaticResCacheSize = 0; - const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); - const auto ShaderType = m_pResources->GetShaderType(); - const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); + const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); - m_pResources->ProcessResources( - [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) // - { - auto VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); - if (!IsAllowedType(VarType, AllowedTypeBits)) - return; + { + auto* pShaderVk = ValidatedCast(pShader); + auto pResources = pShaderVk->GetShaderResources(); + const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - Int32 SrcImmutableSamplerInd = -1; - if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || - Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) + pResources->ProcessResources( + [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) // { - // Only search for the immutable sampler for combined image samplers and separate samplers - SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, ResourceLayoutDesc, Attribs, CombinedSamplerSuffix); - // For immutable separate samplers we allocate VkResource instances, but they are never exposed to the app - } + auto VarType = FindShaderVariableType(m_ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); + if (!IsAllowedType(VarType, AllowedTypeBits)) + return; - Uint32 Binding = Attribs.Type; - Uint32 DescriptorSet = 0; - Uint32 CacheOffset = StaticResCacheSize; - StaticResCacheSize += Attribs.ArraySize; + Int32 SrcImmutableSamplerInd = -1; + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) + { + // Only search for the immutable sampler for combined image samplers and separate samplers + SrcImmutableSamplerInd = FindImmutableSampler(m_ShaderType, ResourceLayoutDesc, Attribs, CombinedSamplerSuffix); + // For immutable separate samplers we allocate VkResource instances, but they are never exposed to the app + } - Uint32 SamplerInd = VkResource::InvalidSamplerInd; - if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) - { - // Separate samplers are enumerated before separate images, so the sampler - // assigned to this separate image must have already been created. - SamplerInd = FindAssignedSampler(Attribs, CurrResInd[VarType], VarType); - } - ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource(*this, Attribs, VarType, Binding, DescriptorSet, CacheOffset, SamplerInd, SrcImmutableSamplerInd >= 0); - } // - ); + Uint32 Binding = Attribs.Type; + Uint32 DescriptorSet = 0; + Uint32 CacheOffset = StaticResCacheSize; + StaticResCacheSize += Attribs.ArraySize; + + Uint32 SamplerInd = VkResource::InvalidSamplerInd; + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) + { + // Separate samplers are enumerated before separate images, so the sampler + // assigned to this separate image must have already been created. + SamplerInd = FindAssignedSampler(*this, *pResources, Attribs, CurrResInd[VarType], VarType); + } + ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource(*this, Attribs, VarType, Binding, DescriptorSet, CacheOffset, SamplerInd, SrcImmutableSamplerInd >= 0); + } // + ); + } #ifdef DILIGENT_DEBUG for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -235,25 +282,24 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr pShaderResources[], - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - bool VerifyVariables, - bool VerifyStaticSamplers) +void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + bool VerifyVariables, + bool VerifyStaticSamplers) { - auto GetAllowedShadersString = [&](SHADER_TYPE ShaderStages) // + auto GetAllowedShadersString = [&](SHADER_TYPE Stages) // { std::string ShadersStr; - while (ShaderStages != SHADER_TYPE_UNKNOWN) + while (Stages != SHADER_TYPE_UNKNOWN) { - const auto ShaderType = ShaderStages & static_cast(~(static_cast(ShaderStages) - 1)); + const auto ShaderType = Stages & static_cast(~(static_cast(Stages) - 1)); const char* ShaderName = nullptr; - for (Uint32 s = 0; s < NumShaders; ++s) + + for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto& Resources = *pShaderResources[s]; - if ((ShaderStages & Resources.GetShaderType()) != 0) + if ((Stages & ShaderStages[s].first) != 0) { - ShaderName = Resources.GetShaderName(); + ShaderName = ShaderStages[s].second->GetDesc().Name; break; } } @@ -274,7 +320,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(Uint32 } ShadersStr.append(")"); - ShaderStages &= ~ShaderType; + Stages &= ~ShaderType; } return ShadersStr; }; @@ -291,9 +337,10 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(Uint32 } bool VariableFound = false; - for (Uint32 s = 0; s < NumShaders && !VariableFound; ++s) + for (size_t s = 0; s < ShaderStages.size() && !VariableFound; ++s) { - const auto& Resources = *pShaderResources[s]; + const auto* pShaderVk = ValidatedCast(ShaderStages[s].second); + const auto& Resources = *pShaderVk->GetShaderResources(); if ((VarDesc.ShaderStages & Resources.GetShaderType()) != 0) { for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) @@ -324,9 +371,10 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(Uint32 } bool SamplerFound = false; - for (Uint32 s = 0; s < NumShaders && !SamplerFound; ++s) + for (size_t s = 0; s < ShaderStages.size() && !SamplerFound; ++s) { - const auto& Resources = *pShaderResources[s]; + const auto* pShaderVk = ValidatedCast(ShaderStages[s].second); + const auto& Resources = *pShaderVk->GetShaderResources(); if ((StSamDesc.ShaderStages & Resources.GetShaderType()) == 0) continue; @@ -363,32 +411,31 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(Uint32 } #endif -void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRenderDevice, - Uint32 NumShaders, - ShaderResourceLayoutVk Layouts[], - std::shared_ptr pShaderResources[], - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - std::vector SPIRVs[], - class PipelineLayout& PipelineLayout, - bool VerifyVariables, - bool VerifyStaticSamplers) +void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRenderDevice, + const ShaderStages_t& ShaderStages, + ShaderResourceLayoutVk Layouts[], + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + ShaderSPIRVs_t& SPIRVs, + class PipelineLayout& PipelineLayout, + bool VerifyVariables, + bool VerifyStaticSamplers) { #ifdef DILIGENT_DEVELOPMENT - dvpVerifyResourceLayoutDesc(NumShaders, pShaderResources, ResourceLayoutDesc, VerifyVariables, VerifyStaticSamplers); + dvpVerifyResourceLayoutDesc(ShaderStages, ResourceLayoutDesc, VerifyVariables, VerifyStaticSamplers); #endif - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; - const Uint32 NumAllowedTypes = 0; - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; + const Uint32 NumAllowedTypes = 0; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + constexpr bool AllocateImmutableSamplers = true; - for (Uint32 s = 0; s < NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - constexpr bool AllocateImmutableSamplers = true; - Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); + Layouts[s].AllocateMemory(ShaderStages[s].second, LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); } - VERIFY_EXPR(NumShaders <= MAX_SHADERS_IN_PIPELINE); + //VERIFY_EXPR(NumShaders <= MAX_SHADERS_IN_PIPELINE); std::array, MAX_SHADERS_IN_PIPELINE> CurrResInd = {}; std::array CurrImmutableSamplerInd = {}; #ifdef DILIGENT_DEBUG @@ -414,7 +461,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* { // Separate samplers are enumerated before separate images, so the sampler // assigned to this separate image must have already been created. - SamplerInd = ResLayout.FindAssignedSampler(Attribs, CurrResInd[ShaderInd][VarType], VarType); + SamplerInd = FindAssignedSampler(ResLayout, Resources, Attribs, CurrResInd[ShaderInd][VarType], VarType); } VkSampler vkImmutableSampler = VK_NULL_HANDLE; @@ -454,42 +501,48 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* }; // First process uniform buffers for all shader stages to make sure all UBs go first in every descriptor set - for (Uint32 s = 0; s < NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& Layout = Layouts[s]; - const auto& Resources = *Layout.m_pResources; + auto& pShader = ShaderStages[s].second; + auto& Layout = Layouts[s]; + auto* pShaderVk = ValidatedCast(pShader); + auto& Resources = *pShaderVk->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n) { const auto& UB = Resources.GetUB(n); auto VarType = GetShaderVariableType(Resources.GetShaderType(), UB.Name, ResourceLayoutDesc); if (IsAllowedType(VarType, AllowedTypeBits)) { - AddResource(s, Layout, Resources, UB); + AddResource(static_cast(s), Layout, Resources, UB); } } } // Second, process all storage buffers - for (Uint32 s = 0; s < NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& Layout = Layouts[s]; - const auto& Resources = *Layout.m_pResources; + auto& pShader = ShaderStages[s].second; + auto& Layout = Layouts[s]; + auto* pShaderVk = ValidatedCast(pShader); + auto& Resources = *pShaderVk->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n) { const auto& SB = Resources.GetSB(n); auto VarType = GetShaderVariableType(Resources.GetShaderType(), SB.Name, ResourceLayoutDesc); if (IsAllowedType(VarType, AllowedTypeBits)) { - AddResource(s, Layout, Resources, SB); + AddResource(static_cast(s), Layout, Resources, SB); } } } // Finally, process all other resource types - for (Uint32 s = 0; s < NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& Layout = Layouts[s]; - const auto& Resources = *Layout.m_pResources; + auto& pShader = ShaderStages[s].second; + auto& Layout = Layouts[s]; + auto* pShaderVk = ValidatedCast(pShader); + auto& Resources = *pShaderVk->GetShaderResources(); // clang-format off Resources.ProcessResources( [&](const SPIRVShaderResourceAttribs& UB, Uint32) @@ -505,39 +558,39 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* [&](const SPIRVShaderResourceAttribs& Img, Uint32) { VERIFY_EXPR(Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageImage || Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer); - AddResource(s, Layout, Resources, Img); + AddResource(static_cast(s), Layout, Resources, Img); }, [&](const SPIRVShaderResourceAttribs& SmplImg, Uint32) { VERIFY_EXPR(SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer); - AddResource(s, Layout, Resources, SmplImg); + AddResource(static_cast(s), Layout, Resources, SmplImg); }, [&](const SPIRVShaderResourceAttribs& AC, Uint32) { VERIFY_EXPR(AC.Type == SPIRVShaderResourceAttribs::ResourceType::AtomicCounter); - AddResource(s, Layout, Resources, AC); + AddResource(static_cast(s), Layout, Resources, AC); }, [&](const SPIRVShaderResourceAttribs& SepSmpl, Uint32) { VERIFY_EXPR(SepSmpl.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler); - AddResource(s, Layout, Resources, SepSmpl); + AddResource(static_cast(s), Layout, Resources, SepSmpl); }, [&](const SPIRVShaderResourceAttribs& SepImg, Uint32) { VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage || SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer); - AddResource(s, Layout, Resources, SepImg); + AddResource(static_cast(s), Layout, Resources, SepImg); }, [&](const SPIRVShaderResourceAttribs& InputAtt, Uint32) { VERIFY_EXPR(InputAtt.Type == SPIRVShaderResourceAttribs::ResourceType::InputAttachment); - AddResource(s, Layout, Resources, InputAtt); + AddResource(static_cast(s), Layout, Resources, InputAtt); } ); // clang-format on } #ifdef DILIGENT_DEBUG - for (Uint32 s = 0; s < NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { auto& Layout = Layouts[s]; for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -551,41 +604,40 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } -Uint32 ShaderResourceLayoutVk::FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, - Uint32 CurrResourceCount, - SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) const +ShaderResourceLayoutVk::VkResource::VkResource(const ShaderResourceLayoutVk& _ParentLayout, + const SPIRVShaderResourceAttribs& _SpirvAttribs, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + uint32_t _Binding, + uint32_t _DescriptorSet, + Uint32 _CacheOffset, + Uint32 _SamplerInd, + bool _ImmutableSamplerAssigned) noexcept : + // clang-format off + Binding {static_cast(_Binding) }, + DescriptorSet {static_cast(_DescriptorSet)}, + CacheOffset {_CacheOffset }, + SamplerInd {_SamplerInd }, + VariableType {_VariableType }, + ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, + SpirvAttribs {_SpirvAttribs }, + ParentResLayout {_ParentLayout } +// clang-format on { - VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); - - Uint32 SamplerInd = VkResource::InvalidSamplerInd; - if (m_pResources->IsUsingCombinedSamplers() && SepImg.IsValidSepSamplerAssigned()) - { - const auto& SepSampler = m_pResources->GetAssignedSepSampler(SepImg); - for (SamplerInd = 0; SamplerInd < CurrResourceCount; ++SamplerInd) - { - const auto& Res = GetResource(ImgVarType, SamplerInd); - if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && - strcmp(Res.SpirvAttribs.Name, SepSampler.Name) == 0) - { - VERIFY(ImgVarType == Res.GetVariableType(), - "The type (", GetShaderVariableTypeLiteralName(ImgVarType), ") of separate image variable '", SepImg.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(Res.GetVariableType()), - ") of the separate sampler '", SepSampler.Name, - "' that is assigned to it. " - "This should never happen as when HLSL-style combined texture samplers are used, the type of the sampler " - "is derived from the type of the corresponding separate image."); - break; - } - } - if (SamplerInd == CurrResourceCount) - { - LOG_ERROR("Unable to find separate sampler '", SepSampler.Name, "' assigned to separate image '", SepImg.Name, "' in the list of already created resources. This seems to be a bug."); - SamplerInd = VkResource::InvalidSamplerInd; - } - } - return SamplerInd; + VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits)); + VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits)); + VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max()); + VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); + + const size_t Size = strlen(SpirvAttribs.Name) + 1; + char* NameCopy = ALLOCATE(GetRawAllocator(), "SPIRV Attribs Name", char, Size); + std::memcpy(NameCopy, SpirvAttribs.Name, Size); + const_cast(SpirvAttribs).Name = NameCopy; } +ShaderResourceLayoutVk::VkResource::~VkResource() +{ + FREE(GetRawAllocator(), const_cast(SpirvAttribs.Name)); +} void ShaderResourceLayoutVk::VkResource::UpdateDescriptorHandle(VkDescriptorSet vkDescrSet, uint32_t ArrayElement, @@ -1017,7 +1069,7 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou { auto NumStaticResources = m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC]; VERIFY(NumStaticResources == SrcLayout.m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC], "Inconsistent number of static resources"); - VERIFY(SrcLayout.m_pResources->GetShaderType() == m_pResources->GetShaderType(), "Incosistent shader types"); + VERIFY(SrcLayout.GetShaderType() == GetShaderType(), "Incosistent shader types"); // Static shader resources are stored in one large continuous descriptor set for (Uint32 r = 0; r < NumStaticResources; ++r) diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index fb151407..95261295 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1511,4 +1511,27 @@ VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags) } #undef ASSERT_SAME + +VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType) +{ + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); + VERIFY((ShaderType & (ShaderType - 1)) == 0, "More than one shader type specified"); + switch (ShaderType) + { + // clang-format off + case SHADER_TYPE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT; + case SHADER_TYPE_HULL: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + case SHADER_TYPE_DOMAIN: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + case SHADER_TYPE_GEOMETRY: return VK_SHADER_STAGE_GEOMETRY_BIT; + case SHADER_TYPE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT; + case SHADER_TYPE_COMPUTE: return VK_SHADER_STAGE_COMPUTE_BIT; + case SHADER_TYPE_AMPLIFICATION: return VK_SHADER_STAGE_TASK_BIT_NV; + case SHADER_TYPE_MESH: return VK_SHADER_STAGE_MESH_BIT_NV; + // clang-format on + default: + UNEXPECTED("Unknown shader type"); + return VK_SHADER_STAGE_VERTEX_BIT; + } +} + } // namespace Diligent -- cgit v1.2.3 From e92a0a857a85fad049646dd78d4f742d245cc9cd Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 21:48:49 +0300 Subject: Some minor fixes --- Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp | 6 +++--- Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp | 2 +- Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp | 2 +- Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp index e01178a5..9976d014 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -135,13 +135,13 @@ public: ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend. + /// Implementation of IDeviceContext::BeginRenderPass() in Vulkan backend. virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final; - /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend. + /// Implementation of IDeviceContext::NextSubpass() in Vulkan backend. virtual void DILIGENT_CALL_TYPE NextSubpass() override final; - /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. + /// Implementation of IDeviceContext::EndRenderPass() in Vulkan backend. virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; // clang-format off diff --git a/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp index f449d416..23097d22 100644 --- a/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/FramebufferVkImpl.hpp @@ -40,7 +40,7 @@ namespace Diligent class FixedBlockMemoryAllocator; -/// Render pass implementation in Direct3D11 backend. +/// Framebuffer implementation in Vulkan backend. class FramebufferVkImpl final : public FramebufferBase { public: diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp index 5c77784f..05962047 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp @@ -41,7 +41,7 @@ namespace Diligent class FixedBlockMemoryAllocator; -/// Render pass implementation in Direct3D11 backend. +/// Render pass implementation in Vulkan backend. class RenderPassVkImpl final : public RenderPassBase { public: diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index c36b98b0..f6e337c2 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -100,6 +100,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, EngineCI.MainDescriptorPoolSize.NumStorageBufferDescriptors}, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, EngineCI.MainDescriptorPoolSize.NumUniformBufferDescriptors}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, EngineCI.MainDescriptorPoolSize.NumStorageBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, EngineCI.MainDescriptorPoolSize.NumInputAttachmentDescriptors}, }, EngineCI.MainDescriptorPoolSize.MaxDescriptorSets, true @@ -120,6 +121,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, EngineCI.DynamicDescriptorPoolSize.NumStorageBufferDescriptors}, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, EngineCI.DynamicDescriptorPoolSize.NumUniformBufferDescriptors}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, EngineCI.DynamicDescriptorPoolSize.NumStorageBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, EngineCI.MainDescriptorPoolSize.NumInputAttachmentDescriptors}, }, EngineCI.DynamicDescriptorPoolSize.MaxDescriptorSets, false // Pools can only be reset -- cgit v1.2.3 From 998165f350cfd8ae6bd9cbf6fc812874c1c3c3da Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 22:14:06 +0300 Subject: Revert some changes in ShaderResourceLayoutVk, fixed PSO comparison --- .../include/ShaderResourceLayoutVk.hpp | 65 +++++++----- .../src/PipelineStateVkImpl.cpp | 11 +- .../src/ShaderResourceLayoutVk.cpp | 115 +++++++-------------- 3 files changed, 83 insertions(+), 108 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 28defd0f..4d29093d 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -177,21 +177,33 @@ public: /* 7.5 */ const Uint32 VariableType : VariableTypeBits; /* 7.7 */ const Uint32 ImmutableSamplerAssigned : ImmutableSamplerFlagBits; -/* 8 */ const SPIRVShaderResourceAttribs SpirvAttribs; -/* 16 */ const ShaderResourceLayoutVk& ParentResLayout; +/* 8 */ const SPIRVShaderResourceAttribs& SpirvAttribs; +/* 16 */ const ShaderResourceLayoutVk& ParentResLayout; + + VkResource(const ShaderResourceLayoutVk& _ParentLayout, + const SPIRVShaderResourceAttribs& _SpirvAttribs, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + uint32_t _Binding, + uint32_t _DescriptorSet, + Uint32 _CacheOffset, + Uint32 _SamplerInd, + bool _ImmutableSamplerAssigned = false)noexcept : + Binding {static_cast(_Binding) }, + DescriptorSet {static_cast(_DescriptorSet)}, + CacheOffset {_CacheOffset }, + SamplerInd {_SamplerInd }, + VariableType {_VariableType }, + ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, + SpirvAttribs {_SpirvAttribs }, + ParentResLayout {_ParentLayout } + { + VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) ); + VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) ); + VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max() ); + VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); + } // clang-format on - VkResource(const ShaderResourceLayoutVk& _ParentLayout, - const SPIRVShaderResourceAttribs& _SpirvAttribs, - SHADER_RESOURCE_VARIABLE_TYPE _VariableType, - uint32_t _Binding, - uint32_t _DescriptorSet, - Uint32 _CacheOffset, - Uint32 _SamplerInd, - bool _ImmutableSamplerAssigned = false) noexcept; - - ~VkResource(); - // Checks if a resource is bound in ResourceCache at the given ArrayIndex bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const; @@ -289,10 +301,15 @@ public: const Char* GetShaderName() const { - return ""; // AZ TODO + return m_pResources->GetShaderName(); } - SHADER_TYPE GetShaderType() const { return m_ShaderType; } + SHADER_TYPE GetShaderType() const + { + return m_pResources->GetShaderType(); + } + + const SPIRVShaderResources& GetResources() const { return *m_pResources; } const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const { @@ -301,7 +318,7 @@ public: return Resources[GetResourceOffset(VarType, r)]; } - bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; } + bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedSamplers(); } private: Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const @@ -348,16 +365,16 @@ private: } // clang-format off -/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; -/* 8 */ std::unique_ptr > m_ResourceBuffer; - -/*24 */ std::array m_NumResources = {}; +/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; +/* 8 */ std::unique_ptr > m_ResourceBuffer; -/*32 */ Uint32 m_NumImmutableSamplers = 0; -/*36 */ bool m_IsUsingSeparateSamplers = false; -/*37 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; + // We must use shared_ptr to reference ShaderResources instance, because + // there may be multiple objects referencing the same set of resources +/*24 */ std::shared_ptr m_pResources; -/*40 */ // End of class +/*40 */ std::array m_NumResources = {}; +/*48 */ Uint32 m_NumImmutableSamplers = 0; +/*56*/ // End of class // clang-format on }; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 29d16239..f40f22c8 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -575,15 +575,14 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const IsCompatibleShaders = false; break; } - - // AZ TODO - /*const auto* pRes0 = pShader0->GetShaderResources().get(); - const auto* pRes1 = pShader1->GetShaderResources().get(); - if (!pRes0->IsCompatibleWith(*pRes1)) + + const auto& Res0 = GetShaderResLayout(s).GetResources(); + const auto& Res1 = pPSOVk->GetShaderResLayout(s).GetResources(); + if (!Res0.IsCompatibleWith(Res1)) { IsCompatibleShaders = false; break; - }*/ + } } } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 1f798eb9..a7410210 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -111,21 +111,21 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* bool AllocateImmutableSamplers) { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); - VERIFY_EXPR(pShader != nullptr); - VERIFY_EXPR(m_ShaderType == SHADER_TYPE_UNKNOWN); + VERIFY_EXPR(!m_pResources); const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - m_ShaderType = pShader->GetDesc().ShaderType; + const auto ShaderType = pShader->GetDesc().ShaderType; // Count the number of resources to allocate all needed memory { auto* pShaderVk = ValidatedCast(pShader); auto pResources = pShaderVk->GetShaderResources(); const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); - pResources->ProcessResources( + VERIFY_EXPR(pResources->GetShaderType() == ShaderType); + m_pResources = pResources; + m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // { - auto VarType = FindShaderVariableType(m_ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); + auto VarType = FindShaderVariableType(ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (IsAllowedType(VarType, AllowedTypeBits)) { // For immutable separate samplers we still allocate VkResource instances, but they are never exposed to the app @@ -135,7 +135,6 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* } } // ); - m_IsUsingSeparateSamplers = !pResources->IsUsingCombinedSamplers(); } Uint32 TotalResources = 0; @@ -152,7 +151,7 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* for (Uint32 s = 0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) { const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; - if ((StSamDesc.ShaderStages & m_ShaderType) != 0) + if ((StSamDesc.ShaderStages & ShaderType) != 0) ++m_NumImmutableSamplers; } } @@ -227,45 +226,41 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* Uint32 StaticResCacheSize = 0; - const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); + const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); + const auto ShaderType = pShader->GetDesc().ShaderType; - { - auto* pShaderVk = ValidatedCast(pShader); - auto pResources = pShaderVk->GetShaderResources(); - const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); + m_pResources->ProcessResources( + [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) // + { + auto VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); + if (!IsAllowedType(VarType, AllowedTypeBits)) + return; - pResources->ProcessResources( - [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) // + Int32 SrcImmutableSamplerInd = -1; + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) { - auto VarType = FindShaderVariableType(m_ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); - if (!IsAllowedType(VarType, AllowedTypeBits)) - return; - - Int32 SrcImmutableSamplerInd = -1; - if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || - Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) - { - // Only search for the immutable sampler for combined image samplers and separate samplers - SrcImmutableSamplerInd = FindImmutableSampler(m_ShaderType, ResourceLayoutDesc, Attribs, CombinedSamplerSuffix); - // For immutable separate samplers we allocate VkResource instances, but they are never exposed to the app - } + // Only search for the immutable sampler for combined image samplers and separate samplers + SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, ResourceLayoutDesc, Attribs, CombinedSamplerSuffix); + // For immutable separate samplers we allocate VkResource instances, but they are never exposed to the app + } - Uint32 Binding = Attribs.Type; - Uint32 DescriptorSet = 0; - Uint32 CacheOffset = StaticResCacheSize; - StaticResCacheSize += Attribs.ArraySize; + Uint32 Binding = Attribs.Type; + Uint32 DescriptorSet = 0; + Uint32 CacheOffset = StaticResCacheSize; + StaticResCacheSize += Attribs.ArraySize; - Uint32 SamplerInd = VkResource::InvalidSamplerInd; - if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) - { - // Separate samplers are enumerated before separate images, so the sampler - // assigned to this separate image must have already been created. - SamplerInd = FindAssignedSampler(*this, *pResources, Attribs, CurrResInd[VarType], VarType); - } - ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource(*this, Attribs, VarType, Binding, DescriptorSet, CacheOffset, SamplerInd, SrcImmutableSamplerInd >= 0); - } // - ); - } + Uint32 SamplerInd = VkResource::InvalidSamplerInd; + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) + { + // Separate samplers are enumerated before separate images, so the sampler + // assigned to this separate image must have already been created. + SamplerInd = FindAssignedSampler(*this, *m_pResources, Attribs, CurrResInd[VarType], VarType); + } + ::new (&GetResource(VarType, CurrResInd[VarType]++)) VkResource(*this, Attribs, VarType, Binding, DescriptorSet, CacheOffset, SamplerInd, SrcImmutableSamplerInd >= 0); + } // + ); #ifdef DILIGENT_DEBUG for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -603,42 +598,6 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende #endif } - -ShaderResourceLayoutVk::VkResource::VkResource(const ShaderResourceLayoutVk& _ParentLayout, - const SPIRVShaderResourceAttribs& _SpirvAttribs, - SHADER_RESOURCE_VARIABLE_TYPE _VariableType, - uint32_t _Binding, - uint32_t _DescriptorSet, - Uint32 _CacheOffset, - Uint32 _SamplerInd, - bool _ImmutableSamplerAssigned) noexcept : - // clang-format off - Binding {static_cast(_Binding) }, - DescriptorSet {static_cast(_DescriptorSet)}, - CacheOffset {_CacheOffset }, - SamplerInd {_SamplerInd }, - VariableType {_VariableType }, - ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, - SpirvAttribs {_SpirvAttribs }, - ParentResLayout {_ParentLayout } -// clang-format on -{ - VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits)); - VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits)); - VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max()); - VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); - - const size_t Size = strlen(SpirvAttribs.Name) + 1; - char* NameCopy = ALLOCATE(GetRawAllocator(), "SPIRV Attribs Name", char, Size); - std::memcpy(NameCopy, SpirvAttribs.Name, Size); - const_cast(SpirvAttribs).Name = NameCopy; -} - -ShaderResourceLayoutVk::VkResource::~VkResource() -{ - FREE(GetRawAllocator(), const_cast(SpirvAttribs.Name)); -} - void ShaderResourceLayoutVk::VkResource::UpdateDescriptorHandle(VkDescriptorSet vkDescrSet, uint32_t ArrayElement, const VkDescriptorImageInfo* pImageInfo, -- cgit v1.2.3 From bff90b395a3cbcc96a199cf8db95309b13e8e855 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 23:51:30 +0300 Subject: formating --- Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp | 2 +- Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 4d29093d..c6432f4a 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -308,7 +308,7 @@ public: { return m_pResources->GetShaderType(); } - + const SPIRVShaderResources& GetResources() const { return *m_pResources; } const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index f40f22c8..881196ec 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -575,7 +575,7 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const IsCompatibleShaders = false; break; } - + const auto& Res0 = GetShaderResLayout(s).GetResources(); const auto& Res1 = pPSOVk->GetShaderResLayout(s).GetResources(); if (!Res0.IsCompatibleWith(Res1)) -- cgit v1.2.3 From 91aac63f651da1079be93d2fe722cd10e4e15570 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 10 Oct 2020 19:28:54 -0700 Subject: A number of corrections for PSO refactoring --- .../include/PipelineStateVkImpl.hpp | 13 ++- .../include/ShaderResourceBindingVkImpl.hpp | 2 +- .../include/ShaderResourceLayoutVk.hpp | 23 ++++-- .../src/PipelineStateVkImpl.cpp | 93 ++++++++++------------ .../src/ShaderResourceBindingVkImpl.cpp | 5 +- .../src/ShaderResourceLayoutVk.cpp | 67 ++++++++-------- .../src/VulkanTypeConversions.cpp | 2 +- 7 files changed, 100 insertions(+), 105 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 303496bb..2185dabd 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -56,7 +56,6 @@ class PipelineStateVkImpl final : public PipelineStateBase; - using ShaderSPIRVs_t = std::vector>; PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateCreateInfo& CreateInfo); ~PipelineStateVkImpl(); @@ -105,7 +104,7 @@ public: const ShaderResourceLayoutVk& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_ShaderResourceLayouts[ShaderInd]; } @@ -128,19 +127,19 @@ public: private: const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); - return m_ShaderResourceLayouts[m_NumShaderTypes + ShaderInd]; + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); + return m_ShaderResourceLayouts[GetNumShaderStages() + ShaderInd]; } const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_StaticResCaches[ShaderInd]; } ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaderTypes); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_StaticVarsMgrs[ShaderInd]; } @@ -156,7 +155,7 @@ private: // Resource layout index in m_ShaderResourceLayouts array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex; + std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp index 85230b02..026bb9da 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -81,7 +81,7 @@ private: // Resource layout index in m_ShaderResourceCache array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex; + std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; bool m_bStaticResourcesInitialized = false; Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index c6432f4a..62ff38b5 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -110,13 +110,23 @@ namespace Diligent { +class ShaderVkImpl; + /// Diligent::ShaderResourceLayoutVk class // sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) class ShaderResourceLayoutVk { public: - using ShaderStages_t = std::vector>; - using ShaderSPIRVs_t = std::vector>; + struct ShaderStageInfo + { + ShaderStageInfo(SHADER_TYPE _Type, + const ShaderVkImpl* _pShader); + + const SHADER_TYPE Type; + const ShaderVkImpl* const pShader; + std::vector SPIRV; + }; + using TShaderStages = std::vector; ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : m_LogicalDevice{LogicalDevice} @@ -134,7 +144,7 @@ public: // This method is called by PipelineStateVkImpl class instance to initialize static // shader resource layout and the cache - void InitializeStaticResourceLayout(IShader* pShader, + void InitializeStaticResourceLayout(const ShaderVkImpl* pShader, IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache); @@ -142,11 +152,10 @@ public: // This method is called by PipelineStateVkImpl class instance to initialize resource // layouts for all shader stages in the pipeline. static void Initialize(IRenderDevice* pRenderDevice, - const ShaderStages_t& ShaderStages, + TShaderStages& ShaderStages, ShaderResourceLayoutVk Layouts[], IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderSPIRVs_t& SPIRVs, class PipelineLayout& PipelineLayout, bool VerifyVariables, bool VerifyStaticSamplers); @@ -281,7 +290,7 @@ public: #ifdef DILIGENT_DEVELOPMENT bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache) const; - static void dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, + static void dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, bool VerifyStaticSamplers); @@ -349,7 +358,7 @@ private: return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; } - void AllocateMemory(IShader* pShader, + void AllocateMemory(const ShaderVkImpl* pShader, IMemoryAllocator& Allocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 881196ec..fbc5fae3 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -149,26 +149,21 @@ static bool StripReflection(std::vector& SPIRV) #endif } -static void InitializeShaderStages(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, - const PipelineStateVkImpl::ShaderStages_t& ShaderStages, - PipelineStateVkImpl::ShaderSPIRVs_t& ShaderSPIRVs, - std::vector& ShaderModules, - std::vector& Stages) +static void InitPipelineShaderStages(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, + ShaderResourceLayoutVk::TShaderStages& ShaderStages, + std::vector& vkShaderModules, + std::vector& vkPipelineShaderStages) { - VERIFY_EXPR(ShaderStages.size() == ShaderSPIRVs.size()); - for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderVk = ValidatedCast(ShaderStages[s].second); - auto& SPIRV = ShaderSPIRVs[s]; - const auto ShaderType = ShaderStages[s].first; + auto& StageInfo = ShaderStages[s]; VkPipelineShaderStageCreateInfo StageCI = {}; StageCI.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; StageCI.pNext = nullptr; StageCI.flags = 0; // reserved for future use - StageCI.stage = ShaderTypeToVkShaderStageFlagBit(ShaderType); + StageCI.stage = ShaderTypeToVkShaderStageFlagBit(StageInfo.Type); VkShaderModuleCreateInfo ShaderModuleCI = {}; @@ -179,22 +174,22 @@ static void InitializeShaderStages(const VulkanUtilities::VulkanLogicalDevice& // We have to strip reflection instructions to fix the follownig validation error: // SPIR-V module not valid: DecorateStringGOOGLE requires one of the following extensions: SPV_GOOGLE_decorate_string // Optimizer also performs validation and may catch problems with the byte code. - if (!StripReflection(SPIRV)) - LOG_ERROR("Failed to strip reflection information from shader '", pShaderVk->GetDesc().Name, "'. This may indicate a problem with the byte code."); + if (!StripReflection(StageInfo.SPIRV)) + LOG_ERROR("Failed to strip reflection information from shader '", StageInfo.pShader->GetDesc().Name, "'. This may indicate a problem with the byte code."); - ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); - ShaderModuleCI.pCode = SPIRV.data(); + ShaderModuleCI.codeSize = StageInfo.SPIRV.size() * sizeof(uint32_t); + ShaderModuleCI.pCode = StageInfo.SPIRV.data(); - ShaderModules.push_back(LogicalDevice.CreateShaderModule(ShaderModuleCI, pShaderVk->GetDesc().Name)); + vkShaderModules.push_back(LogicalDevice.CreateShaderModule(ShaderModuleCI, StageInfo.pShader->GetDesc().Name)); - StageCI.module = ShaderModules.back(); - StageCI.pName = pShaderVk->GetEntryPoint(); + StageCI.module = vkShaderModules.back(); + StageCI.pName = StageInfo.pShader->GetEntryPoint(); StageCI.pSpecializationInfo = nullptr; - Stages.push_back(StageCI); + vkPipelineShaderStages.push_back(StageCI); } - VERIFY_EXPR(ShaderModules.size() == Stages.size()); + VERIFY_EXPR(vkShaderModules.size() == vkPipelineShaderStages.size()); } @@ -417,47 +412,41 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - ShaderStages_t ShaderStages; - ShaderSPIRVs_t ShaderSPIRVs; - ExtractShaders(ShaderStages); - - ShaderSPIRVs.resize(ShaderStages.size()); - for (size_t s = 0; s < ShaderSPIRVs.size(); ++s) - { - auto* pShaderVk = ValidatedCast(ShaderStages[s].second); - ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); - } + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders(ShaderStages); // clang-format off static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderTypes(); + const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderStages(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); m_ShaderResourceLayouts = reinterpret_cast(pRawMem); - m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + GetNumShaderTypes() * 2); - m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + GetNumShaderTypes()); + m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + GetNumShaderStages() * 2); + m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + GetNumShaderStages()); for (size_t s = 0; s < ShaderStages.size(); ++s) { + auto& StageInfo = ShaderStages[s]; + const auto ShaderType = StageInfo.Type; + const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - const auto ShaderType = ShaderStages[s].first; - auto& Shaders = ShaderStages[s].second; - const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; - pStaticResLayout->InitializeStaticResourceLayout(Shaders, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); + pStaticResLayout->InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; } ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(), - m_Desc.ResourceLayout, ShaderSPIRVs, m_PipelineLayout, + m_Desc.ResourceLayout, m_PipelineLayout, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); m_PipelineLayout.Finalize(LogicalDevice); @@ -465,7 +454,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun if (m_Desc.SRBAllocationGranularity > 1) { std::array ShaderVariableDataSizes = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; @@ -477,13 +466,13 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun auto DescriptorSetSizes = m_PipelineLayout.GetDescriptorSetSizes(NumSets); auto CacheMemorySize = ShaderResourceCacheVk::GetRequiredMemorySize(NumSets, DescriptorSetSizes.data()); - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); } // Create shader modules and initialize shader stages std::vector VkShaderStages; std::vector ShaderModules; - InitializeShaderStages(LogicalDevice, ShaderStages, ShaderSPIRVs, ShaderModules, VkShaderStages); + InitPipelineShaderStages(LogicalDevice, ShaderStages, ShaderModules, VkShaderStages); // Create pipeline switch (m_Desc.PipelineType) @@ -498,7 +487,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_HasStaticResources = false; m_HasNonStaticResources = false; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) != 0) @@ -518,12 +507,12 @@ PipelineStateVkImpl::~PipelineStateVkImpl() m_PipelineLayout.Release(m_pDevice, m_Desc.CommandQueueMask); auto& RawAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < GetNumShaderTypes() * 2; ++s) + for (Uint32 s = 0; s < GetNumShaderStages() * 2; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); } - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_StaticResCaches[s].~ShaderResourceCacheVk(); m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); @@ -563,14 +552,14 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (GetNumShaderTypes() != pPSOVk->GetNumShaderTypes()) + if (GetNumShaderStages() != pPSOVk->GetNumShaderStages()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { - if (GetShaderTypes()[s] != pPSOVk->GetShaderTypes()[s]) + if (GetShaderStageType(s) != pPSOVk->GetShaderStageType(s)) { IsCompatibleShaders = false; break; @@ -636,7 +625,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind auto& ResourceCache = pResBindingVkImpl->GetResourceCache(); #ifdef DILIGENT_DEVELOPMENT - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { m_ShaderResourceLayouts[s].dvpVerifyBindings(ResourceCache); } @@ -671,7 +660,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind // Allocate vulkan descriptor set for dynamic resources DynamicDescrSet = pCtxVkImpl->AllocateDynamicDescriptorSet(DynamicDescriptorSetVkLayout, DynamicDescrSetName); // Commit all dynamic resource descriptors - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) @@ -688,7 +677,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind void PipelineStateVkImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderType & ShaderFlags) != 0) @@ -732,7 +721,7 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { const auto& StaticResLayout = GetStaticShaderResLayout(s); const auto& StaticResCache = GetStaticResCache(s); @@ -742,7 +731,7 @@ void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& Re { LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", GetDesc().Name, "' will not be successfully initialized because not all static resource bindings in shader '", - GetShaderTypeLiteralName(GetShaderTypes()[s]), + GetShaderTypeLiteralName(GetShaderStageType(s)), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 75f3bb37..91008811 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -49,8 +49,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); - auto* pShaderTypes = pPSO->GetShaderTypes(); - m_NumShaders = static_cast(pPSO->GetNumShaderTypes()); + m_NumShaders = static_cast(pPSO->GetNumShaderStages()); auto* pRenderDeviceVkImpl = pPSO->GetDevice(); // This will only allocate memory and initialize descriptor sets in the resource cache @@ -62,7 +61,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto ShaderInd = GetShaderTypePipelineIndex(pShaderTypes[s], pPSO->GetDesc().PipelineType); + auto ShaderInd = GetShaderTypePipelineIndex(pPSO->GetShaderStageType(s), pPSO->GetDesc().PipelineType); m_ResourceLayoutIndex[ShaderInd] = static_cast(s); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index a7410210..8b00c394 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -93,6 +93,14 @@ static SHADER_RESOURCE_VARIABLE_TYPE FindShaderVariableType(SHADER_TYPE } } +ShaderResourceLayoutVk::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, + const ShaderVkImpl* _pShader) : + Type{_Type}, + pShader{_pShader}, + SPIRV{pShader->GetSPIRV()} +{ +} + ShaderResourceLayoutVk::~ShaderResourceLayoutVk() { @@ -103,7 +111,7 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() GetImmutableSampler(s).~ImmutableSamplerPtrType(); } -void ShaderResourceLayoutVk::AllocateMemory(IShader* pShader, +void ShaderResourceLayoutVk::AllocateMemory(const ShaderVkImpl* pShader, IMemoryAllocator& Allocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, @@ -112,16 +120,14 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); VERIFY_EXPR(!m_pResources); + m_pResources = pShader->GetShaderResources(); - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - const auto ShaderType = pShader->GetDesc().ShaderType; + const auto ShaderType = pShader->GetDesc().ShaderType; + VERIFY_EXPR(m_pResources->GetShaderType() == ShaderType); // Count the number of resources to allocate all needed memory { - auto* pShaderVk = ValidatedCast(pShader); - auto pResources = pShaderVk->GetShaderResources(); - const auto* CombinedSamplerSuffix = pResources->GetCombinedSamplerSuffix(); - VERIFY_EXPR(pResources->GetShaderType() == ShaderType); - m_pResources = pResources; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) // { @@ -172,11 +178,11 @@ void ShaderResourceLayoutVk::AllocateMemory(IShader* } -Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, - const SPIRVShaderResources& Resources, - const SPIRVShaderResourceAttribs& SepImg, - Uint32 CurrResourceCount, - SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) +static Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, + const SPIRVShaderResources& Resources, + const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) { using VkResource = ShaderResourceLayoutVk::VkResource; VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); @@ -211,7 +217,7 @@ Uint32 FindAssignedSampler(const ShaderResourceLayoutVk& Layout, } -void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* pShader, +void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const ShaderVkImpl* pShader, IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache) @@ -277,7 +283,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(IShader* } #ifdef DILIGENT_DEVELOPMENT -void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& ShaderStages, +void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, bool VerifyStaticSamplers) @@ -290,11 +296,11 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& const auto ShaderType = Stages & static_cast(~(static_cast(Stages) - 1)); const char* ShaderName = nullptr; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& StageInfo : ShaderStages) { - if ((Stages & ShaderStages[s].first) != 0) + if ((Stages & StageInfo.Type) != 0) { - ShaderName = ShaderStages[s].second->GetDesc().Name; + ShaderName = StageInfo.pShader->GetDesc().Name; break; } } @@ -334,8 +340,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& bool VariableFound = false; for (size_t s = 0; s < ShaderStages.size() && !VariableFound; ++s) { - const auto* pShaderVk = ValidatedCast(ShaderStages[s].second); - const auto& Resources = *pShaderVk->GetShaderResources(); + const auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); if ((VarDesc.ShaderStages & Resources.GetShaderType()) != 0) { for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) @@ -368,8 +373,7 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& bool SamplerFound = false; for (size_t s = 0; s < ShaderStages.size() && !SamplerFound; ++s) { - const auto* pShaderVk = ValidatedCast(ShaderStages[s].second); - const auto& Resources = *pShaderVk->GetShaderResources(); + const auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); if ((StSamDesc.ShaderStages & Resources.GetShaderType()) == 0) continue; @@ -407,11 +411,10 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const ShaderStages_t& #endif void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRenderDevice, - const ShaderStages_t& ShaderStages, + TShaderStages& ShaderStages, ShaderResourceLayoutVk Layouts[], IMemoryAllocator& LayoutDataAllocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderSPIRVs_t& SPIRVs, class PipelineLayout& PipelineLayout, bool VerifyVariables, bool VerifyStaticSamplers) @@ -427,7 +430,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende for (size_t s = 0; s < ShaderStages.size(); ++s) { - Layouts[s].AllocateMemory(ShaderStages[s].second, LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); + Layouts[s].AllocateMemory(ShaderStages[s].pShader, LayoutDataAllocator, ResourceLayoutDesc, + AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); } //VERIFY_EXPR(NumShaders <= MAX_SHADERS_IN_PIPELINE); @@ -475,7 +479,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende } } - auto& ShaderSPIRV = SPIRVs[ShaderInd]; + auto& ShaderSPIRV = ShaderStages[ShaderInd].SPIRV; PipelineLayout.AllocateResourceSlot(Attribs, VarType, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); VERIFY(DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", DescriptorSet, ") excceeds maximum representable value"); VERIFY(Binding <= std::numeric_limits::max(), "Binding (", Binding, ") excceeds maximum representable value"); @@ -498,9 +502,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // First process uniform buffers for all shader stages to make sure all UBs go first in every descriptor set for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast(pShader); + auto* pShaderVk = ShaderStages[s].pShader; auto& Resources = *pShaderVk->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n) { @@ -516,10 +519,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // Second, process all storage buffers for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast(pShader); - auto& Resources = *pShaderVk->GetShaderResources(); + auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n) { const auto& SB = Resources.GetSB(n); @@ -534,10 +535,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende // Finally, process all other resource types for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto& pShader = ShaderStages[s].second; auto& Layout = Layouts[s]; - auto* pShaderVk = ValidatedCast(pShader); - auto& Resources = *pShaderVk->GetShaderResources(); + auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); // clang-format off Resources.ProcessResources( [&](const SPIRVShaderResourceAttribs& UB, Uint32) diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index 95261295..55bb7d8f 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1515,7 +1515,7 @@ VkAccessFlags AccessFlagsToVkAccessFlags(ACCESS_FLAGS AccessFlags) VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType) { static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); - VERIFY((ShaderType & (ShaderType - 1)) == 0, "More than one shader type specified"); + VERIFY(IsPowerOfTwo(Uint32{ShaderType}), "More than one shader type is specified"); switch (ShaderType) { // clang-format off -- cgit v1.2.3 From b3fec8bd40e80115086281bce74774617aa95e23 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 14 Oct 2020 01:04:05 -0700 Subject: Added buffer mode validation when binding buffer views --- .../src/ShaderResourceLayoutVk.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 8b00c394..7f726e69 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -702,6 +702,16 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject* // HLSL buffer SRVs are mapped to storge buffers in GLSL auto RequiredViewType = SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer ? BUFFER_VIEW_SHADER_RESOURCE : BUFFER_VIEW_UNORDERED_ACCESS; VerifyResourceViewBinding(SpirvAttribs, GetVariableType(), ArrayInd, pBufferView, pBufferViewVk.RawPtr(), {RequiredViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + if (pBufferViewVk != nullptr) + { + const auto& ViewDesc = pBufferViewVk->GetDesc(); + const auto& BuffDesc = pBufferViewVk->GetBuffer()->GetDesc(); + if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW) + { + LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + SpirvAttribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "': structured buffer view is expected."); + } + } } #endif @@ -748,6 +758,16 @@ void ShaderResourceLayoutVk::VkResource::CacheTexelBuffer(IDeviceObject* // HLSL buffer SRVs are mapped to storge buffers in GLSL auto RequiredViewType = SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer ? BUFFER_VIEW_UNORDERED_ACCESS : BUFFER_VIEW_SHADER_RESOURCE; VerifyResourceViewBinding(SpirvAttribs, GetVariableType(), ArrayInd, pBufferView, pBufferViewVk.RawPtr(), {RequiredViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + if (pBufferViewVk != nullptr) + { + const auto& ViewDesc = pBufferViewVk->GetDesc(); + const auto& BuffDesc = pBufferViewVk->GetBuffer()->GetDesc(); + if (!(BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED || BuffDesc.Mode == BUFFER_MODE_RAW)) + { + LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + SpirvAttribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "': formatted buffer view is expected."); + } + } } #endif -- cgit v1.2.3 From 259a9d5897937dcaaca1b4b294bb8d5250371e76 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 15 Oct 2020 20:55:38 +0300 Subject: Added GraphicsPipelineCreateInfo and ComputePipelineCreateInfo instead of single PipelineCreateInfo. Some optimizations for dynamic memory allocations in PipelineState. --- .../include/PipelineStateVkImpl.hpp | 14 +- .../include/RenderDeviceVkImpl.hpp | 7 +- .../src/DeviceContextVkImpl.cpp | 68 +++++----- .../src/GenerateMipsVkHelper.cpp | 12 +- .../src/PipelineStateVkImpl.cpp | 147 ++++++++++++++------- .../src/RenderDeviceVkImpl.cpp | 16 ++- 6 files changed, 170 insertions(+), 94 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 2185dabd..1773e743 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -57,7 +57,8 @@ class PipelineStateVkImpl final : public PipelineStateBase; - PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateCreateInfo& CreateInfo); + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const GraphicsPipelineStateCreateInfo& CreateInfo); + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const ComputePipelineStateCreateInfo& CreateInfo); ~PipelineStateVkImpl(); virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; @@ -125,6 +126,11 @@ public: void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const; private: + using TShaderStages = ShaderResourceLayoutVk::TShaderStages; + void InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, + const PipelineStateCreateInfo& CreateInfo, + TShaderStages& ShaderStages); + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { VERIFY_EXPR(ShaderInd < GetNumShaderStages()); @@ -143,9 +149,9 @@ private: return m_StaticVarsMgrs[ShaderInd]; } - ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; - ShaderResourceCacheVk* m_StaticResCaches = nullptr; - ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; + ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; // [m_NumShaderStages * 2] + ShaderResourceCacheVk* m_StaticResCaches = nullptr; // [m_NumShaderStages] + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages] // SRB memory allocator must be declared before m_pDefaultShaderResBinding SRBMemoryAllocator m_SRBMemAllocator; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 25a9f44b..24f3345c 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -72,8 +72,11 @@ public: virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - /// Implementation of IRenderDevice::CreatePipelineState() in Vulkan backend. - virtual void DILIGENT_CALL_TYPE CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateGraphicsPipelineState() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateComputePipelineState() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; /// Implementation of IRenderDevice::CreateBuffer() in Vulkan backend. virtual void DILIGENT_CALL_TYPE CreateBuffer(const BufferDesc& BuffDesc, diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 2d7b9591..c8b231c2 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -257,39 +257,49 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState) else { const auto& OldPSODesc = m_pPipelineState->GetDesc(); - // Commit all graphics states when switching from compute pipeline + // Commit all graphics states when switching from non-graphics pipeline // This is necessary because if the command list had been flushed // and the first PSO set on the command list was a compute pipeline, // the states would otherwise never be committed (since m_pPipelineState != nullptr) - CommitStates = OldPSODesc.IsComputePipeline(); + CommitStates = !OldPSODesc.IsAnyGraphicsPipeline(); // We also need to update scissor rect if ScissorEnable state was disabled in previous pipeline - CommitScissor = !OldPSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable; + if (OldPSODesc.IsAnyGraphicsPipeline()) + CommitScissor = !m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable; } TDeviceContextBase::SetPipelineState(pPipelineStateVk, 0 /*Dummy*/); EnsureVkCmdBuffer(); - if (PSODesc.IsComputePipeline()) - { - auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - m_CommandBuffer.BindComputePipeline(vkPipeline); - } - else - { - auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - m_CommandBuffer.BindGraphicsPipeline(vkPipeline); + auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - if (CommitStates) + switch (PSODesc.PipelineType) + { + case PIPELINE_TYPE_GRAPHICS: + case PIPELINE_TYPE_MESH: { - m_CommandBuffer.SetStencilReference(m_StencilRef); - m_CommandBuffer.SetBlendConstants(m_BlendFactors); - CommitViewports(); - } + auto& GraphicsPipeline = pPipelineStateVk->GetGraphicsPipelineDesc(); + m_CommandBuffer.BindGraphicsPipeline(vkPipeline); + + if (CommitStates) + { + m_CommandBuffer.SetStencilReference(m_StencilRef); + m_CommandBuffer.SetBlendConstants(m_BlendFactors); + CommitViewports(); + } - if (PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable && (CommitStates || CommitScissor)) + if (GraphicsPipeline.RasterizerDesc.ScissorEnable && (CommitStates || CommitScissor)) + { + CommitScissorRects(); + } + break; + } + case PIPELINE_TYPE_COMPUTE: { - CommitScissorRects(); + m_CommandBuffer.BindComputePipeline(vkPipeline); + break; } + default: + UNEXPECTED("unknown pipeline type"); } m_DescrSetBindInfo.Reset(); @@ -381,8 +391,11 @@ void DeviceContextVkImpl::CommitVkVertexBuffers() void DeviceContextVkImpl::DvpLogRenderPass_PSOMismatch() { + const auto& Desc = m_pPipelineState->GetDesc(); + const auto& GrPipeline = m_pPipelineState->GetGraphicsPipelineDesc(); + std::stringstream ss; - ss << "Active render pass is incomaptible with PSO '" << m_pPipelineState->GetDesc().Name + ss << "Active render pass is incomaptible with PSO '" << Desc.Name << "'. This indicates the mismatch between the number and/or format of bound render " "targets and/or depth stencil buffer and the PSO. Vulkand requires exact match.\n" " Bound render targets (" @@ -411,7 +424,6 @@ void DeviceContextVkImpl::DvpLogRenderPass_PSOMismatch() ss << ""; ss << "; Sample count: " << SampleCount; - const auto& GrPipeline = m_pPipelineState->GetDesc().GraphicsPipeline; ss << "\n PSO: render targets (" << Uint32{GrPipeline.NumRenderTargets} << "): "; for (Uint32 rt = 0; rt < GrPipeline.NumRenderTargets; ++rt) ss << ' ' << GetTextureFormatAttribs(GrPipeline.RTVFormats[rt]).Name; @@ -472,7 +484,7 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags) # endif #endif - if (m_pPipelineState->GetDesc().GraphicsPipeline.pRenderPass == nullptr) + if (m_pPipelineState->GetGraphicsPipelineDesc().pRenderPass == nullptr) { #ifdef DILIGENT_DEVELOPMENT if (m_pPipelineState->GetRenderPass()->GetVkRenderPass() != m_vkRenderPass) @@ -1110,7 +1122,7 @@ void DeviceContextVkImpl::SetViewports(Uint32 NumViewports, const Viewport* pVie void DeviceContextVkImpl::CommitScissorRects() { - VERIFY(m_pPipelineState && m_pPipelineState->GetDesc().GraphicsPipeline.RasterizerDesc.ScissorEnable, "Scissor test must be enabled in the graphics pipeline"); + VERIFY(m_pPipelineState && m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable, "Scissor test must be enabled in the graphics pipeline"); if (m_NumScissorRects == 0) return; // Scissors have not been set in the context yet @@ -1136,14 +1148,10 @@ void DeviceContextVkImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U // Only commit scissor rects if scissor test is enabled in the rasterizer state. // If scissor is currently disabled, or no PSO is bound, scissor rects will be committed by // the SetPipelineState() when a PSO with enabled scissor test is set. - if (m_pPipelineState) + if (m_pPipelineState && m_pPipelineState->GetDesc().IsAnyGraphicsPipeline() && m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable) { - const auto& PSODesc = m_pPipelineState->GetDesc(); - if (PSODesc.IsAnyGraphicsPipeline() && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable) - { - VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); - CommitScissorRects(); - } + VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); + CommitScissorRects(); } } diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 5110c873..d6f4b0be 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -154,12 +154,12 @@ std::array, 4> GenerateMipsVkHelper::CreatePSOs(TE m_DeviceVkImpl.CreateShader(CSCreateInfo, &pCS); - PipelineStateCreateInfo PSOCreateInfo; - PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; + ComputePipelineStateCreateInfo PSOCreateInfo; + PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; - PSODesc.PipelineType = PIPELINE_TYPE_COMPUTE; - PSODesc.Name = name.c_str(); - PSODesc.ComputePipeline.pCS = pCS; + PSODesc.PipelineType = PIPELINE_TYPE_COMPUTE; + PSODesc.Name = name.c_str(); + PSOCreateInfo.pCS = pCS; PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; ShaderResourceVariableDesc VarDesc{SHADER_TYPE_COMPUTE, "CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; @@ -170,7 +170,7 @@ std::array, 4> GenerateMipsVkHelper::CreatePSOs(TE PSODesc.ResourceLayout.StaticSamplers = &StaticSampler; PSODesc.ResourceLayout.NumStaticSamplers = 1; - m_DeviceVkImpl.CreatePipelineState(PSOCreateInfo, &PSOs[NonPowOfTwo]); + m_DeviceVkImpl.CreateComputePipelineState(PSOCreateInfo, &PSOs[NonPowOfTwo]); PSOs[NonPowOfTwo]->GetStaticVariableByName(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); } #endif diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index fbc5fae3..3e4154be 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -196,7 +196,7 @@ static void InitPipelineShaderStages(const VulkanUtilities::VulkanLogicalDevice& static void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk, std::vector& Stages, const PipelineLayout& Layout, - const PipelineStateDesc& Desc, + const PipelineStateDesc& PSODesc, VulkanUtilities::PipelineWrapper& Pipeline) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); @@ -214,21 +214,21 @@ static void CreateComputePipeline(RenderDeviceVkImpl* PipelineCI.stage = Stages[0]; PipelineCI.layout = Layout.GetVkPipelineLayout(); - Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); + Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } static void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk, std::vector& Stages, const PipelineLayout& Layout, - const PipelineStateDesc& Desc, + const PipelineStateDesc& PSODesc, + const GraphicsPipelineDesc& GraphicsPipeline, VulkanUtilities::PipelineWrapper& Pipeline, RefCntAutoPtr& pRenderPass) { - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); - auto& GraphicsPipeline = Desc.GraphicsPipeline; - auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); + const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); + auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); if (pRenderPass == nullptr) { @@ -276,7 +276,7 @@ static void CreateGraphicsPipeline(RenderDeviceVkImpl* TessStateCI.flags = 0; // reserved for future use PipelineCI.pTessellationState = &TessStateCI; - if (Desc.PipelineType == PIPELINE_TYPE_MESH) + if (PSODesc.PipelineType == PIPELINE_TYPE_MESH) { // Input assembly is not used in the mesh pipeline, so topology may contain any value. // Validation layers may generate a warning if point_list topology is used, so use MAX_ENUM value. @@ -394,40 +394,19 @@ static void CreateGraphicsPipeline(RenderDeviceVkImpl* PipelineCI.renderPass = pRenderPass.RawPtr()->GetVkRenderPass(); - PipelineCI.subpass = Desc.GraphicsPipeline.SubpassIndex; + PipelineCI.subpass = GraphicsPipeline.SubpassIndex; PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from - Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); + Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } - -PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDeviceVk, - const PipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, - m_SRBMemAllocator{GetRawAllocator()} +void PipelineStateVkImpl::InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, + const PipelineStateCreateInfo& CreateInfo, + TShaderStages& ShaderStages) { - m_ResourceLayoutIndex.fill(-1); - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - ShaderResourceLayoutVk::TShaderStages ShaderStages; - ExtractShaders(ShaderStages); - - // clang-format off - static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); - // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderStages(); - auto* const pRawMem = - ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); - - m_ShaderResourceLayouts = reinterpret_cast(pRawMem); - m_StaticResCaches = reinterpret_cast(m_ShaderResourceLayouts + GetNumShaderStages() * 2); - m_StaticVarsMgrs = reinterpret_cast(m_StaticResCaches + GetNumShaderStages()); - for (size_t s = 0; s < ShaderStages.size(); ++s) { auto& StageInfo = ShaderStages[s]; @@ -436,7 +415,6 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; @@ -469,22 +447,6 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); } - // Create shader modules and initialize shader stages - std::vector VkShaderStages; - std::vector ShaderModules; - InitPipelineShaderStages(LogicalDevice, ShaderStages, ShaderModules, VkShaderStages); - - // Create pipeline - switch (m_Desc.PipelineType) - { - // clang-format off - case PIPELINE_TYPE_GRAPHICS: - case PIPELINE_TYPE_MESH: CreateGraphicsPipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline, m_pRenderPass); break; - case PIPELINE_TYPE_COMPUTE: CreateComputePipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); break; - default: UNEXPECTED("unknown pipeline type"); - // clang-format on - } - m_HasStaticResources = false; m_HasNonStaticResources = false; for (Uint32 s = 0; s < GetNumShaderStages(); ++s) @@ -501,6 +463,89 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_ShaderResourceLayoutHash = m_PipelineLayout.GetHash(); } + +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const GraphicsPipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages() * 2); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + m_ShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); + m_StaticResCaches = MemPool.Allocate(GetNumShaderStages()); + m_StaticVarsMgrs = MemPool.Allocate(GetNumShaderStages()); + + InitGraphicsPipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); + + // Create shader modules and initialize shader stages + std::vector VkShaderStages; + std::vector ShaderModules; + InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); + + CreateGraphicsPipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); +} + + +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const ComputePipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages() * 2); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + m_ShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); + m_StaticResCaches = MemPool.Allocate(GetNumShaderStages()); + m_StaticVarsMgrs = MemPool.Allocate(GetNumShaderStages()); + + InitComputePipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); + + // Create shader modules and initialize shader stages + std::vector VkShaderStages; + std::vector ShaderModules; + InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); + + CreateComputePipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); +} + + PipelineStateVkImpl::~PipelineStateVkImpl() { m_pDevice->SafeReleaseDeviceObject(std::move(m_Pipeline), m_Desc.CommandQueueMask); diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index f6e337c2..ca729479 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -541,7 +541,21 @@ void RenderDeviceVkImpl::TestTextureFormat(TEXTURE_FORMAT TexFormat) IMPLEMENT_QUERY_INTERFACE(RenderDeviceVkImpl, IID_RenderDeviceVk, TRenderDeviceBase) -void RenderDeviceVkImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +void RenderDeviceVkImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreateDeviceObject( + "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, + [&]() // + { + PipelineStateVkImpl* pPipelineStateVk(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateVkImpl instance", PipelineStateVkImpl)(this, PSOCreateInfo)); + pPipelineStateVk->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); + OnCreateDeviceObject(pPipelineStateVk); + } // + ); +} + + +void RenderDeviceVkImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { CreateDeviceObject( "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, -- cgit v1.2.3 From 645ef7e425d6ff4ee64b782d27767e0a5732be50 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 18 Oct 2020 13:06:48 -0700 Subject: A number of fixes for PSO creation refactoring (API240075) --- .../include/PipelineStateVkImpl.hpp | 9 ++- .../include/RenderDeviceVkImpl.hpp | 3 + .../src/PipelineStateVkImpl.cpp | 77 +++++++++------------- .../src/RenderDeviceVkImpl.cpp | 18 +++-- 4 files changed, 50 insertions(+), 57 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 1773e743..96b34008 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -127,8 +127,13 @@ public: private: using TShaderStages = ShaderResourceLayoutVk::TShaderStages; - void InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, - const PipelineStateCreateInfo& CreateInfo, + + template + LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& vkShaderStages, + std::vector& ShaderModules); + + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 24f3345c..469e8119 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -183,6 +183,9 @@ public: IDXCompiler* GetDxCompiler() const { return m_pDxCompiler.get(); } private: + template + void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState); + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; // Submits command buffer for execution to the command queue diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 3e4154be..dfa270cc 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -401,10 +401,10 @@ static void CreateGraphicsPipeline(RenderDeviceVkImpl* Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } -void PipelineStateVkImpl::InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, - const PipelineStateCreateInfo& CreateInfo, +void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages) { + auto* const pDeviceVk = GetDevice(); const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); for (size_t s = 0; s < ShaderStages.size(); ++s) @@ -463,26 +463,24 @@ void PipelineStateVkImpl::InitResourceLayouts(RenderDeviceVkImpl* pDe m_ShaderResourceLayoutHash = m_PipelineLayout.GetHash(); } - -PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDeviceVk, - const GraphicsPipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, - m_SRBMemAllocator{GetRawAllocator()} +template +LinearAllocator PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& vkShaderStages, + std::vector& ShaderModules) { m_ResourceLayoutIndex.fill(-1); - ShaderResourceLayoutVk::TShaderStages ShaderStages; + TShaderStages ShaderStages; ExtractShaders(CreateInfo, ShaderStages); // Memory must be released if an exception is thrown. LinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddRequiredSize(GetNumShaderStages() * 2); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddSpace(GetNumShaderStages() * 2); + MemPool.AddSpace(GetNumShaderStages()); + MemPool.AddSpace(GetNumShaderStages()); - ValidateAndReserveSpace(CreateInfo, MemPool); + ReserveSpaceForPipelineDesc(CreateInfo, MemPool); MemPool.Reserve(); @@ -490,15 +488,27 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* m_StaticResCaches = MemPool.Allocate(GetNumShaderStages()); m_StaticVarsMgrs = MemPool.Allocate(GetNumShaderStages()); - InitGraphicsPipeline(CreateInfo, MemPool); - InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); + InitializePipelineDesc(CreateInfo, MemPool); + InitResourceLayouts(CreateInfo, ShaderStages); // Create shader modules and initialize shader stages - std::vector VkShaderStages; + InitPipelineShaderStages(GetDevice()->GetLogicalDevice(), ShaderStages, ShaderModules, vkShaderStages); + + return MemPool; +} + +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const GraphicsPipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + std::vector vkShaderStages; std::vector ShaderModules; - InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); - CreateGraphicsPipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); + auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + + CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); void* Ptr = MemPool.Release(); VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); @@ -511,35 +521,12 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* p TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { - m_ResourceLayoutIndex.fill(-1); - - ShaderResourceLayoutVk::TShaderStages ShaderStages; - ExtractShaders(CreateInfo, ShaderStages); - - // Memory must be released if an exception is thrown. - LinearAllocator MemPool{GetRawAllocator()}; - - MemPool.AddRequiredSize(GetNumShaderStages() * 2); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); - - ValidateAndReserveSpace(CreateInfo, MemPool); - - MemPool.Reserve(); - - m_ShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); - m_StaticResCaches = MemPool.Allocate(GetNumShaderStages()); - m_StaticVarsMgrs = MemPool.Allocate(GetNumShaderStages()); - - InitComputePipeline(CreateInfo, MemPool); - InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); - - // Create shader modules and initialize shader stages - std::vector VkShaderStages; + std::vector vkShaderStages; std::vector ShaderModules; - InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); - CreateComputePipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); + auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + + CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); void* Ptr = MemPool.Release(); VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index ca729479..1441569e 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -541,7 +541,8 @@ void RenderDeviceVkImpl::TestTextureFormat(TEXTURE_FORMAT TexFormat) IMPLEMENT_QUERY_INTERFACE(RenderDeviceVkImpl, IID_RenderDeviceVk, TRenderDeviceBase) -void RenderDeviceVkImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +template +void RenderDeviceVkImpl::CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState) { CreateDeviceObject( "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, @@ -554,18 +555,15 @@ void RenderDeviceVkImpl::CreateGraphicsPipelineState(const GraphicsPipelineState ); } +void RenderDeviceVkImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreatePipelineState(PSOCreateInfo, ppPipelineState); +} + void RenderDeviceVkImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { - CreateDeviceObject( - "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, - [&]() // - { - PipelineStateVkImpl* pPipelineStateVk(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateVkImpl instance", PipelineStateVkImpl)(this, PSOCreateInfo)); - pPipelineStateVk->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); - OnCreateDeviceObject(pPipelineStateVk); - } // - ); + CreatePipelineState(PSOCreateInfo, ppPipelineState); } -- cgit v1.2.3 From ff88c0507d8e8d4571b00adb421557bca1f4ed48 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 18 Oct 2020 17:25:39 -0700 Subject: Updated third-party modules; fixed compiler warnings --- Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 7f726e69..33e0aa82 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -762,7 +762,7 @@ void ShaderResourceLayoutVk::VkResource::CacheTexelBuffer(IDeviceObject* { const auto& ViewDesc = pBufferViewVk->GetDesc(); const auto& BuffDesc = pBufferViewVk->GetBuffer()->GetDesc(); - if (!(BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED || BuffDesc.Mode == BUFFER_MODE_RAW)) + if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW)) { LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", SpirvAttribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "': formatted buffer view is expected."); -- cgit v1.2.3 From a520bf4f9748d20e432bcf7994be3148d0b75d54 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 10:21:30 -0700 Subject: Renamed static sampler to immutable sampler (API240076) --- .../include/ShaderResourceLayoutVk.hpp | 4 +- .../src/GenerateMipsVkHelper.cpp | 6 +-- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 2 +- .../src/PipelineStateVkImpl.cpp | 2 +- .../src/ShaderResourceLayoutVk.cpp | 44 +++++++++++----------- 5 files changed, 29 insertions(+), 29 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 62ff38b5..0013fe23 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -158,7 +158,7 @@ public: const PipelineResourceLayoutDesc& ResourceLayoutDesc, class PipelineLayout& PipelineLayout, bool VerifyVariables, - bool VerifyStaticSamplers); + bool VerifyImmutableSamplers); // sizeof(VkResource) == 24 (x64) struct VkResource @@ -293,7 +293,7 @@ public: static void dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, - bool VerifyStaticSamplers); + bool VerifyImmutableSamplers); #endif Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index d6f4b0be..e7ab95b1 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -166,9 +166,9 @@ std::array, 4> GenerateMipsVkHelper::CreatePSOs(TE PSODesc.ResourceLayout.Variables = &VarDesc; PSODesc.ResourceLayout.NumVariables = 1; - const StaticSamplerDesc StaticSampler(SHADER_TYPE_COMPUTE, "SrcMip", Sam_LinearClamp); - PSODesc.ResourceLayout.StaticSamplers = &StaticSampler; - PSODesc.ResourceLayout.NumStaticSamplers = 1; + const ImmutableSamplerDesc ImtblSampler{SHADER_TYPE_COMPUTE, "SrcMip", Sam_LinearClamp}; + PSODesc.ResourceLayout.ImmutableSamplers = &ImtblSampler; + PSODesc.ResourceLayout.NumImmutableSamplers = 1; m_DeviceVkImpl.CreateComputePipelineState(PSOCreateInfo, &PSOs[NonPowOfTwo]); PSOs[NonPowOfTwo]->GetStaticVariableByName(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 6ed84171..b221659a 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -213,7 +213,7 @@ bool PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::operator== if ((B0.pImmutableSamplers != nullptr && B1.pImmutableSamplers == nullptr) || (B0.pImmutableSamplers == nullptr && B1.pImmutableSamplers != nullptr)) return false; - // Static samplers themselves should not affect compatibility + // Immutable samplers themselves should not affect compatibility // clang-format on } return true; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index dfa270cc..6cbe5da9 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -426,7 +426,7 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(), m_Desc.ResourceLayout, m_PipelineLayout, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, - (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); + (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_IMMUTABLE_SAMPLERS) == 0); m_PipelineLayout.Finalize(LogicalDevice); if (m_Desc.SRBAllocationGranularity > 1) diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 33e0aa82..e73ee9aa 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -63,10 +63,10 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, return -1; } - for (Uint32 s = 0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + for (Uint32 s = 0; s < ResourceLayoutDesc.NumImmutableSamplers; ++s) { - const auto& StSam = ResourceLayoutDesc.StaticSamplers[s]; - if (((StSam.ShaderStages & ShaderType) != 0) && StreqSuff(Attribs.Name, StSam.SamplerOrTextureName, SamplerSuffix)) + const auto& ImtblSam = ResourceLayoutDesc.ImmutableSamplers[s]; + if (((ImtblSam.ShaderStages & ShaderType) != 0) && StreqSuff(Attribs.Name, ImtblSam.SamplerOrTextureName, SamplerSuffix)) return s; } @@ -154,10 +154,10 @@ void ShaderResourceLayoutVk::AllocateMemory(const ShaderVkImpl* m_NumImmutableSamplers = 0; if (AllocateImmutableSamplers) { - for (Uint32 s = 0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + for (Uint32 s = 0; s < ResourceLayoutDesc.NumImmutableSamplers; ++s) { - const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; - if ((StSamDesc.ShaderStages & ShaderType) != 0) + const auto& ImtblSamDesc = ResourceLayoutDesc.ImmutableSamplers[s]; + if ((ImtblSamDesc.ShaderStages & ShaderType) != 0) ++m_NumImmutableSamplers; } } @@ -286,7 +286,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const ShaderVkImpl* void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& ShaderStages, const PipelineResourceLayoutDesc& ResourceLayoutDesc, bool VerifyVariables, - bool VerifyStaticSamplers) + bool VerifyImmutableSamplers) { auto GetAllowedShadersString = [&](SHADER_TYPE Stages) // { @@ -359,14 +359,14 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& } } - if (VerifyStaticSamplers) + if (VerifyImmutableSamplers) { - for (Uint32 sam = 0; sam < ResourceLayoutDesc.NumStaticSamplers; ++sam) + for (Uint32 sam = 0; sam < ResourceLayoutDesc.NumImmutableSamplers; ++sam) { - const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[sam]; - if (StSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) + const auto& ImtblSamDesc = ResourceLayoutDesc.ImmutableSamplers[sam]; + if (ImtblSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { - LOG_WARNING_MESSAGE("No allowed shader stages are specified for static sampler '", StSamDesc.SamplerOrTextureName, "'."); + LOG_WARNING_MESSAGE("No allowed shader stages are specified for immutable sampler '", ImtblSamDesc.SamplerOrTextureName, "'."); continue; } @@ -374,36 +374,36 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& for (size_t s = 0; s < ShaderStages.size() && !SamplerFound; ++s) { const auto& Resources = *ShaderStages[s].pShader->GetShaderResources(); - if ((StSamDesc.ShaderStages & Resources.GetShaderType()) == 0) + if ((ImtblSamDesc.ShaderStages & Resources.GetShaderType()) == 0) continue; // Irrespective of whether HLSL-style combined image samplers are used, - // a static sampler can be assigned to GLSL sampled image (i.e. sampler2D g_tex) + // an immutable sampler can be assigned to a GLSL sampled image (i.e. sampler2D g_tex) for (Uint32 i = 0; i < Resources.GetNumSmpldImgs() && !SamplerFound; ++i) { const auto& SmplImg = Resources.GetSmpldImg(i); - SamplerFound = (strcmp(SmplImg.Name, StSamDesc.SamplerOrTextureName) == 0); + SamplerFound = (strcmp(SmplImg.Name, ImtblSamDesc.SamplerOrTextureName) == 0); } if (!SamplerFound) { - // Check if static sampler is assigned to a separate sampler. + // Check if an immutable sampler is assigned to a separate sampler. // In case HLSL-style combined image samplers are used, the condition is SepSmpl.Name == "g_Texture" + "_sampler". // Otherwise the condition is SepSmpl.Name == "g_Texture_sampler" + "". const auto* CombinedSamplerSuffix = Resources.GetCombinedSamplerSuffix(); for (Uint32 i = 0; i < Resources.GetNumSepSmplrs() && !SamplerFound; ++i) { const auto& SepSmpl = Resources.GetSepSmplr(i); - SamplerFound = StreqSuff(SepSmpl.Name, StSamDesc.SamplerOrTextureName, CombinedSamplerSuffix); + SamplerFound = StreqSuff(SepSmpl.Name, ImtblSamDesc.SamplerOrTextureName, CombinedSamplerSuffix); } } } if (!SamplerFound) { - LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, + LOG_WARNING_MESSAGE("Immutable sampler '", ImtblSamDesc.SamplerOrTextureName, "' is not found in any of the designated shader stages: ", - GetAllowedShadersString(StSamDesc.ShaderStages)); + GetAllowedShadersString(ImtblSamDesc.ShaderStages)); } } } @@ -417,10 +417,10 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende const PipelineResourceLayoutDesc& ResourceLayoutDesc, class PipelineLayout& PipelineLayout, bool VerifyVariables, - bool VerifyStaticSamplers) + bool VerifyImmutableSamplers) { #ifdef DILIGENT_DEVELOPMENT - dvpVerifyResourceLayoutDesc(ShaderStages, ResourceLayoutDesc, VerifyVariables, VerifyStaticSamplers); + dvpVerifyResourceLayoutDesc(ShaderStages, ResourceLayoutDesc, VerifyVariables, VerifyImmutableSamplers); #endif const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; @@ -473,7 +473,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende { auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++); VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized!"); - const auto& ImmutableSamplerDesc = ResourceLayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; + const auto& ImmutableSamplerDesc = ResourceLayoutDesc.ImmutableSamplers[SrcImmutableSamplerInd].Desc; pRenderDevice->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); vkImmutableSampler = ImmutableSampler.RawPtr()->GetVkSampler(); } -- cgit v1.2.3 From e5f36378de4a7258fcc9d6ca7a349df1136b7444 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 12:08:40 -0700 Subject: Renamed USAGE_STATIC to USAGE_IMMUTABLE (API240077) --- Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp | 6 +++--- Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp index 8edb3472..3e61a756 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp @@ -59,8 +59,8 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, { ValidateBufferInitData(BuffDesc, pBuffData); - if (m_Desc.Usage == USAGE_STATIC) - VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for static buffers"); + if (m_Desc.Usage == USAGE_IMMUTABLE) + VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for immutable buffers"); if (m_Desc.Usage == USAGE_DYNAMIC) VERIFY(pBuffData == nullptr || pBuffData->pData == nullptr, "Initial data must be null for dynamic buffers"); @@ -186,7 +186,7 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, VkMemoryPropertyFlags vkMemoryFlags = 0; switch (m_Desc.Usage) { - case USAGE_STATIC: + case USAGE_IMMUTABLE: case USAGE_DEFAULT: case USAGE_DYNAMIC: // Dynamic buffer with SRV or UAV bind flag vkMemoryFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index 313de089..488e4bf6 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -54,13 +54,13 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters, } // clang-format on { - if (m_Desc.Usage == USAGE_STATIC && (pInitData == nullptr || pInitData->pSubResources == nullptr)) - LOG_ERROR_AND_THROW("Static textures must be initialized with data at creation time: pInitData can't be null"); + if (m_Desc.Usage == USAGE_IMMUTABLE && (pInitData == nullptr || pInitData->pSubResources == nullptr)) + LOG_ERROR_AND_THROW("Immutable textures must be initialized with data at creation time: pInitData can't be null"); const auto& FmtAttribs = GetTextureFormatAttribs(m_Desc.Format); const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); - if (m_Desc.Usage == USAGE_STATIC || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC) + if (m_Desc.Usage == USAGE_IMMUTABLE || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC) { VkImageCreateInfo ImageCI = {}; -- cgit v1.2.3 From 13b0b54987db2684e46e337d2e5be5b81366083b Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 13:26:21 -0700 Subject: Improved exception safety of pipeline state object construction --- .../include/PipelineStateVkImpl.hpp | 10 +- .../include/ShaderResourceCacheVk.hpp | 2 +- .../include/ShaderResourceLayoutVk.hpp | 2 +- .../include/ShaderVariableVk.hpp | 24 ++-- .../src/PipelineStateVkImpl.cpp | 123 ++++++++++++++------- .../src/ShaderResourceBindingVkImpl.cpp | 3 +- .../GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 29 ++--- 7 files changed, 116 insertions(+), 77 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 96b34008..d4f2fc36 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -129,13 +129,15 @@ private: using TShaderStages = ShaderResourceLayoutVk::TShaderStages; template - LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo, - std::vector& vkShaderStages, - std::vector& ShaderModules); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& vkShaderStages, + std::vector& ShaderModules); void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); + void Destruct(); + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { VERIFY_EXPR(ShaderInd < GetNumShaderStages()); @@ -148,7 +150,7 @@ private: return m_StaticResCaches[ShaderInd]; } - ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const + const ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const { VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_StaticVarsMgrs[ShaderInd]; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp index a5278cb7..7d77ff48 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp @@ -75,7 +75,7 @@ public: }; // clang-format off - ShaderResourceCacheVk(DbgCacheContentType dbgContentType) + ShaderResourceCacheVk(DbgCacheContentType dbgContentType) noexcept #ifdef DILIGENT_DEBUG : m_DbgContentType{dbgContentType} #endif diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 0013fe23..9452a390 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -128,7 +128,7 @@ public: }; using TShaderStages = std::vector; - ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : + ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) noexcept : m_LogicalDevice{LogicalDevice} { } diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp index 9039e04e..27689c1e 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp @@ -73,21 +73,25 @@ class ShaderVariableVkImpl; class ShaderVariableManagerVk { public: - ShaderVariableManagerVk(IObject& Owner, - const ShaderResourceLayoutVk& SrcLayout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache); + ShaderVariableManagerVk(IObject& Owner, + ShaderResourceCacheVk& ResourceCache) noexcept : + m_Owner{Owner}, + m_ResourceCache{ResourceCache} + {} + + void Initialize(const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes); ~ShaderVariableManagerVk(); void DestroyVariables(IMemoryAllocator& Allocator); - ShaderVariableVkImpl* GetVariable(const Char* Name); - ShaderVariableVkImpl* GetVariable(Uint32 Index); + ShaderVariableVkImpl* GetVariable(const Char* Name) const; + ShaderVariableVkImpl* GetVariable(Uint32 Index) const; - void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) const; static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, @@ -115,7 +119,7 @@ private: Uint32 m_NumVariables = 0; #ifdef DILIGENT_DEBUG - IMemoryAllocator& m_DbgAllocator; + IMemoryAllocator* m_pDbgAllocator = nullptr; #endif }; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 6cbe5da9..83512870 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -413,15 +413,12 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre const auto ShaderType = StageInfo.Type; const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); - new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); - auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; - auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources}; - pStaticResLayout->InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); + auto& StaticResLayout = m_ShaderResourceLayouts[GetNumShaderStages() + s]; + StaticResLayout.InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]); - new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache}; + m_StaticVarsMgrs[s].Initialize(StaticResLayout, GetRawAllocator(), nullptr, 0); } ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(), m_Desc.ResourceLayout, m_PipelineLayout, @@ -464,37 +461,52 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre } template -LinearAllocator PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, - std::vector& vkShaderStages, - std::vector& ShaderModules) +void PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& vkShaderStages, + std::vector& ShaderModules) { m_ResourceLayoutIndex.fill(-1); TShaderStages ShaderStages; ExtractShaders(CreateInfo, ShaderStages); - // Memory must be released if an exception is thrown. LinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddSpace(GetNumShaderStages() * 2); - MemPool.AddSpace(GetNumShaderStages()); - MemPool.AddSpace(GetNumShaderStages()); + const auto NumShaderStages = GetNumShaderStages(); + VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); + + MemPool.AddSpace(NumShaderStages); + MemPool.AddSpace(NumShaderStages * 2); + MemPool.AddSpace(NumShaderStages); ReserveSpaceForPipelineDesc(CreateInfo, MemPool); MemPool.Reserve(); - m_ShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); - m_StaticResCaches = MemPool.Allocate(GetNumShaderStages()); - m_StaticVarsMgrs = MemPool.Allocate(GetNumShaderStages()); + const auto& LogicalDevice = GetDevice()->GetLogicalDevice(); + + m_StaticResCaches = MemPool.ConstructArray(NumShaderStages, ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources); + + // The memory is now owned by PipelineStateVkImpl and will be freed by Destruct(). + auto* Ptr = MemPool.ReleaseOwnership(); + VERIFY_EXPR(Ptr == m_StaticResCaches); + (void)Ptr; + + m_ShaderResourceLayouts = MemPool.ConstructArray(NumShaderStages * 2, LogicalDevice); + + m_StaticVarsMgrs = MemPool.Allocate(NumShaderStages); + for (Uint32 s = 0; s < NumShaderStages; ++s) + new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, m_StaticResCaches[s]}; InitializePipelineDesc(CreateInfo, MemPool); + + // It is important to construct all objects before initializing them because if an exception is thrown, + // destructors will be called for all objects + InitResourceLayouts(CreateInfo, ShaderStages); // Create shader modules and initialize shader stages InitPipelineShaderStages(GetDevice()->GetLogicalDevice(), ShaderStages, ShaderModules, vkShaderStages); - - return MemPool; } PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, @@ -503,15 +515,20 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { - std::vector vkShaderStages; - std::vector ShaderModules; - - auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + try + { + std::vector vkShaderStages; + std::vector ShaderModules; - CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); + InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); - void* Ptr = MemPool.Release(); - VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); + CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); + } + catch (...) + { + Destruct(); + throw; + } } @@ -521,39 +538,59 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* p TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { - std::vector vkShaderStages; - std::vector ShaderModules; - - auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); + try + { + std::vector vkShaderStages; + std::vector ShaderModules; - CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); + InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules); - void* Ptr = MemPool.Release(); - VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); + CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); + } + catch (...) + { + Destruct(); + throw; + } } PipelineStateVkImpl::~PipelineStateVkImpl() +{ + Destruct(); +} + +void PipelineStateVkImpl::Destruct() { m_pDevice->SafeReleaseDeviceObject(std::move(m_Pipeline), m_Desc.CommandQueueMask); m_PipelineLayout.Release(m_pDevice, m_Desc.CommandQueueMask); auto& RawAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < GetNumShaderStages() * 2; ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { - m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); + if (m_StaticVarsMgrs != nullptr) + { + m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); + m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); + } + + if (m_ShaderResourceLayouts != nullptr) + { + m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); + m_ShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutVk(); + } + + if (m_StaticResCaches != nullptr) + { + m_StaticResCaches[s].~ShaderResourceCacheVk(); + } } - for (Uint32 s = 0; s < GetNumShaderStages(); ++s) + // All internal objects are allocted in contiguous chunks of memory. + if (void* pRawMem = m_StaticResCaches) { - m_StaticResCaches[s].~ShaderResourceCacheVk(); - m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); - m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); + RawAllocator.Free(pRawMem); } - // m_ShaderResourceLayouts, m_StaticResCaches and m_StaticVarsMgrs are allocted in - // contiguous chunks of memory. - void* pRawMem = m_ShaderResourceLayouts; - RawAllocator.Free(pRawMem); } IMPLEMENT_QUERY_INTERFACE(PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase) @@ -746,7 +783,7 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY if (LayoutInd < 0) return nullptr; - auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); + const auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); return StaticVarMgr.GetVariable(Index); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 91008811..21b216db 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -75,7 +75,8 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR // Initialize vars manager to reference mutable and dynamic variables // Note that the cache has space for all variable types const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; - new (m_pShaderVarMgrs + s) ShaderVariableManagerVk{*this, SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes), m_ShaderResourceCache}; + new (m_pShaderVarMgrs + s) ShaderVariableManagerVk{*this, m_ShaderResourceCache}; + m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes)); } #ifdef DILIGENT_DEBUG m_ShaderResourceCache.DbgVerifyResourceInitialization(); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index 82d26b44..7e06bd69 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -65,20 +65,15 @@ size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayout } // Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes -ShaderVariableManagerVk::ShaderVariableManagerVk(IObject& Owner, - const ShaderResourceLayoutVk& SrcLayout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache) : - // clang-format off - m_Owner {Owner }, - m_ResourceCache{ResourceCache} +void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes) +{ #ifdef DILIGENT_DEBUG - , m_DbgAllocator {Allocator} + m_pDbgAllocator = &Allocator; #endif -// clang-format on -{ + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); VERIFY_EXPR(m_NumVariables == 0); auto MemSize = GetRequiredMemorySize(SrcLayout, AllowedVarTypes, NumAllowedTypes, m_NumVariables); @@ -119,10 +114,10 @@ ShaderVariableManagerVk::~ShaderVariableManagerVk() void ShaderVariableManagerVk::DestroyVariables(IMemoryAllocator& Allocator) { - VERIFY(&m_DbgAllocator == &Allocator, "Incosistent alloctor"); - if (m_pVariables != nullptr) { + VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor"); + for (Uint32 v = 0; v < m_NumVariables; ++v) m_pVariables[v].~ShaderVariableVkImpl(); Allocator.Free(m_pVariables); @@ -130,7 +125,7 @@ void ShaderVariableManagerVk::DestroyVariables(IMemoryAllocator& Allocator) } } -ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name) +ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name) const { ShaderVariableVkImpl* pVar = nullptr; for (Uint32 v = 0; v < m_NumVariables; ++v) @@ -147,7 +142,7 @@ ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name) } -ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(Uint32 Index) +ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(Uint32 Index) const { if (Index >= m_NumVariables) { @@ -178,7 +173,7 @@ Uint32 ShaderVariableManagerVk::GetVariableIndex(const ShaderVariableVkImpl& Var } } -void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) +void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) const { if (!pResourceMapping) { -- cgit v1.2.3 From 0c7e8e2efc95362cbc0998558bb41789a3943037 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 14:06:33 -0700 Subject: Improved exception safety of SRB object creation --- .../include/ShaderResourceBindingVkImpl.hpp | 2 + .../src/ShaderResourceBindingVkImpl.cpp | 88 ++++++++++++++-------- 2 files changed, 60 insertions(+), 30 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp index 026bb9da..00f2c33a 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -76,6 +76,8 @@ public: bool StaticResourcesInitialized() const { return m_bStaticResourcesInitialized; } private: + void Destruct(); + ShaderResourceCacheVk m_ShaderResourceCache; ShaderVariableManagerVk* m_pShaderVarMgrs = nullptr; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 21b216db..3e4a65cf 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -30,6 +30,7 @@ #include "PipelineStateVkImpl.hpp" #include "ShaderVkImpl.hpp" #include "RenderDeviceVkImpl.hpp" +#include "LinearAllocator.hpp" namespace Diligent { @@ -47,52 +48,79 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR m_ShaderResourceCache{ShaderResourceCacheVk::DbgCacheContentType::SRBResources} // clang-format on { - m_ResourceLayoutIndex.fill(-1); + try + { + m_ResourceLayoutIndex.fill(-1); - m_NumShaders = static_cast(pPSO->GetNumShaderStages()); + m_NumShaders = static_cast(pPSO->GetNumShaderStages()); - auto* pRenderDeviceVkImpl = pPSO->GetDevice(); - // This will only allocate memory and initialize descriptor sets in the resource cache - // Resources will be initialized by InitializeResourceMemoryInCache() - auto& ResourceCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); - pPSO->GetPipelineLayout().InitResourceCache(pRenderDeviceVkImpl, m_ShaderResourceCache, ResourceCacheDataAllocator, pPSO->GetDesc().Name); + LinearAllocator MemPool{GetRawAllocator()}; + MemPool.AddSpace(m_NumShaders); + MemPool.Reserve(); + m_pShaderVarMgrs = MemPool.ConstructArray(m_NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache)); - m_pShaderVarMgrs = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", ShaderVariableManagerVk, m_NumShaders); + // The memory is now owned by ShaderResourceBindingVkImpl and will be freed by Destruct(). + auto* Ptr = MemPool.ReleaseOwnership(); + VERIFY_EXPR(Ptr == m_pShaderVarMgrs); + (void)Ptr; - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - auto ShaderInd = GetShaderTypePipelineIndex(pPSO->GetShaderStageType(s), pPSO->GetDesc().PipelineType); + // It is important to construct all objects before initializing them because if an exception is thrown, + // destructors will be called for all objects - m_ResourceLayoutIndex[ShaderInd] = static_cast(s); + auto* pRenderDeviceVkImpl = pPSO->GetDevice(); + // This will only allocate memory and initialize descriptor sets in the resource cache + // Resources will be initialized by InitializeResourceMemoryInCache() + auto& ResourceCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); + pPSO->GetPipelineLayout().InitResourceCache(pRenderDeviceVkImpl, m_ShaderResourceCache, ResourceCacheDataAllocator, pPSO->GetDesc().Name); - auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + auto ShaderInd = GetShaderTypePipelineIndex(pPSO->GetShaderStageType(s), pPSO->GetDesc().PipelineType); - const auto& SrcLayout = pPSO->GetShaderResLayout(s); - // Use source layout to initialize resource memory in the cache - SrcLayout.InitializeResourceMemoryInCache(m_ShaderResourceCache); + m_ResourceLayoutIndex[ShaderInd] = static_cast(s); - // Create shader variable manager in place - // Initialize vars manager to reference mutable and dynamic variables - // Note that the cache has space for all variable types - const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; - new (m_pShaderVarMgrs + s) ShaderVariableManagerVk{*this, m_ShaderResourceCache}; - m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes)); - } + auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + + const auto& SrcLayout = pPSO->GetShaderResLayout(s); + // Use source layout to initialize resource memory in the cache + SrcLayout.InitializeResourceMemoryInCache(m_ShaderResourceCache); + + // Create shader variable manager in place + // Initialize vars manager to reference mutable and dynamic variables + // Note that the cache has space for all variable types + const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes)); + } #ifdef DILIGENT_DEBUG - m_ShaderResourceCache.DbgVerifyResourceInitialization(); + m_ShaderResourceCache.DbgVerifyResourceInitialization(); #endif + } + catch (...) + { + Destruct(); + throw; + } } ShaderResourceBindingVkImpl::~ShaderResourceBindingVkImpl() { - for (Uint32 s = 0; s < m_NumShaders; ++s) + Destruct(); +} + +void ShaderResourceBindingVkImpl::Destruct() +{ + if (m_pShaderVarMgrs != nullptr) { - auto& VarDataAllocator = m_pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); - m_pShaderVarMgrs[s].DestroyVariables(VarDataAllocator); - m_pShaderVarMgrs[s].~ShaderVariableManagerVk(); - } + auto& SRBMemAllocator = m_pPSO->GetSRBMemoryAllocator(); + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); + m_pShaderVarMgrs[s].DestroyVariables(VarDataAllocator); + m_pShaderVarMgrs[s].~ShaderVariableManagerVk(); + } - GetRawAllocator().Free(m_pShaderVarMgrs); + GetRawAllocator().Free(m_pShaderVarMgrs); + } } IMPLEMENT_QUERY_INTERFACE(ShaderResourceBindingVkImpl, IID_ShaderResourceBindingVk, TBase) -- cgit v1.2.3 From b9d1a84943f61d1b48ffb1847cd0b3f7b8c60fb2 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 18:05:02 -0700 Subject: Added ShaderResourceQueries device feature and EngineGLCreateInfo::ForceNonSeparablePrograms parameter (API 240078) --- Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 2 +- Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 81d6753c..cbe1779f 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -389,7 +389,7 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E #if defined(_MSC_VER) && defined(_WIN64) - static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); + static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); #endif DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data(); diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 1441569e..ccfb74ac 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -213,6 +213,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* // The following features are always enabled Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED; + Features.ShaderResourceQueries = DEVICE_FEATURE_STATE_ENABLED; Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED; Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_ENABLED; Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED; @@ -222,7 +223,7 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED; #if defined(_MSC_VER) && defined(_WIN64) - static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary)."); + static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here (if necessary)."); #endif const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits; -- cgit v1.2.3