From c07ee39e4241251ef4583ecbc22a369935ad8b9a Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 25 Feb 2019 20:41:16 -0800 Subject: Cosmetic changes --- Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h | 14 +++++++------- Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h | 6 +++--- Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h index abedce7d..f7245d0a 100644 --- a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h @@ -44,15 +44,15 @@ class BufferViewVkImpl final : public BufferViewBase; - BufferViewVkImpl( IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - const BufferViewDesc& ViewDesc, - class IBuffer* pBuffer, - VulkanUtilities::BufferViewWrapper&& BuffView, - bool bIsDefaultView); + BufferViewVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer* pBuffer, + VulkanUtilities::BufferViewWrapper&& BuffView, + bool bIsDefaultView); ~BufferViewVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; virtual VkBufferView GetVkBufferView()const override final{return m_BuffView;} diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h index f3d1784b..c3afd4ee 100644 --- a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h @@ -63,7 +63,7 @@ public: VkBuffer vkBuffer); ~BufferVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; #ifdef DEVELOPMENT void DvpVerifyDynamicAllocation(DeviceContextVkImpl* pCtx)const; @@ -104,14 +104,14 @@ public: private: friend class DeviceContextVkImpl; - virtual void CreateViewInternal( const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView )override; + virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView)override; VulkanUtilities::BufferViewWrapper CreateView(struct BufferViewDesc &ViewDesc); Uint32 m_DynamicOffsetAlignment = 0; std::vector > m_DynamicAllocations; - VulkanUtilities::BufferWrapper m_VulkanBuffer; + VulkanUtilities::BufferWrapper m_VulkanBuffer; VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; }; diff --git a/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h index e257506e..3f986515 100644 --- a/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h @@ -45,7 +45,7 @@ public: SamplerVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const SamplerDesc& SamplerDesc); ~SamplerVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; virtual VkSampler GetVkSampler()const override final{return m_VkSampler;} -- cgit v1.2.3 From ccce7d6fb134a653d7f9b6fd4089f1ba99777bb7 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 25 Feb 2019 21:16:05 -0800 Subject: Updated SaderVkImpl: removed static resources --- .../GraphicsEngineVulkan/include/ShaderVkImpl.h | 40 ++++++---------------- Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 23 +++---------- 2 files changed, 14 insertions(+), 49 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index c21e10a2..c646820c 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -29,9 +29,7 @@ #include "RenderDeviceVk.h" #include "ShaderVk.h" #include "ShaderBase.h" -#include "ShaderResourceLayoutVk.h" #include "SPIRVShaderResources.h" -#include "ShaderVariableVk.h" #include "RenderDeviceVkImpl.h" namespace Diligent @@ -46,55 +44,37 @@ class ShaderVkImpl final : public ShaderBase public: using TShaderBase = ShaderBase; - ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreationAttribs &CreationAttribs); + ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreateInfo &CreationAttribs); ~ShaderVkImpl(); - //virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderVk, TShaderBase); - virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override + virtual Uint32 GetResourceCount()const { - m_StaticVarsMgr.BindResources(pResourceMapping, Flags); + UNSUPPORTED("Not yet implemented"); + return 0; } - virtual IShaderVariable* GetShaderVariable(const Char* Name)override + virtual const ShaderResourceDesc* GetResources()const { - return m_StaticVarsMgr.GetVariable(Name); - } - - virtual Uint32 GetVariableCount() const override final - { - return m_StaticVarsMgr.GetVariableCount(); - } - - virtual IShaderVariable* GetShaderVariable(Uint32 Index)override final - { - return m_StaticVarsMgr.GetVariable(Index); + UNSUPPORTED("Not yet implemented"); + return nullptr; } virtual const std::vector& GetSPIRV()const override final { return m_SPIRV; } - + const std::shared_ptr& GetShaderResources()const{return m_pShaderResources;} - const ShaderResourceLayoutVk& GetStaticResLayout()const { return m_StaticResLayout; } - const ShaderResourceCacheVk& GetStaticResCache() const { return m_StaticResCache; } - const char* GetEntryPoint() const { return m_EntryPoint.c_str(); } -#ifdef DEVELOPMENT - bool DvpVerifyStaticResourceBindings()const; -#endif - private: void MapHLSLVertexShaderInputs(); - // ShaderResources class instance must be referenced through the shared pointer, because + // SPIRVShaderResources class instance must be referenced through the shared pointer, because // it is referenced by ShaderResourceLayoutVk class instances std::shared_ptr m_pShaderResources; - ShaderResourceLayoutVk m_StaticResLayout; - ShaderResourceCacheVk m_StaticResCache; - ShaderVariableManagerVk m_StaticVarsMgr; std::string m_EntryPoint; std::vector m_SPIRV; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index fef2d052..3cf4c3f0 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -37,13 +37,10 @@ namespace Diligent { -ShaderVkImpl::ShaderVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pRenderDeviceVk, - const ShaderCreationAttribs& CreationAttribs) : - TShaderBase (pRefCounters, pRenderDeviceVk, CreationAttribs.Desc), - m_StaticResLayout (*this, pRenderDeviceVk->GetLogicalDevice()), - m_StaticResCache (ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources), - m_StaticVarsMgr (*this) +ShaderVkImpl::ShaderVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRenderDeviceVk, + const ShaderCreateInfo& CreationAttribs) : + TShaderBase(pRefCounters, pRenderDeviceVk, CreationAttribs.Desc) { if (CreationAttribs.Source != nullptr || CreationAttribs.FilePath != nullptr) { @@ -95,10 +92,6 @@ ShaderVkImpl::ShaderVkImpl(IReferenceCounters* pRefCounters, { MapHLSLVertexShaderInputs(); } - - m_StaticResLayout.InitializeStaticResourceLayout(m_pShaderResources, GetRawAllocator(), m_StaticResCache); - // m_StaticResLayout only contains static resources, so reference all of them - m_StaticVarsMgr.Initialize(m_StaticResLayout, GetRawAllocator(), nullptr, 0, m_StaticResCache); } void ShaderVkImpl::MapHLSLVertexShaderInputs() @@ -134,14 +127,6 @@ void ShaderVkImpl::MapHLSLVertexShaderInputs() ShaderVkImpl::~ShaderVkImpl() { - m_StaticVarsMgr.Destroy(GetRawAllocator()); } -#ifdef DEVELOPMENT -bool ShaderVkImpl::DvpVerifyStaticResourceBindings()const -{ - return m_StaticResLayout.dvpVerifyBindings(m_StaticResCache); -} -#endif - } -- cgit v1.2.3 From c03fae535f3e5080906c43690e800ae34572278c Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Tue, 26 Feb 2019 22:49:28 -0800 Subject: Updating some files to match the new API --- Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index fc9af5a8..793aea80 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -104,16 +104,16 @@ namespace Diligent std::array, 4> GenerateMipsVkHelper::CreatePSOs(TEXTURE_FORMAT Fmt) { - ShaderCreationAttribs CSCreateAttribs; + ShaderCreateInfo CSCreateAttribs; std::array, 4> PSOs; CSCreateAttribs.Source = g_GenerateMipsCSSource; CSCreateAttribs.EntryPoint = "main"; CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; CSCreateAttribs.Desc.ShaderType = SHADER_TYPE_COMPUTE; - CSCreateAttribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_DYNAMIC; + CSCreateAttribs.Desc.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; - ShaderVariableDesc VarDesc{"CB", SHADER_VARIABLE_TYPE_STATIC}; + ShaderResourceVariableDesc VarDesc{"CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; CSCreateAttribs.Desc.VariableDesc = &VarDesc; CSCreateAttribs.Desc.NumVariables = 1; -- cgit v1.2.3 From 786c4f793220a7ca259f8ed9f5854a2d07941f99 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 08:55:49 -0800 Subject: Updated ShaderResourceLayoutVk --- .../include/ShaderResourceLayoutVk.h | 141 +++++--- .../src/ShaderResourceLayoutVk.cpp | 377 +++++++++++++++------ 2 files changed, 354 insertions(+), 164 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index a4970680..f49bc342 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -30,14 +30,14 @@ // // m_ResourceBuffer // | -// || VkResource[0] ... VkResource[s-1] | VkResource[s] ... VkResource[s+m-1] | VkResource[s+m] ... VkResource[s+m+d-1] || -// || | | || -// || SHADER_VARIABLE_TYPE_STATIC | SHADER_VARIABLE_TYPE_MUTABLE | SHADER_VARIABLE_TYPE_DYNAMIC || -// || | | || +// || VkResource[0] ... VkResource[s-1] | VkResource[s] ... VkResource[s+m-1] | VkResource[s+m] ... VkResource[s+m+d-1] || || +// || | | || || +// || VARIABLE_TYPE_STATIC | VARIABLE_TYPE_MUTABLE | VARIABLE_TYPE_DYNAMIC || Immutable Samplers || +// || | | || || // -// s == m_NumResources[SHADER_VARIABLE_TYPE_STATIC] -// m == m_NumResources[SHADER_VARIABLE_TYPE_MUTABLE] -// d == m_NumResources[SHADER_VARIABLE_TYPE_DYNAMIC] +// s == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] +// m == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] +// d == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] // // // @@ -86,17 +86,17 @@ // // // -// ShaderResourceLayoutVk is used as follows: -// * Every shader object (ShaderVkImpl) contains shader resource layout that facilitates management of static shader resources -// ** The resource layout defines artificial layout where resource binding matches the -// resource type (SPIRVShaderResourceAttribs::ResourceType) -// * Every pipeline state object (PipelineStateVkImpl) maintains shader resource layout for every active shader stage -// ** All variable types are preserved -// ** Bindings, descriptor sets and offsets are assigned during the initialization +// Every pipeline state object (PipelineStateVkImpl) keeps the following layouts: +// * One layout object per shader stage to facilitate management of static shader resources +// - Uses artificial layout where resource binding matches the resource type (SPIRVShaderResourceAttribs::ResourceType) +// * One layout object per shader stage used by SRBs to manage all resource types: +// - All variable types are preserved +// - Bindings, descriptor sets and offsets are assigned during the initialization #include #include +#include "PipelineState.h" #include "ShaderBase.h" #include "HashUtils.h" #include "ShaderResourceCacheVk.h" @@ -107,7 +107,7 @@ namespace Diligent { /// Diligent::ShaderResourceLayoutVk class -// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) +// sizeof(ShaderResourceLayoutVk)==64 (MS compiler, x64) - TODO: verify class ShaderResourceLayoutVk { public: @@ -121,53 +121,68 @@ public: ~ShaderResourceLayoutVk(); - // This method is called by ShaderVkImpl class instance to initialize static - // shader resource layout and cache + // 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 PipelineLayoutDesc& LayoutDesc, ShaderResourceCacheVk& StaticResourceCache); // This method is called by PipelineStateVkImpl class instance to initialize resource - // layouts for all shader stages in a pipeline. - static void Initialize(Uint32 NumShaders, + // layouts for all shader stages in the pipeline. + static void Initialize(IRenderDevice* pRenderDevice, + Uint32 NumShaders, ShaderResourceLayoutVk Layouts[], std::shared_ptr pShaderResources[], IMemoryAllocator& LayoutDataAllocator, + const PipelineLayoutDesc& LayoutDesc, std::vector SPIRVs[], class PipelineLayout& PipelineLayout); - // sizeof(VkResource) == 24 (x64) + // sizeof(VkResource) == 24 (x64) - TODO: Verify struct VkResource { - VkResource(const VkResource&) = delete; - VkResource(VkResource&&) = delete; - VkResource& operator = (const VkResource&) = delete; - VkResource& operator = (VkResource&&) = delete; + VkResource (const VkResource&) = delete; + VkResource ( VkResource&&) = delete; + VkResource& operator = (const VkResource&) = delete; + VkResource& operator = ( VkResource&&) = delete; + + static constexpr const Uint32 CacheOffsetBits = 21; + static constexpr const Uint32 SamplerIndBits = 8; + static constexpr const Uint32 VariableTypeBits = 2; + static constexpr const Uint32 ImmutableSamplerFlagBits = 1; + static_assert(CacheOffsetBits + SamplerIndBits + VariableTypeBits + ImmutableSamplerFlagBits == 32, "Elements are expected to be packed into 32 bits"); + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES <= (1<(_Binding)), - DescriptorSet (static_cast(_DescriptorSet)), - CacheOffset (_CacheOffset), - SamplerInd (_SamplerInd), - SpirvAttribs (_SpirvAttribs), - ParentResLayout (_ParentLayout) + Uint32 _SamplerInd, + bool _ImmutableSamplerAssigned = false)noexcept : + Binding (static_cast(_Binding)), + DescriptorSet (static_cast(_DescriptorSet)), + CacheOffset (_CacheOffset), + SamplerInd (_SamplerInd), + VariableType (_VariableType), + ImmutableSamplerAssigned (_ImmutableSamplerAssigned ? 1 : 0), + 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) ); @@ -188,6 +203,17 @@ public: const VkDescriptorBufferInfo* pBufferInfo, const VkBufferView* pTexelBufferView)const; + bool IsImmutableSamplerAssigned() const + { + VERIFY_EXPR(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); + return ImmutableSamplerAssigned != 0; + } + + SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const + { + return static_cast(VariableType); + } + private: void CacheUniformBuffer(IDeviceObject* pBuffer, ShaderResourceCacheVk::Resource& DstRes, @@ -233,7 +259,7 @@ public: bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache)const; #endif - Uint32 GetResourceCount(SHADER_VARIABLE_TYPE VarType)const + Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType)const { return m_NumResources[VarType]; } @@ -247,7 +273,7 @@ public: const Char* GetShaderName()const; - const VkResource& GetResource(SHADER_VARIABLE_TYPE VarType, Uint32 r)const + const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r)const { VERIFY_EXPR( r < m_NumResources[VarType] ); auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); @@ -257,16 +283,16 @@ public: bool IsUsingSeparateSamplers()const {return !m_pResources->IsUsingCombinedSamplers();} private: - Uint32 GetResourceOffset(SHADER_VARIABLE_TYPE VarType, Uint32 r)const + Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r)const { VERIFY_EXPR( r < m_NumResources[VarType] ); - static_assert(SHADER_VARIABLE_TYPE_STATIC == 0, "SHADER_VARIABLE_TYPE_STATIC == 0 expected"); - r += (VarType > SHADER_VARIABLE_TYPE_STATIC) ? m_NumResources[SHADER_VARIABLE_TYPE_STATIC] : 0; - static_assert(SHADER_VARIABLE_TYPE_MUTABLE == 1, "SHADER_VARIABLE_TYPE_MUTABLE == 1 expected"); - r += (VarType > SHADER_VARIABLE_TYPE_MUTABLE) ? m_NumResources[SHADER_VARIABLE_TYPE_MUTABLE] : 0; + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0, "SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0 expected"); + r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_STATIC) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] : 0; + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1, "SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1 expected"); + r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] : 0; return r; } - VkResource& GetResource(SHADER_VARIABLE_TYPE VarType, Uint32 r) + VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) { VERIFY_EXPR( r < m_NumResources[VarType] ); auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); @@ -282,16 +308,26 @@ private: Uint32 GetTotalResourceCount()const { - return m_NumResources[SHADER_VARIABLE_TYPE_NUM_TYPES]; + return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; } void AllocateMemory(std::shared_ptr pSrcResources, IMemoryAllocator& Allocator, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, + const PipelineLayoutDesc& LayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes); - Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, Uint32 CurrResourceCount)const; + Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType)const; + using ImmutableSamplerPtrType = RefCntAutoPtr; + ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n)noexcept + { + VERIFY(n < m_NumImmutableSamplers, "Immutable sampler index (", n, ") is out of range. Total immutable sampler count: ", m_NumImmutableSamplers); + auto* ResourceMemoryEnd = reinterpret_cast(m_ResourceBuffer.get()) + GetTotalResourceCount(); + return reinterpret_cast(ResourceMemoryEnd)[n]; + } IObject& m_Owner; const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; @@ -301,7 +337,8 @@ private: // there may be multiple objects referencing the same set of resources std::shared_ptr m_pResources; - std::array m_NumResources = {}; + std::array m_NumResources = {}; + Uint32 m_NumImmutableSamplers = 0; }; } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 8915d67f..9151fc9a 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -32,11 +32,64 @@ #include "SamplerVkImpl.h" #include "ShaderVkImpl.h" #include "PipelineLayout.h" +#include "ShaderResourceVariableBase.h" +#include "StringTools.h" #include "PipelineStateVkImpl.h" namespace Diligent { +static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, + const PipelineLayoutDesc& LayoutDesc, + const SPIRVShaderResourceAttribs& Attribs, + const char* SamplerSuffix) +{ + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) + { + SamplerSuffix = nullptr; + } + else if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) + { + // Use SamplerSuffix. If HLSL-style combined images samplers are not used, + // SamplerSuffix will be null and we will be looking for the sampler itself. + } + else + { + return -1; + } + + for (Uint32 s=0; s < LayoutDesc.NumStaticSamplers; ++s) + { + const auto& StSam = LayoutDesc.StaticSamplers[s]; + if ( ((StSam.ShaderStages & ShaderType) != 0) && StreqSuff(Attribs.Name, StSam.SamplerOrTextureName, SamplerSuffix) ) + return s; + } + + return -1; +} + +static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE ShaderType, + const SPIRVShaderResourceAttribs& Attribs, + const PipelineLayoutDesc& LayoutDesc, + const char* CombinedSamplerSuffix) +{ + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) + { + // Use texture or sampler name to derive separate sampler type + // When HLSL-style combined image samplers are not used, CombinedSamplerSuffix is null + return GetShaderVariableType(ShaderType, LayoutDesc.DefaultVariableType, LayoutDesc.Variables, LayoutDesc.NumVariables, + [&](const char* VarName) + { + return StreqSuff(Attribs.Name, VarName, CombinedSamplerSuffix); + }); + } + else + { + return GetShaderVariableType(ShaderType, Attribs.Name, LayoutDesc); + } +} + + ShaderResourceLayoutVk::ShaderResourceLayoutVk(IObject& Owner, const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : m_Owner(Owner), @@ -49,11 +102,15 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); for (Uint32 r=0; r < GetTotalResourceCount(); ++r) Resources[r].~VkResource(); + + for(Uint32 s=0; s < m_NumImmutableSamplers; ++s) + GetImmutableSampler(s).~ImmutableSamplerPtrType(); } void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr pSrcResources, IMemoryAllocator& Allocator, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, + const PipelineLayoutDesc& LayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes) { VERIFY(!m_ResourceBuffer, "Memory has already been initialized"); @@ -62,50 +119,77 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrGetShaderType(); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); // Count number of resources to allocate all needed memory m_pResources->ProcessResources( - AllowedVarTypes, NumAllowedTypes, - [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) { - VERIFY_EXPR(IsAllowedType(ResAttribs.VarType, AllowedTypeBits)); - VERIFY( Uint32{m_NumResources[ResAttribs.VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds max representable value"); - ++m_NumResources[ResAttribs.VarType]; + auto VarType = GetShaderVariableType(ShaderType, ResAttribs, LayoutDesc, CombinedSamplerSuffix); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + VERIFY( Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds max representable value"); + ++m_NumResources[VarType]; + } } ); Uint32 TotalResources = 0; - for (SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { TotalResources += m_NumResources[VarType]; } VERIFY(TotalResources <= Uint32{std::numeric_limits::max()}, "Total number of resources exceeds Uint16 max representable value" ); - m_NumResources[SHADER_VARIABLE_TYPE_NUM_TYPES] = static_cast(TotalResources); + m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES] = static_cast(TotalResources); - size_t MemSize = TotalResources * sizeof(VkResource); + m_NumImmutableSamplers = 0; + for(Uint32 s=0; s < LayoutDesc.NumStaticSamplers; ++s) + { + const auto& StSamDesc = LayoutDesc.StaticSamplers[s]; + if ((StSamDesc.ShaderStages & ShaderType) != 0) + ++m_NumImmutableSamplers; + } + + size_t MemSize = TotalResources * sizeof(VkResource) + m_NumImmutableSamplers * sizeof(ImmutableSamplerPtrType); + static_assert( (sizeof(VkResource) % sizeof(void*)) == 0, "sizeof(VkResource) must be multiple of sizeof(void*)" ); if (MemSize == 0) return; auto* pRawMem = ALLOCATE(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); m_ResourceBuffer = std::unique_ptr >(pRawMem, Allocator); + for(Uint32 s=0; s < m_NumImmutableSamplers; ++s) + { + // We need to initialize immutable samplers + new(&GetImmutableSampler(s)) ImmutableSamplerPtrType; + } } + void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr pSrcResources, IMemoryAllocator& LayoutDataAllocator, + const PipelineLayoutDesc& LayoutDesc, ShaderResourceCacheVk& StaticResourceCache) { - auto AllowedVarType = SHADER_VARIABLE_TYPE_STATIC; - AllocateMemory(std::move(pSrcResources), LayoutDataAllocator, &AllowedVarType, 1); + auto AllowedVarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + AllocateMemory(std::move(pSrcResources), LayoutDataAllocator, LayoutDesc, &AllowedVarType, 1); - std::array CurrResInd = {}; + std::array CurrResInd = {}; Uint32 StaticResCacheSize = 0; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(&AllowedVarType, 1); + const auto ShaderType = pSrcResources->GetShaderType(); + const auto* CombinedSamplerSuffix = pSrcResources->GetCombinedSamplerSuffix(); + m_pResources->ProcessResources( - &AllowedVarType, 1, [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) { + auto VarType = GetShaderVariableType(ShaderType, Attribs, LayoutDesc, CombinedSamplerSuffix); + if (!IsAllowedType(VarType, AllowedTypeBits)) + return; + + //TODO: how to handle static samplers? + Uint32 Binding = Attribs.Type; Uint32 DescriptorSet = 0; Uint32 CacheOffset = StaticResCacheSize; @@ -115,15 +199,15 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr(VarType + 1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) { VERIFY(CurrResInd[VarType] == m_NumResources[VarType], "Not all resources are initialized, which will cause a crash when dtor is called"); } @@ -133,25 +217,89 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr pShaderResources[], IMemoryAllocator& LayoutDataAllocator, + const PipelineLayoutDesc& LayoutDesc, std::vector SPIRVs[], class PipelineLayout& PipelineLayout) { - SHADER_VARIABLE_TYPE* AllowedVarTypes = nullptr; - Uint32 NumAllowedTypes = 0; - Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); +#ifdef DEVELOPMENT + for (Uint32 v = 0; v < LayoutDesc.NumVariables; ++v) + { + bool VariableFound = false; + const auto& VarDesc = LayoutDesc.Variables[v]; + for(Uint32 s=0; s < NumShaders && !VariableFound; ++s) + { + const auto& Resources = *pShaderResources[s]; + if ( (VarDesc.ShaderStages & Resources.GetShaderType()) != 0 ) + { + for (Uint32 res = 0; res < Resources.GetTotalResources() && !VariableFound; ++res) + { + const auto& ResAttribs = Resources.GetResource(res); + VariableFound = (strcmp(ResAttribs.Name, VarDesc.Name) == 0); + } + } + } + if (!VariableFound) + { + LOG_WARNING_MESSAGE("Variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), " is not found in any of shader stages"); + } + } + + for (Uint32 sam = 0; sam < LayoutDesc.NumStaticSamplers; ++sam) + { + const auto& StSamDesc = LayoutDesc.StaticSamplers[sam]; + bool SamplerFound = false; + for(Uint32 s=0; s < NumShaders && !SamplerFound; ++s) + { + const auto& Resources = *pShaderResources[s]; + // 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) + for (Uint32 i = 0; i < Resources.GetNumSmpldImgs() && !SamplerFound; ++i) + { + const auto& SmplImg = Resources.GetSmpldImg(i); + SamplerFound = (strcmp(SmplImg.Name, StSamDesc.SamplerOrTextureName) == 0); + } + + if (!SamplerFound) + { + // Check if static sampler is assigned to a separate sampler or + // separate image depending on whether HLSL-style combined samplers + // are used + const auto* CombinedSamplerSuffix = Resources.GetCombinedSamplerSuffix(); + for (Uint32 i = 0; i < Resources.GetNumSepSmplrs(); ++i) + { + const auto& SepSmpl = Resources.GetSepSmplr(i); + SamplerFound = StreqSuff(SepSmpl.Name, StSamDesc.SamplerOrTextureName, CombinedSamplerSuffix); + if (SamplerFound) + break; + } + } + } + + if (!SamplerFound) + { + LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, "' is not found in any of shader stages"); + } + } +#endif + + + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; + const Uint32 NumAllowedTypes = 0; + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); for (Uint32 s=0; s < NumShaders; ++s) { - Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, AllowedVarTypes, NumAllowedTypes); + Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, LayoutDesc, AllowedVarTypes, NumAllowedTypes); } VERIFY_EXPR(NumShaders <= MaxShadersInPipeline); - std::array, MaxShadersInPipeline> CurrResInd = {}; + std::array, MaxShadersInPipeline> CurrResInd = {}; + std::array CurrImmutableSamplerInd = {}; #ifdef _DEBUG std::unordered_map> dbgBindings_CacheOffsets; #endif @@ -159,17 +307,35 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, auto AddResource = [&](Uint32 ShaderInd, ShaderResourceLayoutVk& ResLayout, const SPIRVShaderResources& Resources, - const SPIRVShaderResourceAttribs& Attribs, - Uint32 SamplerInd = VkResource::InvalidSamplerInd) + const SPIRVShaderResourceAttribs& Attribs) { Uint32 Binding = 0; Uint32 DescriptorSet = 0; Uint32 CacheOffset = 0; + const auto ShaderType = Resources.GetShaderType(); + const SHADER_RESOURCE_VARIABLE_TYPE VarType = GetShaderVariableType(ShaderType, Attribs, LayoutDesc, Resources.GetCombinedSamplerSuffix()); + if (!IsAllowedType(VarType, AllowedTypeBits)) + return; - auto* pImmutableSampler = Resources.GetImmutableSampler(Attribs); + 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 = ResLayout.FindAssignedSampler(Attribs, CurrResInd[ShaderInd][VarType], VarType); + } + + Int32 SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, LayoutDesc, Attribs, Resources.GetCombinedSamplerSuffix()); VkSampler vkImmutableSampler = VK_NULL_HANDLE; - if (pImmutableSampler != nullptr) - vkImmutableSampler = ValidatedCast(pImmutableSampler)->GetVkSampler(); + if (SrcImmutableSamplerInd >= 0) + { + auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++); + VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized!"); + const auto& ImmutableSamplerDesc = LayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; + pRenderDevice->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); + vkImmutableSampler = ImmutableSampler.RawPtr()->GetVkSampler(); + } auto& ShaderSPIRV = SPIRVs[ShaderInd]; PipelineLayout.AllocateResourceSlot(Attribs, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); @@ -187,8 +353,8 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, dbgBindings_CacheOffsets[DescriptorSet] = std::make_pair(Binding, CacheOffset); #endif - auto& ResInd = CurrResInd[ShaderInd][Attribs.VarType]; - ::new (&ResLayout.GetResource(Attribs.VarType, ResInd++)) VkResource(ResLayout, Attribs, Binding, DescriptorSet, CacheOffset, SamplerInd); + auto& ResInd = CurrResInd[ShaderInd][VarType]; + ::new (&ResLayout.GetResource(VarType, ResInd++)) VkResource(ResLayout, Attribs, VarType, Binding, DescriptorSet, CacheOffset, SamplerInd, vkImmutableSampler != VK_NULL_HANDLE ? 1 : 0); }; // First process uniform buffers for all shader stages to make sure all UBs go first in every descriptor set @@ -199,7 +365,8 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n) { const auto& UB = Resources.GetUB(n); - if (IsAllowedType(UB.VarType, AllowedTypeBits)) + auto VarType = GetShaderVariableType(Resources.GetShaderType(), UB.Name, LayoutDesc); + if (IsAllowedType(VarType, AllowedTypeBits)) { AddResource(s, Layout, Resources, UB); } @@ -214,7 +381,8 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n) { const auto& SB = Resources.GetSB(n); - if (IsAllowedType(SB.VarType, AllowedTypeBits)) + auto VarType = GetShaderVariableType(Resources.GetShaderType(), SB.Name, LayoutDesc); + if (IsAllowedType(VarType, AllowedTypeBits)) { AddResource(s, Layout, Resources, SB); } @@ -227,50 +395,40 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, auto& Layout = Layouts[s]; const auto& Resources = *Layout.m_pResources; Resources.ProcessResources( - AllowedVarTypes, NumAllowedTypes, - [&](const SPIRVShaderResourceAttribs& UB, Uint32) { VERIFY_EXPR(UB.Type == SPIRVShaderResourceAttribs::ResourceType::UniformBuffer); - VERIFY_EXPR(IsAllowedType(UB.VarType, AllowedTypeBits)); // Skip }, [&](const SPIRVShaderResourceAttribs& SB, Uint32) { VERIFY_EXPR(SB.Type == SPIRVShaderResourceAttribs::ResourceType::StorageBuffer); - VERIFY_EXPR(IsAllowedType(SB.VarType, AllowedTypeBits)); // Skip }, [&](const SPIRVShaderResourceAttribs& Img, Uint32) { VERIFY_EXPR(Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageImage || Img.Type == SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer); - VERIFY_EXPR(IsAllowedType(Img.VarType, AllowedTypeBits)); AddResource(s, Layout, Resources, Img); }, [&](const SPIRVShaderResourceAttribs& SmplImg, Uint32) { VERIFY_EXPR(SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || SmplImg.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer); - VERIFY_EXPR(IsAllowedType(SmplImg.VarType, AllowedTypeBits)); AddResource(s, Layout, Resources, SmplImg); }, [&](const SPIRVShaderResourceAttribs& AC, Uint32) { VERIFY_EXPR(AC.Type == SPIRVShaderResourceAttribs::ResourceType::AtomicCounter); - VERIFY_EXPR(IsAllowedType(AC.VarType, AllowedTypeBits)); AddResource(s, Layout, Resources, AC); }, [&](const SPIRVShaderResourceAttribs& SepSmpl, Uint32) { VERIFY_EXPR(SepSmpl.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler); - VERIFY_EXPR(IsAllowedType(SepSmpl.VarType, AllowedTypeBits)); AddResource(s, Layout, Resources, SepSmpl); }, [&](const SPIRVShaderResourceAttribs& SepImg, Uint32) { VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); - VERIFY_EXPR(IsAllowedType(SepImg.VarType, AllowedTypeBits)); - Uint32 SamplerInd = Layout.FindAssignedSampler(SepImg, CurrResInd[s][SepImg.VarType]); - AddResource(s, Layout, Resources, SepImg, SamplerInd); + AddResource(s, Layout, Resources, SepImg); } ); } @@ -279,7 +437,7 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, for (Uint32 s = 0; s < NumShaders; ++s) { auto& Layout = Layouts[s]; - for (SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) { VERIFY(CurrResInd[s][VarType] == Layout.m_NumResources[VarType], "Not all resources are initialized, which will cause a crash when dtor is called"); } @@ -288,7 +446,9 @@ void ShaderResourceLayoutVk::Initialize(Uint32 NumShaders, } -Uint32 ShaderResourceLayoutVk::FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, Uint32 CurrResourceCount)const +Uint32 ShaderResourceLayoutVk::FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType)const { VERIFY_EXPR(SepImg.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); @@ -296,17 +456,16 @@ Uint32 ShaderResourceLayoutVk::FindAssignedSampler(const SPIRVShaderResourceAttr if (m_pResources->IsUsingCombinedSamplers() && SepImg.IsValidSepSamplerAssigned()) { const auto& SepSampler = m_pResources->GetSepSmplr(SepImg.GetAssignedSepSamplerInd()); - DEV_CHECK_ERR(SepImg.VarType == SepSampler.VarType, - "The type (", GetShaderVariableTypeLiteralName(SepImg.VarType),") of separate image variable '", SepImg.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SepSampler.VarType), - ") of the separate sampler '", SepSampler.Name, "' that is assigned to it."); - for (SamplerInd = 0; SamplerInd < CurrResourceCount; ++SamplerInd) { - const auto& Res = GetResource(SepSampler.VarType, SamplerInd); + const auto& Res = GetResource(ImgVarType, SamplerInd); if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && strcmp(Res.SpirvAttribs.Name, SepSampler.Name) == 0) { + DEV_CHECK_ERR(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."); break; } } @@ -319,9 +478,11 @@ Uint32 ShaderResourceLayoutVk::FindAssignedSampler(const SPIRVShaderResourceAttr return SamplerInd; } + + #define LOG_RESOURCE_BINDING_ERROR(ResType, pResource, VarName, ShaderName, ...)\ { \ - const auto &ResName = pResource->GetDesc().Name; \ + const auto& ResName = pResource->GetDesc().Name; \ LOG_ERROR_MESSAGE( "Failed to bind ", ResType, " '", ResName, "' to variable '", VarName, \ "' in shader '", ShaderName, "'. ", __VA_ARGS__ ); \ } @@ -362,11 +523,11 @@ bool ShaderResourceLayoutVk::VkResource::UpdateCachedResource(ShaderResourceCach RefCntAutoPtr pResource(pObject, InterfaceId); if(pResource) { - if (SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr) + if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr) { if (DstRes.pObject != pResource) { - auto VarTypeStr = GetShaderVariableTypeLiteralName(SpirvAttribs.VarType); + auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType()); LOG_ERROR_MESSAGE("Non-null resource is already bound to ", VarTypeStr, " shader variable '", SpirvAttribs.GetPrintName(ArrayInd), "' in shader '", ParentResLayout.GetShaderName(), "'. Attempring to bind another resource is an error and will be ignored. Use another shader resource binding instance or label the variable as dynamic."); } @@ -408,7 +569,7 @@ void ShaderResourceLayoutVk::VkResource::CacheUniformBuffer(IDeviceObject* // Do not update descriptor for a dynamic uniform buffer. All dynamic resource // descriptors are updated at once by CommitDynamicResources() when SRB is committed. - if (vkDescrSet != VK_NULL_HANDLE && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (vkDescrSet != VK_NULL_HANDLE && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { VkDescriptorBufferInfo DescrBuffInfo = DstRes.GetUniformBufferDescriptorWriteInfo(); UpdateDescriptorHandle(vkDescrSet, ArrayInd, nullptr, &DescrBuffInfo, nullptr); @@ -440,7 +601,7 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject* // Do not update descriptor for a dynamic storage buffer. All dynamic resource // descriptors are updated at once by CommitDynamicResources() when SRB is committed. - if (vkDescrSet != VK_NULL_HANDLE && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (vkDescrSet != VK_NULL_HANDLE && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { VkDescriptorBufferInfo DescrBuffInfo = DstRes.GetStorageBufferDescriptorWriteInfo(); UpdateDescriptorHandle(vkDescrSet, ArrayInd, nullptr, &DescrBuffInfo, nullptr); @@ -470,8 +631,8 @@ void ShaderResourceLayoutVk::VkResource::CacheTexelBuffer(IDeviceObject* const auto dbgExpectedViewType = IsStorageBuffer ? BUFFER_VIEW_UNORDERED_ACCESS : BUFFER_VIEW_SHADER_RESOURCE; if (ViewType != dbgExpectedViewType) { - const auto *ExpectedViewTypeName = GetViewTypeLiteralName(dbgExpectedViewType); - const auto *ActualViewTypeName = GetViewTypeLiteralName(ViewType); + const auto* ExpectedViewTypeName = GetViewTypeLiteralName(dbgExpectedViewType); + const auto* ActualViewTypeName = GetViewTypeLiteralName(ViewType); LOG_RESOURCE_BINDING_ERROR("Texture view", pBuffViewVk, SpirvAttribs.GetPrintName(ArrayInd), ParentResLayout.GetShaderName(), "Incorrect view type: ", ExpectedViewTypeName, " is expected, but ", ActualViewTypeName, " is provided."); DstRes.pObject.Release(); @@ -481,7 +642,7 @@ void ShaderResourceLayoutVk::VkResource::CacheTexelBuffer(IDeviceObject* // Do not update descriptor for a dynamic texel buffer. All dynamic resource descriptors // are updated at once by CommitDynamicResources() when SRB is committed. - if (vkDescrSet != VK_NULL_HANDLE && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (vkDescrSet != VK_NULL_HANDLE && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { VkBufferView BuffView = pBuffViewVk->GetVkBufferView(); UpdateDescriptorHandle(vkDescrSet, ArrayInd, nullptr, nullptr, &BuffView); @@ -511,15 +672,15 @@ void ShaderResourceLayoutVk::VkResource::CacheImage(IDeviceObject* const auto dbgExpectedViewType = IsStorageImage ? TEXTURE_VIEW_UNORDERED_ACCESS : TEXTURE_VIEW_SHADER_RESOURCE; if (ViewType != dbgExpectedViewType) { - const auto *ExpectedViewTypeName = GetViewTypeLiteralName(dbgExpectedViewType); - const auto *ActualViewTypeName = GetViewTypeLiteralName(ViewType); + const auto* ExpectedViewTypeName = GetViewTypeLiteralName(dbgExpectedViewType); + const auto* ActualViewTypeName = GetViewTypeLiteralName(ViewType); LOG_RESOURCE_BINDING_ERROR("Texture view", pTexViewVk, SpirvAttribs.GetPrintName(ArrayInd), ParentResLayout.GetShaderName(), "Incorrect view type: ", ExpectedViewTypeName, " is expected, but ", ActualViewTypeName, " is provided."); DstRes.pObject.Release(); return; } - if (SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage && !SpirvAttribs.IsImmutableSamplerAssigned()) + if (SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage && !IsImmutableSamplerAssigned()) { if(pTexViewVk->GetSampler() == nullptr) { @@ -530,18 +691,18 @@ void ShaderResourceLayoutVk::VkResource::CacheImage(IDeviceObject* // Do not update descriptor for a dynamic image. All dynamic resource descriptors // are updated at once by CommitDynamicResources() when SRB is committed. - if (vkDescrSet != VK_NULL_HANDLE && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (vkDescrSet != VK_NULL_HANDLE && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { - VkDescriptorImageInfo DescrImgInfo = DstRes.GetImageDescriptorWriteInfo(SpirvAttribs.IsImmutableSamplerAssigned()); + VkDescriptorImageInfo DescrImgInfo = DstRes.GetImageDescriptorWriteInfo(IsImmutableSamplerAssigned()); UpdateDescriptorHandle(vkDescrSet, ArrayInd, &DescrImgInfo, nullptr, nullptr); } if (SamplerInd != InvalidSamplerInd) { VERIFY_EXPR(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); - VERIFY_EXPR(!SpirvAttribs.IsImmutableSamplerAssigned()); + VERIFY_EXPR(!IsImmutableSamplerAssigned()); auto* pSampler = pTexViewVk->GetSampler(); - const auto& SamplerAttribs = ParentResLayout.GetResource(SpirvAttribs.VarType, SamplerInd); + const auto& SamplerAttribs = ParentResLayout.GetResource(GetVariableType(), SamplerInd); if (pSampler != nullptr) { CacheSampler(SamplerAttribs, pSampler); @@ -567,7 +728,7 @@ void ShaderResourceLayoutVk::VkResource::CacheSeparateSampler(IDeviceObject* { // Do not update descriptor for a dynamic sampler. All dynamic resource descriptors // are updated at once by CommitDynamicResources() when SRB is committed. - if (vkDescrSet != VK_NULL_HANDLE && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (vkDescrSet != VK_NULL_HANDLE && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { VkDescriptorImageInfo DescrImgInfo = DstRes.GetSamplerDescriptorWriteInfo(); UpdateDescriptorHandle(vkDescrSet, ArrayInd, &DescrImgInfo, nullptr, nullptr); @@ -576,16 +737,16 @@ void ShaderResourceLayoutVk::VkResource::CacheSeparateSampler(IDeviceObject* } -void ShaderResourceLayoutVk::VkResource::BindResource(IDeviceObject *pObj, Uint32 ArrayIndex, ShaderResourceCacheVk& ResourceCache)const +void ShaderResourceLayoutVk::VkResource::BindResource(IDeviceObject* pObj, Uint32 ArrayIndex, ShaderResourceCacheVk& ResourceCache)const { VERIFY_EXPR(ArrayIndex < SpirvAttribs.ArraySize); - auto &DstDescrSet = ResourceCache.GetDescriptorSet(DescriptorSet); + auto& DstDescrSet = ResourceCache.GetDescriptorSet(DescriptorSet); auto vkDescrSet = DstDescrSet.GetVkDescriptorSet(); #ifdef _DEBUG if (ResourceCache.DbgGetContentType() == ShaderResourceCacheVk::DbgCacheContentType::SRBResources) { - if(SpirvAttribs.VarType == SHADER_VARIABLE_TYPE_STATIC || SpirvAttribs.VarType == SHADER_VARIABLE_TYPE_MUTABLE) + if(VariableType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC || VariableType == SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) { VERIFY(vkDescrSet != VK_NULL_HANDLE, "Static and mutable variables must have valid vulkan descriptor set assigned"); // Dynamic variables do not have vulkan descriptor set only until they are assigned one the first time @@ -638,7 +799,7 @@ void ShaderResourceLayoutVk::VkResource::BindResource(IDeviceObject *pObj, Uint3 break; case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler: - if (!SpirvAttribs.IsImmutableSamplerAssigned()) + if (!IsImmutableSamplerAssigned()) { CacheSeparateSampler(pObj, DstRes, vkDescrSet, ArrayIndex); } @@ -655,7 +816,7 @@ void ShaderResourceLayoutVk::VkResource::BindResource(IDeviceObject *pObj, Uint3 } else { - if (DstRes.pObject && SpirvAttribs.VarType != SHADER_VARIABLE_TYPE_DYNAMIC) + if (DstRes.pObject && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { LOG_ERROR_MESSAGE( "Shader variable '", SpirvAttribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but being unbound. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label shader variable as dynamic if you need to bind another resource." ); } @@ -686,21 +847,21 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou const ShaderResourceCacheVk& SrcResourceCache, ShaderResourceCacheVk& DstResourceCache)const { - auto NumStaticResources = m_NumResources[SHADER_VARIABLE_TYPE_STATIC]; - VERIFY(NumStaticResources == SrcLayout.m_NumResources[SHADER_VARIABLE_TYPE_STATIC], "Inconsistent number of static resources"); + 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"); // Static shader resources are stored in one large continuous descriptor set for (Uint32 r=0; r < NumStaticResources; ++r) { // Get resource attributes - auto &DstRes = GetResource(SHADER_VARIABLE_TYPE_STATIC, r); - const auto &SrcRes = SrcLayout.GetResource(SHADER_VARIABLE_TYPE_STATIC, r); + auto& DstRes = GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); + const auto& SrcRes = SrcLayout.GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); VERIFY(SrcRes.Binding == SrcRes.SpirvAttribs.Type, "Unexpected binding"); VERIFY(SrcRes.SpirvAttribs.ArraySize == DstRes.SpirvAttribs.ArraySize, "Inconsistent array size"); if (DstRes.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && - DstRes.SpirvAttribs.IsImmutableSamplerAssigned()) + DstRes.IsImmutableSamplerAssigned()) continue; // Skip immutable samplers for (Uint32 ArrInd = 0; ArrInd < DstRes.SpirvAttribs.ArraySize; ++ArrInd) @@ -728,21 +889,21 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou bool ShaderResourceLayoutVk::dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache)const { bool BindingsOK = true; - for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { for(Uint32 r=0; r < m_NumResources[VarType]; ++r) { const auto& Res = GetResource(VarType, r); - VERIFY(Res.SpirvAttribs.VarType == VarType, "Unexpected variable type"); + VERIFY(Res.GetVariableType() == VarType, "Unexpected variable type"); for(Uint32 ArrInd = 0; ArrInd < Res.SpirvAttribs.ArraySize; ++ArrInd) { const auto& CachedDescrSet = ResourceCache.GetDescriptorSet(Res.DescriptorSet); const auto& CachedRes = CachedDescrSet.GetResource(Res.CacheOffset + ArrInd); VERIFY(CachedRes.Type == Res.SpirvAttribs.Type, "Inconsistent types"); if (CachedRes.pObject == nullptr && - !(Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.SpirvAttribs.IsImmutableSamplerAssigned())) + !(Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.IsImmutableSamplerAssigned())) { - LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(Res.SpirvAttribs.VarType), " variable '", Res.SpirvAttribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(Res.GetVariableType()), " variable '", Res.SpirvAttribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } #ifdef _DEBUG @@ -752,11 +913,11 @@ bool ShaderResourceLayoutVk::dvpVerifyBindings(const ShaderResourceCacheVk& Reso VERIFY(vkDescSet == VK_NULL_HANDLE, "Static resource cache should never have vulkan descriptor set"); else if (dbgCacheContentType == ShaderResourceCacheVk::DbgCacheContentType::SRBResources) { - if (VarType == SHADER_VARIABLE_TYPE_STATIC || VarType == SHADER_VARIABLE_TYPE_MUTABLE) + if (VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC || VarType == SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) { VERIFY(vkDescSet != VK_NULL_HANDLE, "Static and mutable variables must have valid vulkan descriptor set assigned"); } - else if (VarType == SHADER_VARIABLE_TYPE_DYNAMIC) + else if (VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) { VERIFY(vkDescSet == VK_NULL_HANDLE, "Dynamic variables must not be assigned a vulkan descriptor set"); } @@ -774,31 +935,23 @@ bool ShaderResourceLayoutVk::dvpVerifyBindings(const ShaderResourceCacheVk& Reso const Char* ShaderResourceLayoutVk::GetShaderName()const { - RefCntAutoPtr pShader(&m_Owner, IID_Shader); - if (pShader) + RefCntAutoPtr pPSO(&m_Owner, IID_PipelineState); + if (pPSO) { - return pShader->GetDesc().Name; + auto* pPSOVk = pPSO.RawPtr(); + auto* ppShaders = pPSOVk->GetShaders(); + auto NumShaders = pPSOVk->GetNumShaders(); + for (Uint32 s = 0; s < NumShaders; ++s) + { + const auto& ShaderDesc = ppShaders[s]->GetDesc(); + if (ShaderDesc.ShaderType == m_pResources->GetShaderType()) + return ShaderDesc.Name; + } + UNEXPECTED("Shader not found"); } else { - RefCntAutoPtr pPSO(&m_Owner, IID_PipelineState); - if (pPSO) - { - auto *pPSOVk = pPSO.RawPtr(); - auto *ppShaders = pPSOVk->GetShaders(); - auto NumShaders = pPSOVk->GetNumShaders(); - for (Uint32 s = 0; s < NumShaders; ++s) - { - const auto &ShaderDesc = ppShaders[s]->GetDesc(); - if(ShaderDesc.ShaderType == m_pResources->GetShaderType()) - return ShaderDesc.Name; - } - UNEXPECTED("Shader not found"); - } - else - { - UNEXPECTED("Shader resource layout owner must be a shader or a pipeline state"); - } + UNEXPECTED("Shader resource layout owner must be a shader or a pipeline state"); } return ""; } @@ -816,7 +969,7 @@ void ShaderResourceLayoutVk::InitializeResourceMemoryInCache(ShaderResourceCache void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache, VkDescriptorSet vkDynamicDescriptorSet)const { - Uint32 NumDynamicResources = m_NumResources[SHADER_VARIABLE_TYPE_DYNAMIC]; + Uint32 NumDynamicResources = m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC]; VERIFY(NumDynamicResources != 0, "This shader resource layout does not contain dynamic resources"); VERIFY_EXPR(vkDynamicDescriptorSet != VK_NULL_HANDLE); @@ -850,8 +1003,8 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& while(ResNum < NumDynamicResources) { - const auto& Res = GetResource(SHADER_VARIABLE_TYPE_DYNAMIC, ResNum); - VERIFY_EXPR(Res.SpirvAttribs.VarType == SHADER_VARIABLE_TYPE_DYNAMIC); + const auto& Res = GetResource(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC, ResNum); + VERIFY_EXPR(Res.GetVariableType() == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC); #ifdef _DEBUG if(DynamicDescrSetIndex < 0) DynamicDescrSetIndex = Res.DescriptorSet; @@ -914,7 +1067,7 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& while (ArrElem < Res.SpirvAttribs.ArraySize && DescrImgIt != DescrImgInfoArr.end()) { const auto& CachedRes = SetResources.GetResource(Res.CacheOffset + ArrElem); - *DescrImgIt = CachedRes.GetImageDescriptorWriteInfo(Res.SpirvAttribs.IsImmutableSamplerAssigned()); + *DescrImgIt = CachedRes.GetImageDescriptorWriteInfo(Res.IsImmutableSamplerAssigned()); ++DescrImgIt; ++ArrElem; } @@ -928,7 +1081,7 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler: // Immutable samplers are permanently bound into the set layout; later binding a sampler // into an immutable sampler slot in a descriptor set is not allowed (13.2.1) - if (!Res.SpirvAttribs.IsImmutableSamplerAssigned()) + if (!Res.IsImmutableSamplerAssigned()) { WriteDescrSetIt->pImageInfo = &(*DescrImgIt); while (ArrElem < Res.SpirvAttribs.ArraySize && DescrImgIt != DescrImgInfoArr.end()) -- cgit v1.2.3 From db55aa475fb2c13118e29c4ece91b99d20ab798a Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 09:05:39 -0800 Subject: Updated ShaderVariableVk and ShaderResourceBindingVk --- .../include/ShaderResourceBindingVkImpl.h | 4 ++-- .../include/ShaderVariableVk.h | 26 +++++++++++----------- .../src/ShaderResourceBindingVkImpl.cpp | 6 ++--- .../GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 13 ++++++----- 4 files changed, 25 insertions(+), 24 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h index 451ddcb8..b3933747 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h @@ -52,11 +52,11 @@ public: virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, const char* Name)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, const char* Name)override final; virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h index 92af69a3..5f7a0628 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h @@ -73,11 +73,11 @@ public: {} ~ShaderVariableManagerVk(); - void Initialize(const ShaderResourceLayoutVk& Layout, - IMemoryAllocator& Allocator, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache); + void Initialize(const ShaderResourceLayoutVk& Layout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheVk& ResourceCache); void Destroy(IMemoryAllocator& Allocator); ShaderVariableVkImpl* GetVariable(const Char* Name); @@ -85,10 +85,10 @@ public: void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags); - static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - Uint32& NumVariables); + static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + Uint32& NumVariables); Uint32 GetVariableCount()const { return m_NumVariables; } @@ -117,7 +117,7 @@ private: }; // sizeof(ShaderVariableVkImpl) == 24 (x64) -class ShaderVariableVkImpl final : public IShaderVariable +class ShaderVariableVkImpl final : public IShaderResourceVariable { public: ShaderVariableVkImpl(ShaderVariableManagerVk& ParentManager, @@ -153,16 +153,16 @@ public: return; *ppInterface = nullptr; - if (IID == IID_ShaderVariable || IID == IID_Unknown) + if (IID == IID_ShaderResourceVariable || IID == IID_Unknown) { *ppInterface = this; (*ppInterface)->AddRef(); } } - virtual SHADER_VARIABLE_TYPE GetType()const override final + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType()const override final { - return m_Resource.SpirvAttribs.VarType; + return m_Resource.GetVariableType(); } virtual void Set(IDeviceObject *pObject)override final diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 02a98d11..342f5ae6 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -64,7 +64,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl( IReferenceCounters* pR // Initialize vars manager to reference mutable and dynamic variables // Note that the cache has space for all variable types - std::array VarTypes = {{SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}}; + std::array VarTypes = {{SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}}; m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes.data(), static_cast(VarTypes.size()), m_ShaderResourceCache); m_ResourceLayoutIndex[ShaderInd] = static_cast(s); @@ -101,7 +101,7 @@ void ShaderResourceBindingVkImpl::BindResources(Uint32 ShaderFlags, IResourceMap } } -IShaderVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, const char *Name) +IShaderResourceVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, const char *Name) { auto ShaderInd = GetShaderTypeIndex(ShaderType); auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; @@ -125,7 +125,7 @@ Uint32 ShaderResourceBindingVkImpl::GetVariableCount(SHADER_TYPE ShaderType) con return m_pShaderVarMgrs[ResLayoutInd].GetVariableCount(); } -IShaderVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) +IShaderResourceVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) { auto ShaderInd = GetShaderTypeIndex(ShaderType); auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index 485ca318..22acaf5c 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -24,18 +24,19 @@ #include "pch.h" #include "ShaderVariableVk.h" +#include "ShaderResourceVariableBase.h" namespace Diligent { size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes, Uint32& NumVariables) { NumVariables = 0; Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { if (IsAllowedType(VarType, AllowedTypeBits)) { @@ -61,7 +62,7 @@ size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayout // Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout, IMemoryAllocator& Allocator, - const SHADER_VARIABLE_TYPE* AllowedVarTypes, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheVk& ResourceCache) { @@ -82,7 +83,7 @@ void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout m_pVariables = reinterpret_cast(pRawMem); Uint32 VarInd = 0; - for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { if (!IsAllowedType(VarType, AllowedTypeBits)) continue; @@ -186,10 +187,10 @@ void ShaderVariableManagerVk::BindResources( IResourceMapping* pResourceMapping, const auto& Res = Var.m_Resource; // Skip immutable separate samplers - if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.SpirvAttribs.IsImmutableSamplerAssigned()) + if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.IsImmutableSamplerAssigned()) continue; - if ( (Flags & (1 << Res.SpirvAttribs.VarType)) == 0 ) + if ( (Flags & (1 << Res.GetVariableType())) == 0 ) continue; for (Uint32 ArrInd = 0; ArrInd < Res.SpirvAttribs.ArraySize; ++ArrInd) -- cgit v1.2.3 From 43302d5fc3b3978952dd4215eea8f3f5668b95dd Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 20:45:24 -0800 Subject: Working on resource binding API refactor --- .../include/PipelineStateVkImpl.h | 42 +++++++- .../src/GenerateMipsVkHelper.cpp | 23 ++-- .../src/PipelineStateVkImpl.cpp | 120 +++++++++++++++++---- .../src/RenderDeviceVkImpl.cpp | 6 +- .../src/ShaderResourceBindingVkImpl.cpp | 19 +--- 5 files changed, 155 insertions(+), 55 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index cd7d1cab..07b0f414 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -33,6 +33,7 @@ #include "PipelineStateBase.h" #include "PipelineLayout.h" #include "ShaderResourceLayoutVk.h" +#include "ShaderVariableVk.h" #include "FixedBlockMemoryAllocator.h" #include "SRBMemoryAllocator.h" #include "VulkanUtilities/VulkanObjectWrappers.h" @@ -44,6 +45,7 @@ namespace Diligent { class FixedBlockMemoryAllocator; +class ShaderVariableManagerVk; /// Implementation of the Diligent::IRenderDeviceVk interface class PipelineStateVkImpl final : public PipelineStateBase @@ -54,9 +56,9 @@ public: PipelineStateVkImpl( IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc &PipelineDesc ); ~PipelineStateVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources)override final; virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; @@ -64,6 +66,14 @@ public: virtual VkPipeline GetVkPipeline()const override final { return m_Pipeline; } + virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags)override final; + + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) override final; + void CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, DeviceContextVkImpl* pCtxVkImpl, bool CommitResources, @@ -98,9 +108,31 @@ public: VkSubpassDescription& SubpassDesc); + void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache)const; + private: - ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; - + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_ShaderResourceLayouts[m_NumShaders + ShaderInd]; + } + + const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticResCaches[ShaderInd]; + } + + ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticVarsMgrs[ShaderInd]; + } + + ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; + ShaderResourceCacheVk* m_StaticResCaches = nullptr; + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; + // SRB memory allocator must be declared before m_pDefaultShaderResBinding SRBMemoryAllocator m_SRBMemAllocator; @@ -109,6 +141,8 @@ private: VkRenderPass m_RenderPass = VK_NULL_HANDLE; // Render passes are managed by the render device VulkanUtilities::PipelineWrapper m_Pipeline; PipelineLayout m_PipelineLayout; + + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; }; diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 793aea80..d177ca46 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -109,17 +109,8 @@ namespace Diligent CSCreateAttribs.Source = g_GenerateMipsCSSource; CSCreateAttribs.EntryPoint = "main"; - CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; + CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; CSCreateAttribs.Desc.ShaderType = SHADER_TYPE_COMPUTE; - CSCreateAttribs.Desc.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; - - ShaderResourceVariableDesc VarDesc{"CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - CSCreateAttribs.Desc.VariableDesc = &VarDesc; - CSCreateAttribs.Desc.NumVariables = 1; - - const StaticSamplerDesc StaticSampler("SrcMip", Sam_LinearClamp); - CSCreateAttribs.Desc.StaticSamplers = &StaticSampler; - CSCreateAttribs.Desc.NumStaticSamplers = 1; const auto& FmtAttribs = GetTextureFormatAttribs(Fmt); bool IsGamma = FmtAttribs.ComponentType == COMPONENT_TYPE_UNORM_SRGB; @@ -155,8 +146,18 @@ namespace Diligent PSODesc.IsComputePipeline = true; PSODesc.Name = name.c_str(); PSODesc.ComputePipeline.pCS = pCS; - pCS->GetShaderVariable("CB")->Set(m_ConstantsCB); + + PSODesc.Layout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; + ShaderResourceVariableDesc VarDesc{SHADER_TYPE_COMPUTE, "CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; + PSODesc.Layout.Variables = &VarDesc; + PSODesc.Layout.NumVariables = 1; + + const StaticSamplerDesc StaticSampler(SHADER_TYPE_COMPUTE, "SrcMip", Sam_LinearClamp); + PSODesc.Layout.StaticSamplers = &StaticSampler; + PSODesc.Layout.NumStaticSamplers = 1; + m_DeviceVkImpl.CreatePipelineState(PSODesc, &PSOs[NonPowOfTwo]); + PSOs[NonPowOfTwo]->GetStaticShaderVariable(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); } return PSOs; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 8fd4583c..2a60ce96 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -60,12 +60,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( { auto& DepthAttachment = Attachments[AttachmentInd]; - DepthAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - DepthAttachment.format = TexFormatToVkFormat(DSVFormat); + DepthAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT + DepthAttachment.format = TexFormatToVkFormat(DSVFormat); DepthAttachment.samples = SampleCountFlags; - DepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area - // will be preserved. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. + DepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area + // will be preserved. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. DepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render // area are written to memory. For attachments with a depth/stencil format, // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. @@ -113,12 +113,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. - SubpassDesc.flags = 0; // All bits for this type are defined by extensions - SubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Currently, only graphics subpasses are supported. - SubpassDesc.inputAttachmentCount = 0; - SubpassDesc.pInputAttachments = nullptr; - SubpassDesc.colorAttachmentCount = NumRenderTargets; - SubpassDesc.pColorAttachments = pColorAttachmentsReference; + SubpassDesc.flags = 0; // All bits for this type are defined by extensions + SubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Currently, only graphics subpasses are supported. + SubpassDesc.inputAttachmentCount = 0; + SubpassDesc.pInputAttachments = nullptr; + SubpassDesc.colorAttachmentCount = NumRenderTargets; + SubpassDesc.pColorAttachments = pColorAttachmentsReference; SubpassDesc.pResolveAttachments = nullptr; SubpassDesc.pDepthStencilAttachment = pDepthAttachmentReference; SubpassDesc.preserveAttachmentCount = 0; @@ -147,7 +147,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc) : TPipelineStateBase(pRefCounters, pDeviceVk, PipelineDesc), - m_SRBMemAllocator(GetRawAllocator()) + m_SRBMemAllocator (GetRawAllocator()) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); @@ -155,16 +155,32 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters auto& ShaderResLayoutAllocator = GetRawAllocator(); std::array, MaxShadersInPipeline> ShaderResources; std::array, MaxShadersInPipeline> ShaderSPIRVs; - auto* pResLayoutRawMem = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", sizeof(ShaderResourceLayoutVk) * m_NumShaders); + auto* pResLayoutRawMem = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", sizeof(ShaderResourceLayoutVk) * m_NumShaders * 2); + auto* pStaticResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheVk", sizeof(ShaderResourceCacheVk) * m_NumShaders); + auto* pStaticVarMgrRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", sizeof(ShaderVariableManagerVk) * m_NumShaders); m_ShaderResourceLayouts = reinterpret_cast(pResLayoutRawMem); + m_StaticResCaches = reinterpret_cast(pStaticResCacheRawMem); + m_StaticVarsMgrs = reinterpret_cast(pStaticVarMgrRawMem); for (Uint32 s=0; s < m_NumShaders; ++s) { new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(*this, LogicalDevice); auto* pShaderVk = GetShader(s); ShaderResources[s] = pShaderVk->GetShaderResources(); ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); + + const auto ShaderType = pShaderVk->GetDesc().ShaderType; + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); + + auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk(*this, LogicalDevice); + auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk(ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources); + pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, PipelineDesc.Layout, m_StaticResCaches[s]); + + auto* pStaticVarMgr = new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this); + pStaticVarMgr->Initialize(*pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache); } - ShaderResourceLayoutVk::Initialize(m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), ShaderSPIRVs.data(), m_PipelineLayout); + ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), + PipelineDesc.Layout, ShaderSPIRVs.data(), m_PipelineLayout); m_PipelineLayout.Finalize(LogicalDevice); if (PipelineDesc.SRBAllocationGranularity > 1) @@ -172,7 +188,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters std::array ShaderVariableDataSizes = {}; for (Uint32 s = 0; s < m_NumShaders; ++s) { - std::array AllowedVarTypes = { {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC} }; + std::array AllowedVarTypes = { {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; Uint32 UnusedNumVars = 0; ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(m_ShaderResourceLayouts[s], AllowedVarTypes.data(), static_cast(AllowedVarTypes.size()), UnusedNumVars); } @@ -412,11 +428,11 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters for (Uint32 s=0; s < m_NumShaders; ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_STATIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) != 0) m_HasStaticResources = true; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_MUTABLE) != 0 || - Layout.GetResourceCount(SHADER_VARIABLE_TYPE_DYNAMIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) != 0 || + Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) m_HasNonStaticResources = true; } @@ -440,8 +456,13 @@ PipelineStateVkImpl::~PipelineStateVkImpl() for (Uint32 s=0; s < m_NumShaders; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); + m_StaticResCaches[s].~ShaderResourceCacheVk(); + m_StaticVarsMgrs[s].Destroy(GetRawAllocator()); + m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); } RawAllocator.Free(m_ShaderResourceLayouts); + RawAllocator.Free(m_StaticResCaches); + RawAllocator.Free(m_StaticVarsMgrs); } IMPLEMENT_QUERY_INTERFACE( PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase ) @@ -581,7 +602,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind for (Uint32 s=0; s < m_NumShaders; ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_DYNAMIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) Layout.CommitDynamicResources(ResourceCache, DynamicDescrSet); } } @@ -593,4 +614,65 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind } } +void PipelineStateVkImpl::BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags) +{ + for (Uint32 s=0; s < m_NumShaders; ++s) + { + auto& StaticVarMgr = GetStaticVarMgr(s); + StaticVarMgr.BindResources(pResourceMapping, Flags); + } +} + +Uint32 PipelineStateVkImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return 0; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariableCount(); +} + +IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return nullptr; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariable(Name); +} + +IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return nullptr; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariable(Index); +} + + +void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache)const +{ + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + const auto& StaticResLayout = GetStaticShaderResLayout(s); +#ifdef DEVELOPMENT + if (!StaticResLayout.dvpVerifyBindings(ResourceCache)) + { + 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, "' are valid. " + "Please make sure you bind all static resources to the shader before calling InitializeStaticResources() " + "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); + } +#endif + const auto& StaticResCache = GetStaticResCache(s); + const auto& ShaderResourceLayouts = GetShaderResLayout(s); + ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, ResourceCache); + } +} + } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index dbf2893f..89ed5d01 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -433,12 +433,12 @@ void RenderDeviceVkImpl :: CreateBuffer(const BufferDesc& BuffDesc, const Buffer } -void RenderDeviceVkImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) +void RenderDeviceVkImpl :: CreateShader(const ShaderCreateInfo& ShaderCI, IShader **ppShader) { - CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + CreateDeviceObject( "shader", ShaderCI.Desc, ppShader, [&]() { - ShaderVkImpl *pShaderVk( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderVkImpl instance", ShaderVkImpl)(this, ShaderCreationAttribs ) ); + ShaderVkImpl *pShaderVk( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderVkImpl instance", ShaderVkImpl)(this, ShaderCI) ); pShaderVk->QueryInterface( IID_Shader, reinterpret_cast(ppShader) ); OnCreateDeviceObject( pShaderVk ); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 342f5ae6..3077a5dd 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -155,24 +155,7 @@ void ShaderResourceBindingVkImpl::InitializeStaticResources(const IPipelineState } auto* pPSOVK = ValidatedCast(pPipelineState); - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - const auto* pShaderVk = pPSOVK->GetShader(s); -#ifdef DEVELOPMENT - if (!pShaderVk->DvpVerifyStaticResourceBindings()) - { - LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOVK->GetDesc().Name, "' will not be successfully initialized " - "because not all static resource bindings in shader '", pShaderVk->GetDesc().Name, "' are valid. " - "Please make sure you bind all static resources to the shader before calling InitializeStaticResources() " - "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); - } -#endif - const auto& StaticResLayout = pShaderVk->GetStaticResLayout(); - const auto& StaticResCache = pShaderVk->GetStaticResCache(); - const auto& ShaderResourceLayouts = pPSOVK->GetShaderResLayout(s); - ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, m_ShaderResourceCache); - } - + pPSOVK->InitializeStaticSRBResources(m_ShaderResourceCache); m_bStaticResourcesInitialized = true; } -- cgit v1.2.3 From 26e240dfcb3dad8527a25c0f6270395528a5a71e Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 20:56:45 -0800 Subject: Fixed PipelineLayoutVk --- .../GraphicsEngineVulkan/include/PipelineLayout.h | 12 ++++++----- .../include/RenderDeviceVkImpl.h | 6 +++--- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 23 +++++++++++----------- .../src/ShaderResourceLayoutVk.cpp | 2 +- 4 files changed, 23 insertions(+), 20 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index f970501a..a875cb90 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -58,6 +58,7 @@ public: const char* DbgPipelineName)const; void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, VkSampler vkStaticSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, @@ -65,9 +66,9 @@ public: Uint32& OffsetInCache, std::vector& SPIRV); - Uint32 GetTotalDescriptors(SHADER_VARIABLE_TYPE VarType)const + Uint32 GetTotalDescriptors(SHADER_RESOURCE_VARIABLE_TYPE VarType)const { - VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES); + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES); return m_LayoutMgr.GetDescriptorSet(VarType).TotalDescriptors; } @@ -82,7 +83,7 @@ public: VkDescriptorSetLayout GetDynamicDescriptorSetVkLayout()const { - return m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_DYNAMIC).VkLayout; + return m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC).VkLayout; } struct DescriptorSetBindInfo @@ -178,8 +179,8 @@ private: void Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice); void Release(RenderDeviceVkImpl* pRenderDeviceVk, Uint64 CommandQueueMask); - DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType) { return m_DescriptorSetLayouts[VarType == SHADER_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } - const DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType)const { return m_DescriptorSetLayouts[VarType == SHADER_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } + DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType) { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } + const DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType)const { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } bool operator == (const DescriptorSetLayoutManager& rhs)const; bool operator != (const DescriptorSetLayoutManager& rhs)const {return !(*this == rhs);} @@ -187,6 +188,7 @@ private: VkPipelineLayout GetVkPipelineLayout()const{return m_VkPipelineLayout;} void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, VkSampler vkStaticSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h index 64410774..c0e2847b 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h @@ -66,13 +66,13 @@ public: Uint32 NumDeferredContexts ); ~RenderDeviceVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; - virtual void CreatePipelineState( const PipelineStateDesc &PipelineDesc, IPipelineState** ppPipelineState )override final; + virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState)override final; virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer)override final; - virtual void CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader)override final; + virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader)override final; virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture)override final; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 6e930bcc..7ce29a6f 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -315,13 +315,14 @@ size_t PipelineLayout::DescriptorSetLayoutManager::GetHash()const } void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, VkSampler vkStaticSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, Uint32& Binding, Uint32& OffsetInCache) { - auto& DescrSet = GetDescriptorSet(ResAttribs.VarType); + auto& DescrSet = GetDescriptorSet(VariableType); if (DescrSet.SetIndex < 0) { DescrSet.SetIndex = m_ActiveSets++; @@ -335,9 +336,8 @@ void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIR VkBinding.descriptorCount = ResAttribs.ArraySize; // There are no limitations on what combinations of stages can use a descriptor binding (13.2.1) VkBinding.stageFlags = ShaderTypeToVkShaderStageFlagBit(ShaderType); - if (ResAttribs.IsImmutableSamplerAssigned()) + if (vkStaticSampler != VK_NULL_HANDLE) { - VERIFY(vkStaticSampler != VK_NULL_HANDLE, "No static sampler provided"); // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and // descriptorCount is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a valid pointer // to an array of descriptorCount valid VkSampler handles (13.2.1) @@ -365,6 +365,7 @@ void PipelineLayout::Release(RenderDeviceVkImpl *pDeviceVkImpl, Uint64 CommandQu } void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, VkSampler vkStaticSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, // Output parameter @@ -372,7 +373,7 @@ void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResA Uint32& OffsetInCache, std::vector& SPIRV) { - m_LayoutMgr.AllocateResourceSlot(ResAttribs, vkStaticSampler, ShaderType, DescriptorSet, Binding, OffsetInCache); + m_LayoutMgr.AllocateResourceSlot(ResAttribs, VariableType,vkStaticSampler, ShaderType, DescriptorSet, Binding, OffsetInCache); SPIRV[ResAttribs.BindingDecorationOffset] = Binding; SPIRV[ResAttribs.DescriptorSetDecorationOffset] = DescriptorSet; } @@ -387,14 +388,14 @@ std::array PipelineLayout::GetDescriptorSetSizes(Uint32& NumSets)cons NumSets = 0; std::array SetSizes = {}; - const auto &StaticAndMutSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_STATIC); + const auto &StaticAndMutSet = m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_STATIC); if (StaticAndMutSet.SetIndex >= 0) { NumSets = std::max(NumSets, static_cast(StaticAndMutSet.SetIndex + 1)); SetSizes[StaticAndMutSet.SetIndex] = StaticAndMutSet.TotalDescriptors; } - const auto &DynamicSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_DYNAMIC); + const auto &DynamicSet = m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC); if (DynamicSet.SetIndex >= 0) { NumSets = std::max(NumSets, static_cast(DynamicSet.SetIndex + 1)); @@ -416,7 +417,7 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, // Resources are initialized by source layout when shader resource binding objects are created ResourceCache.InitializeSets(CacheMemAllocator, NumSets, SetSizes.data()); - const auto& StaticAndMutSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_STATIC); + const auto& StaticAndMutSet = m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_STATIC); if (StaticAndMutSet.SetIndex >= 0) { const char* DescrSetName = "Static/Mutable Descriptor Set"; @@ -443,11 +444,11 @@ void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkI // Do not use vector::resize for BindInfo.vkSets and BindInfo.DynamicOffsets as this // causes unnecessary work to zero-initialize new elements - VERIFY(m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_STATIC).SetIndex == m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_MUTABLE).SetIndex, + VERIFY(m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_STATIC).SetIndex == m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE).SetIndex, "Static and mutable variables are expected to share the same descriptor set"); Uint32 TotalDynamicDescriptors = 0; BindInfo.SetCout = 0; - for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType+1)) + for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType+1)) { const auto& Set = m_LayoutMgr.GetDescriptorSet(VarType); if (Set.SetIndex >= 0) @@ -456,7 +457,7 @@ void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkI if (BindInfo.SetCout > BindInfo.vkSets.size()) BindInfo.vkSets.resize(BindInfo.SetCout); VERIFY_EXPR(BindInfo.vkSets[Set.SetIndex] == VK_NULL_HANDLE); - if (VarType == SHADER_VARIABLE_TYPE_MUTABLE) + if (VarType == SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) BindInfo.vkSets[Set.SetIndex] = ResourceCache.GetDescriptorSet(Set.SetIndex).GetVkDescriptorSet(); else { @@ -506,7 +507,7 @@ void PipelineLayout::BindDescriptorSetsWithDynamicOffsets(DeviceContextVkImpl* VERIFY_EXPR(BindInfo.pResourceCache != nullptr); #ifdef _DEBUG Uint32 TotalDynamicDescriptors = 0; - for (SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType + 1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType + 1)) { const auto &Set = m_LayoutMgr.GetDescriptorSet(VarType); TotalDynamicDescriptors += Set.NumDynamicDescriptors; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 9151fc9a..546fd01e 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -338,7 +338,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } auto& ShaderSPIRV = SPIRVs[ShaderInd]; - PipelineLayout.AllocateResourceSlot(Attribs, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); + PipelineLayout.AllocateResourceSlot(Attribs, VarType, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); VERIFY(DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", DescriptorSet, ") excceeds max representable value"); VERIFY(Binding <= std::numeric_limits::max(), "Binding (", Binding, ") excceeds max representable value"); -- cgit v1.2.3 From 59f58900fed7fa5c2ed490d31252950b55308175 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 21:15:52 -0800 Subject: Keeping copy of a shader name in SPIRVShaderResources --- .../include/ShaderResourceLayoutVk.h | 15 ++++++--- .../src/PipelineStateVkImpl.cpp | 4 +-- .../src/ShaderResourceLayoutVk.cpp | 37 +++------------------- 3 files changed, 16 insertions(+), 40 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index f49bc342..b4712d70 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -107,12 +107,15 @@ namespace Diligent { /// Diligent::ShaderResourceLayoutVk class -// sizeof(ShaderResourceLayoutVk)==64 (MS compiler, x64) - TODO: verify +// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) - TODO: verify class ShaderResourceLayoutVk { public: - ShaderResourceLayoutVk(IObject& Owner, - const VulkanUtilities::VulkanLogicalDevice& LogicalDevice); + ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : + m_LogicalDevice(LogicalDevice) + { + } + ShaderResourceLayoutVk (const ShaderResourceLayoutVk&) = delete; ShaderResourceLayoutVk (ShaderResourceLayoutVk&&) = delete; @@ -271,7 +274,10 @@ public: void CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache, VkDescriptorSet vkDynamicDescriptorSet)const; - const Char* GetShaderName()const; + const Char* GetShaderName()const + { + return m_pResources->GetShaderName(); + } const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r)const { @@ -329,7 +335,6 @@ private: return reinterpret_cast(ResourceMemoryEnd)[n]; } - IObject& m_Owner; const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; std::unique_ptr > m_ResourceBuffer; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 2a60ce96..14f4c962 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -163,7 +163,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters m_StaticVarsMgrs = reinterpret_cast(pStaticVarMgrRawMem); for (Uint32 s=0; s < m_NumShaders; ++s) { - new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(*this, LogicalDevice); + new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(LogicalDevice); auto* pShaderVk = GetShader(s); ShaderResources[s] = pShaderVk->GetShaderResources(); ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); @@ -172,7 +172,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); - auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk(*this, LogicalDevice); + 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, PipelineDesc.Layout, m_StaticResCaches[s]); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 546fd01e..a0835334 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -90,13 +90,6 @@ static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE } -ShaderResourceLayoutVk::ShaderResourceLayoutVk(IObject& Owner, - const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : - m_Owner(Owner), - m_LogicalDevice(LogicalDevice) -{ -} - ShaderResourceLayoutVk::~ShaderResourceLayoutVk() { auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); @@ -521,14 +514,16 @@ bool ShaderResourceLayoutVk::VkResource::UpdateCachedResource(ShaderResourceCach // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type RefCntAutoPtr pResource(pObject, InterfaceId); - if(pResource) + if (pResource) { if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr) { if (DstRes.pObject != pResource) { auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType()); - LOG_ERROR_MESSAGE("Non-null resource is already bound to ", VarTypeStr, " shader variable '", SpirvAttribs.GetPrintName(ArrayInd), "' in shader '", ParentResLayout.GetShaderName(), "'. Attempring to bind another resource is an error and will be ignored. Use another shader resource binding instance or label the variable as dynamic."); + LOG_ERROR_MESSAGE("Non-null resource is already bound to ", VarTypeStr, " shader variable '", SpirvAttribs.GetPrintName(ArrayInd), + "' in shader '", ParentResLayout.GetShaderName(), "'. Attempring to bind another resource is an error and will be ignored. " + "Use another shader resource binding instance or label the variable as dynamic."); } // Do not update resource if one is already bound unless it is dynamic. This may be @@ -932,30 +927,6 @@ bool ShaderResourceLayoutVk::dvpVerifyBindings(const ShaderResourceCacheVk& Reso } #endif - -const Char* ShaderResourceLayoutVk::GetShaderName()const -{ - RefCntAutoPtr pPSO(&m_Owner, IID_PipelineState); - if (pPSO) - { - auto* pPSOVk = pPSO.RawPtr(); - auto* ppShaders = pPSOVk->GetShaders(); - auto NumShaders = pPSOVk->GetNumShaders(); - for (Uint32 s = 0; s < NumShaders; ++s) - { - const auto& ShaderDesc = ppShaders[s]->GetDesc(); - if (ShaderDesc.ShaderType == m_pResources->GetShaderType()) - return ShaderDesc.Name; - } - UNEXPECTED("Shader not found"); - } - else - { - UNEXPECTED("Shader resource layout owner must be a shader or a pipeline state"); - } - return ""; -} - void ShaderResourceLayoutVk::InitializeResourceMemoryInCache(ShaderResourceCacheVk& ResourceCache)const { auto TotalResources = GetTotalResourceCount(); -- cgit v1.2.3 From ea25e99aaca4dd9c4a442d9ce39a5365aaf72bc1 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 28 Feb 2019 00:29:49 -0800 Subject: Fixed some issues in Vk backend --- .../include/ShaderResourceLayoutVk.h | 2 +- .../GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 18 +++++++++--------- .../src/ShaderResourceLayoutVk.cpp | 7 ++++--- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index b4712d70..c3dd9146 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -142,7 +142,7 @@ public: std::vector SPIRVs[], class PipelineLayout& PipelineLayout); - // sizeof(VkResource) == 24 (x64) - TODO: Verify + // sizeof(VkResource) == 24 (x64) struct VkResource { VkResource (const VkResource&) = delete; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 14f4c962..443076df 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -625,31 +625,31 @@ void PipelineStateVkImpl::BindStaticResources(IResourceMapping* pResourceMapping Uint32 PipelineStateVkImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const { - const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); - if (ShaderTypeInd < 0) + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) return 0; - auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); return StaticVarMgr.GetVariableCount(); } IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) { - const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); - if (ShaderTypeInd < 0) + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) return nullptr; - auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); return StaticVarMgr.GetVariable(Name); } IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) { - const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); - if (ShaderTypeInd < 0) + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + if (LayoutInd < 0) return nullptr; - auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + auto& StaticVarMgr = GetStaticVarMgr(LayoutInd); return StaticVarMgr.GetVariable(Index); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index a0835334..201fadc6 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -154,7 +154,8 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrGetShaderType(); - const auto* CombinedSamplerSuffix = pSrcResources->GetCombinedSamplerSuffix(); + const auto ShaderType = m_pResources->GetShaderType(); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) -- cgit v1.2.3 From 3f69e88e20ebabc9b4ee363106e7646cbff7d754 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 28 Feb 2019 07:13:07 -0800 Subject: Fixed memory leak --- Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 443076df..ec5ff6b3 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -453,9 +453,13 @@ PipelineStateVkImpl::~PipelineStateVkImpl() } auto& RawAllocator = GetRawAllocator(); - for (Uint32 s=0; s < m_NumShaders; ++s) + for (Uint32 s=0; s < m_NumShaders*2; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); + } + + for (Uint32 s=0; s < m_NumShaders; ++s) + { m_StaticResCaches[s].~ShaderResourceCacheVk(); m_StaticVarsMgrs[s].Destroy(GetRawAllocator()); m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); -- cgit v1.2.3 From 6384ebb550a265f60dc30220d21460164df07936 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 28 Feb 2019 07:35:57 -0800 Subject: Improved shader resource binding error reporting in ShaderResourceLayoutVk --- .../GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 201fadc6..7f1eb1bb 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -225,6 +225,11 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* { bool VariableFound = false; const auto& VarDesc = LayoutDesc.Variables[v]; + if (VarDesc.ShaderStages == SHADER_TYPE_UNKNOWN) + { + LOG_WARNING_MESSAGE("No allowed shader stages specified for variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), "."); + } + for(Uint32 s=0; s < NumShaders && !VariableFound; ++s) { const auto& Resources = *pShaderResources[s]; @@ -239,17 +244,25 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } if (!VariableFound) { - LOG_WARNING_MESSAGE("Variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), " is not found in any of shader stages"); + LOG_WARNING_MESSAGE("Variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), " is not found in any of the specified shader stages: ", GetShaderStagesString(VarDesc.ShaderStages)); } } for (Uint32 sam = 0; sam < LayoutDesc.NumStaticSamplers; ++sam) { const auto& StSamDesc = LayoutDesc.StaticSamplers[sam]; + if (StSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) + { + LOG_WARNING_MESSAGE("No allowed shader stages specified for static sampler '", StSamDesc.SamplerOrTextureName, "."); + } + bool SamplerFound = false; for(Uint32 s=0; s < NumShaders && !SamplerFound; ++s) { const auto& Resources = *pShaderResources[s]; + if ( (StSamDesc.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) for (Uint32 i = 0; i < Resources.GetNumSmpldImgs() && !SamplerFound; ++i) @@ -276,7 +289,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* if (!SamplerFound) { - LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, "' is not found in any of shader stages"); + LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, "' is not found in any of the specified shader stages: ", GetShaderStagesString(StSamDesc.ShaderStages)); } } #endif -- cgit v1.2.3 From a11b4c46b33a49501b81ce638474abd36b89582b Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 28 Feb 2019 07:56:53 -0800 Subject: Renamed PipelineLayoutDesc to PipelineResourceLayoutDesc --- .../include/ShaderResourceLayoutVk.h | 6 +-- .../src/GenerateMipsVkHelper.cpp | 10 ++--- .../src/PipelineStateVkImpl.cpp | 4 +- .../src/ShaderResourceLayoutVk.cpp | 48 +++++++++++----------- 4 files changed, 34 insertions(+), 34 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index c3dd9146..5fd6f520 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -128,7 +128,7 @@ public: // shader resource layout and the cache void InitializeStaticResourceLayout(std::shared_ptr pSrcResources, IMemoryAllocator& LayoutDataAllocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache); // This method is called by PipelineStateVkImpl class instance to initialize resource @@ -138,7 +138,7 @@ public: ShaderResourceLayoutVk Layouts[], std::shared_ptr pShaderResources[], IMemoryAllocator& LayoutDataAllocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, std::vector SPIRVs[], class PipelineLayout& PipelineLayout); @@ -319,7 +319,7 @@ private: void AllocateMemory(std::shared_ptr pSrcResources, IMemoryAllocator& Allocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes); diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index d177ca46..305f04ef 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -147,14 +147,14 @@ namespace Diligent PSODesc.Name = name.c_str(); PSODesc.ComputePipeline.pCS = pCS; - PSODesc.Layout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; + PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; ShaderResourceVariableDesc VarDesc{SHADER_TYPE_COMPUTE, "CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - PSODesc.Layout.Variables = &VarDesc; - PSODesc.Layout.NumVariables = 1; + PSODesc.ResourceLayout.Variables = &VarDesc; + PSODesc.ResourceLayout.NumVariables = 1; const StaticSamplerDesc StaticSampler(SHADER_TYPE_COMPUTE, "SrcMip", Sam_LinearClamp); - PSODesc.Layout.StaticSamplers = &StaticSampler; - PSODesc.Layout.NumStaticSamplers = 1; + PSODesc.ResourceLayout.StaticSamplers = &StaticSampler; + PSODesc.ResourceLayout.NumStaticSamplers = 1; m_DeviceVkImpl.CreatePipelineState(PSODesc, &PSOs[NonPowOfTwo]); PSOs[NonPowOfTwo]->GetStaticShaderVariable(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index ec5ff6b3..548441a7 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -174,13 +174,13 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters 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, PipelineDesc.Layout, m_StaticResCaches[s]); + pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, PipelineDesc.ResourceLayout, m_StaticResCaches[s]); auto* pStaticVarMgr = new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this); pStaticVarMgr->Initialize(*pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache); } ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), - PipelineDesc.Layout, ShaderSPIRVs.data(), m_PipelineLayout); + PipelineDesc.ResourceLayout, ShaderSPIRVs.data(), m_PipelineLayout); m_PipelineLayout.Finalize(LogicalDevice); if (PipelineDesc.SRBAllocationGranularity > 1) diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 7f1eb1bb..abd606b4 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -40,7 +40,7 @@ namespace Diligent { static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SPIRVShaderResourceAttribs& Attribs, const char* SamplerSuffix) { @@ -58,9 +58,9 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, return -1; } - for (Uint32 s=0; s < LayoutDesc.NumStaticSamplers; ++s) + for (Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) { - const auto& StSam = LayoutDesc.StaticSamplers[s]; + const auto& StSam = ResourceLayoutDesc.StaticSamplers[s]; if ( ((StSam.ShaderStages & ShaderType) != 0) && StreqSuff(Attribs.Name, StSam.SamplerOrTextureName, SamplerSuffix) ) return s; } @@ -70,14 +70,14 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE ShaderType, const SPIRVShaderResourceAttribs& Attribs, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, const char* CombinedSamplerSuffix) { if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) { // Use texture or sampler name to derive separate sampler type // When HLSL-style combined image samplers are not used, CombinedSamplerSuffix is null - return GetShaderVariableType(ShaderType, LayoutDesc.DefaultVariableType, LayoutDesc.Variables, LayoutDesc.NumVariables, + return GetShaderVariableType(ShaderType, ResourceLayoutDesc.DefaultVariableType, ResourceLayoutDesc.Variables, ResourceLayoutDesc.NumVariables, [&](const char* VarName) { return StreqSuff(Attribs.Name, VarName, CombinedSamplerSuffix); @@ -85,7 +85,7 @@ static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE } else { - return GetShaderVariableType(ShaderType, Attribs.Name, LayoutDesc); + return GetShaderVariableType(ShaderType, Attribs.Name, ResourceLayoutDesc); } } @@ -102,7 +102,7 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk() void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr pSrcResources, IMemoryAllocator& Allocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes) { @@ -119,7 +119,7 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) { - auto VarType = GetShaderVariableType(ShaderType, ResAttribs, LayoutDesc, CombinedSamplerSuffix); + auto VarType = GetShaderVariableType(ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (IsAllowedType(VarType, AllowedTypeBits)) { VERIFY( Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds max representable value"); @@ -137,9 +137,9 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr(TotalResources); m_NumImmutableSamplers = 0; - for(Uint32 s=0; s < LayoutDesc.NumStaticSamplers; ++s) + for(Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) { - const auto& StSamDesc = LayoutDesc.StaticSamplers[s]; + const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; if ((StSamDesc.ShaderStages & ShaderType) != 0) ++m_NumImmutableSamplers; } @@ -162,11 +162,11 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr pSrcResources, IMemoryAllocator& LayoutDataAllocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, ShaderResourceCacheVk& StaticResourceCache) { auto AllowedVarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; - AllocateMemory(std::move(pSrcResources), LayoutDataAllocator, LayoutDesc, &AllowedVarType, 1); + AllocateMemory(std::move(pSrcResources), LayoutDataAllocator, ResourceLayoutDesc, &AllowedVarType, 1); std::array CurrResInd = {}; Uint32 StaticResCacheSize = 0; @@ -178,7 +178,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptrProcessResources( [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) { - auto VarType = GetShaderVariableType(ShaderType, Attribs, LayoutDesc, CombinedSamplerSuffix); + auto VarType = GetShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (!IsAllowedType(VarType, AllowedTypeBits)) return; @@ -216,15 +216,15 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* ShaderResourceLayoutVk Layouts[], std::shared_ptr pShaderResources[], IMemoryAllocator& LayoutDataAllocator, - const PipelineLayoutDesc& LayoutDesc, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, std::vector SPIRVs[], class PipelineLayout& PipelineLayout) { #ifdef DEVELOPMENT - for (Uint32 v = 0; v < LayoutDesc.NumVariables; ++v) + for (Uint32 v = 0; v < ResourceLayoutDesc.NumVariables; ++v) { bool VariableFound = false; - const auto& VarDesc = LayoutDesc.Variables[v]; + const auto& VarDesc = ResourceLayoutDesc.Variables[v]; if (VarDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { LOG_WARNING_MESSAGE("No allowed shader stages specified for variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), "."); @@ -248,9 +248,9 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } } - for (Uint32 sam = 0; sam < LayoutDesc.NumStaticSamplers; ++sam) + for (Uint32 sam = 0; sam < ResourceLayoutDesc.NumStaticSamplers; ++sam) { - const auto& StSamDesc = LayoutDesc.StaticSamplers[sam]; + const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[sam]; if (StSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { LOG_WARNING_MESSAGE("No allowed shader stages specified for static sampler '", StSamDesc.SamplerOrTextureName, "."); @@ -301,7 +301,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* for (Uint32 s=0; s < NumShaders; ++s) { - Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, LayoutDesc, AllowedVarTypes, NumAllowedTypes); + Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes); } VERIFY_EXPR(NumShaders <= MaxShadersInPipeline); @@ -320,7 +320,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* Uint32 DescriptorSet = 0; Uint32 CacheOffset = 0; const auto ShaderType = Resources.GetShaderType(); - const SHADER_RESOURCE_VARIABLE_TYPE VarType = GetShaderVariableType(ShaderType, Attribs, LayoutDesc, Resources.GetCombinedSamplerSuffix()); + const SHADER_RESOURCE_VARIABLE_TYPE VarType = GetShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix()); if (!IsAllowedType(VarType, AllowedTypeBits)) return; @@ -333,13 +333,13 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* SamplerInd = ResLayout.FindAssignedSampler(Attribs, CurrResInd[ShaderInd][VarType], VarType); } - Int32 SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, LayoutDesc, Attribs, Resources.GetCombinedSamplerSuffix()); + Int32 SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, ResourceLayoutDesc, Attribs, Resources.GetCombinedSamplerSuffix()); VkSampler vkImmutableSampler = VK_NULL_HANDLE; if (SrcImmutableSamplerInd >= 0) { auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++); VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized!"); - const auto& ImmutableSamplerDesc = LayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; + const auto& ImmutableSamplerDesc = ResourceLayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; pRenderDevice->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); vkImmutableSampler = ImmutableSampler.RawPtr()->GetVkSampler(); } @@ -372,7 +372,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* for (Uint32 n = 0; n < Resources.GetNumUBs(); ++n) { const auto& UB = Resources.GetUB(n); - auto VarType = GetShaderVariableType(Resources.GetShaderType(), UB.Name, LayoutDesc); + auto VarType = GetShaderVariableType(Resources.GetShaderType(), UB.Name, ResourceLayoutDesc); if (IsAllowedType(VarType, AllowedTypeBits)) { AddResource(s, Layout, Resources, UB); @@ -388,7 +388,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* for (Uint32 n = 0; n < Resources.GetNumSBs(); ++n) { const auto& SB = Resources.GetSB(n); - auto VarType = GetShaderVariableType(Resources.GetShaderType(), SB.Name, LayoutDesc); + auto VarType = GetShaderVariableType(Resources.GetShaderType(), SB.Name, ResourceLayoutDesc); if (IsAllowedType(VarType, AllowedTypeBits)) { AddResource(s, Layout, Resources, SB); -- cgit v1.2.3 From 0865ee3b7b5d4558e2cea100e615b8ce39b3aa91 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Fri, 1 Mar 2019 09:53:55 -0800 Subject: Fixed a number of issue with resource binding --- .../include/ShaderResourceLayoutVk.h | 5 +- .../src/GenerateMipsVkHelper.cpp | 16 +++--- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 3 ++ .../src/PipelineStateVkImpl.cpp | 4 +- .../src/ShaderResourceCacheVk.cpp | 4 +- .../src/ShaderResourceLayoutVk.cpp | 62 ++++++++++++++-------- 6 files changed, 61 insertions(+), 33 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index 5fd6f520..b9f0ea10 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -208,7 +208,10 @@ public: bool IsImmutableSamplerAssigned() const { - VERIFY_EXPR(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); + VERIFY(ImmutableSamplerAssigned == 0 || + SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, + "Immutable sampler can only be assigned to a sampled image or separate sampler"); return ImmutableSamplerAssigned != 0; } diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 305f04ef..4ae8243e 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -104,13 +104,13 @@ namespace Diligent std::array, 4> GenerateMipsVkHelper::CreatePSOs(TEXTURE_FORMAT Fmt) { - ShaderCreateInfo CSCreateAttribs; + ShaderCreateInfo CSCreateInfo; std::array, 4> PSOs; - CSCreateAttribs.Source = g_GenerateMipsCSSource; - CSCreateAttribs.EntryPoint = "main"; - CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; - CSCreateAttribs.Desc.ShaderType = SHADER_TYPE_COMPUTE; + CSCreateInfo.Source = g_GenerateMipsCSSource; + CSCreateInfo.EntryPoint = "main"; + CSCreateInfo.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; + CSCreateInfo.Desc.ShaderType = SHADER_TYPE_COMPUTE; const auto& FmtAttribs = GetTextureFormatAttribs(Fmt); bool IsGamma = FmtAttribs.ComponentType == COMPONENT_TYPE_UNORM_SRGB; @@ -125,7 +125,7 @@ namespace Diligent Macros.AddShaderMacro("IMG_FORMAT", GlFmt.data()); Macros.Finalize(); - CSCreateAttribs.Macros = Macros; + CSCreateInfo.Macros = Macros; std::stringstream name_ss; name_ss << "Generate mips " << GlFmt.data(); @@ -138,10 +138,10 @@ namespace Diligent default: UNEXPECTED("Unexpected value"); } auto name = name_ss.str(); - CSCreateAttribs.Desc.Name = name.c_str(); + CSCreateInfo.Desc.Name = name.c_str(); RefCntAutoPtr pCS; - m_DeviceVkImpl.CreateShader(CSCreateAttribs, &pCS); + m_DeviceVkImpl.CreateShader(CSCreateInfo, &pCS); PipelineStateDesc PSODesc; PSODesc.IsComputePipeline = true; PSODesc.Name = name.c_str(); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 7ce29a6f..ef7fd8ec 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -373,6 +373,9 @@ void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResA Uint32& OffsetInCache, std::vector& SPIRV) { + VERIFY( (ResAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + ResAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) || vkStaticSampler == VK_NULL_HANDLE, + "Immutable sampler should only be specified for combined image samplers or separate samplers"); m_LayoutMgr.AllocateResourceSlot(ResAttribs, VariableType,vkStaticSampler, ShaderType, DescriptorSet, Binding, OffsetInCache); SPIRV[ResAttribs.BindingDecorationOffset] = Binding; SPIRV[ResAttribs.DescriptorSetDecorationOffset] = DescriptorSet; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 548441a7..fe05a3bd 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -663,8 +663,9 @@ void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& Re for (Uint32 s = 0; s < m_NumShaders; ++s) { const auto& StaticResLayout = GetStaticShaderResLayout(s); + const auto& StaticResCache = GetStaticResCache(s); #ifdef DEVELOPMENT - if (!StaticResLayout.dvpVerifyBindings(ResourceCache)) + 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 " @@ -673,7 +674,6 @@ void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& Re "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } #endif - const auto& StaticResCache = GetStaticResCache(s); const auto& ShaderResourceLayouts = GetShaderResLayout(s); ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, ResourceCache); } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 98d4e424..85f835f8 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -324,6 +324,8 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetImageDescriptorWriteIn VkDescriptorImageInfo DescrImgInfo; DescrImgInfo.sampler = VK_NULL_HANDLE; + VERIFY(Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || !IsImmutableSampler, + "Immutable sampler can't be assigned to separarate image or storage image"); if (Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage && !IsImmutableSampler) { // Immutable samplers are permanently bound into the set layout; later binding a sampler @@ -340,7 +342,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetImageDescriptorWriteIn #ifdef DEVELOPMENT else { - LOG_ERROR_MESSAGE("No sampler assigned to texture view '", pTexViewVk->GetDesc().Name, "'"); + LOG_ERROR_MESSAGE("No sampler is assigned to texture view '", pTexViewVk->GetDesc().Name, "'"); } #endif } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index abd606b4..5b3578ba 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -44,7 +44,7 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, const SPIRVShaderResourceAttribs& Attribs, const char* SamplerSuffix) { - if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage) { SamplerSuffix = nullptr; } @@ -55,6 +55,7 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, } else { + UNEXPECTED("Immutable sampler can only be assigned to a sampled image or separate sampler"); return -1; } @@ -182,6 +183,14 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr= 0); } ); @@ -227,7 +236,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* const auto& VarDesc = ResourceLayoutDesc.Variables[v]; if (VarDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { - LOG_WARNING_MESSAGE("No allowed shader stages specified for variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), "."); + LOG_WARNING_MESSAGE("No allowed shader stages are specified for variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), "."); + continue; } for(Uint32 s=0; s < NumShaders && !VariableFound; ++s) @@ -253,7 +263,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[sam]; if (StSamDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { - LOG_WARNING_MESSAGE("No allowed shader stages specified for static sampler '", StSamDesc.SamplerOrTextureName, "."); + LOG_WARNING_MESSAGE("No allowed shader stages are specified for static sampler '", StSamDesc.SamplerOrTextureName, "."); + continue; } bool SamplerFound = false; @@ -333,17 +344,22 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* SamplerInd = ResLayout.FindAssignedSampler(Attribs, CurrResInd[ShaderInd][VarType], VarType); } - Int32 SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, ResourceLayoutDesc, Attribs, Resources.GetCombinedSamplerSuffix()); VkSampler vkImmutableSampler = VK_NULL_HANDLE; - if (SrcImmutableSamplerInd >= 0) + if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) { - auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++); - VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized!"); - const auto& ImmutableSamplerDesc = ResourceLayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; - pRenderDevice->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); - vkImmutableSampler = ImmutableSampler.RawPtr()->GetVkSampler(); + // Only search for the immutable sampler for combined image samplers and separate samplers + Int32 SrcImmutableSamplerInd = FindImmutableSampler(ShaderType, ResourceLayoutDesc, Attribs, Resources.GetCombinedSamplerSuffix()); + if (SrcImmutableSamplerInd >= 0) + { + auto& ImmutableSampler = ResLayout.GetImmutableSampler(CurrImmutableSamplerInd[ShaderInd]++); + VERIFY(!ImmutableSampler, "Immutable sampler has already been initialized!"); + const auto& ImmutableSamplerDesc = ResourceLayoutDesc.StaticSamplers[SrcImmutableSamplerInd].Desc; + pRenderDevice->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler); + vkImmutableSampler = ImmutableSampler.RawPtr()->GetVkSampler(); + } } - + auto& ShaderSPIRV = SPIRVs[ShaderInd]; PipelineLayout.AllocateResourceSlot(Attribs, VarType, vkImmutableSampler, Resources.GetShaderType(), DescriptorSet, Binding, CacheOffset, ShaderSPIRV); VERIFY(DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", DescriptorSet, ") excceeds max representable value"); @@ -693,7 +709,7 @@ void ShaderResourceLayoutVk::VkResource::CacheImage(IDeviceObject* { if(pTexViewVk->GetSampler() == nullptr) { - LOG_RESOURCE_BINDING_ERROR("resource", pTexView, SpirvAttribs.GetPrintName(ArrayInd), ParentResLayout.GetShaderName(), "No sampler assigned to texture view '", pTexViewVk->GetDesc().Name, "'"); + LOG_RESOURCE_BINDING_ERROR("resource", pTexView, SpirvAttribs.GetPrintName(ArrayInd), ParentResLayout.GetShaderName(), "No sampler is assigned to texture view '", pTexViewVk->GetDesc().Name, "'"); } } #endif @@ -712,15 +728,19 @@ void ShaderResourceLayoutVk::VkResource::CacheImage(IDeviceObject* VERIFY_EXPR(!IsImmutableSamplerAssigned()); auto* pSampler = pTexViewVk->GetSampler(); const auto& SamplerAttribs = ParentResLayout.GetResource(GetVariableType(), SamplerInd); - if (pSampler != nullptr) + VERIFY_EXPR(SamplerAttribs.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler); + if (!SamplerAttribs.IsImmutableSamplerAssigned()) { - CacheSampler(SamplerAttribs, pSampler); - } - else - { - LOG_ERROR_MESSAGE( "Failed to bind sampler to sampler variable '", SamplerAttribs.SpirvAttribs.Name, - "' assigned to separate image '", SpirvAttribs.GetPrintName(ArrayInd), "' in shader '", - ParentResLayout.GetShaderName(), "': no sampler is set in texture view '", pTexViewVk->GetDesc().Name, '\''); \ + if (pSampler != nullptr) + { + CacheSampler(SamplerAttribs, pSampler); + } + else + { + LOG_ERROR_MESSAGE( "Failed to bind sampler to sampler variable '", SamplerAttribs.SpirvAttribs.Name, + "' assigned to separate image '", SpirvAttribs.GetPrintName(ArrayInd), "' in shader '", + ParentResLayout.GetShaderName(), "': no sampler is set in texture view '", pTexViewVk->GetDesc().Name, '\''); \ + } } } } -- cgit v1.2.3 From 604f72b4a00ca67b0b17d52ea31ddce5c746a29b Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Fri, 1 Mar 2019 20:52:29 -0800 Subject: Minor update --- 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 5b3578ba..bc6c0a54 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -263,7 +263,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[sam]; if (StSamDesc.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 static sampler '", StSamDesc.SamplerOrTextureName, "'."); continue; } -- cgit v1.2.3 From a643ee949f206c51d76432410e164f4f9810cbb8 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 12:53:29 -0800 Subject: Some minor changes to ShaderResourceCacheVk --- .../include/ShaderResourceCacheVk.h | 15 +++++++------ .../src/ShaderResourceCacheVk.cpp | 26 +++++++++++----------- 2 files changed, 21 insertions(+), 20 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h index d9d1c07f..21f97b04 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h @@ -83,7 +83,7 @@ public: ~ShaderResourceCacheVk(); static size_t GetRequiredMemorySize(Uint32 NumSets, Uint32 SetSizes[]); - void InitializeSets(IMemoryAllocator &MemAllocator, Uint32 NumSets, Uint32 SetSizes[]); + void InitializeSets(IMemoryAllocator& MemAllocator, Uint32 NumSets, Uint32 SetSizes[]); void InitializeResources(Uint32 Set, Uint32 Offset, Uint32 ArraySize, SPIRVShaderResourceAttribs::ResourceType Type); // sizeof(Resource) == 16 (x64, msvc, Release) @@ -93,13 +93,14 @@ public: Type(_Type) {} - Resource(const Resource&) = delete; - Resource(Resource&&) = delete; + Resource (const Resource&) = delete; + Resource (Resource&&) = delete; Resource& operator = (const Resource&) = delete; Resource& operator = (Resource&&) = delete; - const SPIRVShaderResourceAttribs::ResourceType Type; - RefCntAutoPtr pObject; +/* 0 */ const SPIRVShaderResourceAttribs::ResourceType Type; +/*1-7*/ // Unused +/* 8 */ RefCntAutoPtr pObject; VkDescriptorBufferInfo GetUniformBufferDescriptorWriteInfo () const; VkDescriptorBufferInfo GetStorageBufferDescriptorWriteInfo () const; @@ -117,8 +118,8 @@ public: m_pResources (pResources) {} - DescriptorSet(const DescriptorSet&) = delete; - DescriptorSet(DescriptorSet&&) = delete; + DescriptorSet (const DescriptorSet&) = delete; + DescriptorSet (DescriptorSet&&) = delete; DescriptorSet& operator = (const DescriptorSet&) = delete; DescriptorSet& operator = (DescriptorSet&&) = delete; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 85f835f8..47d098f9 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -38,7 +38,7 @@ namespace Diligent size_t ShaderResourceCacheVk::GetRequiredMemorySize(Uint32 NumSets, Uint32 SetSizes[]) { Uint32 TotalResources = 0; - for(Uint32 t=0; t < NumSets; ++t) + for (Uint32 t=0; t < NumSets; ++t) TotalResources += SetSizes[t]; auto MemorySize = NumSets * sizeof(DescriptorSet) + TotalResources * sizeof(Resource); return MemorySize; @@ -60,15 +60,15 @@ void ShaderResourceCacheVk::InitializeSets(IMemoryAllocator& MemAllocator, Uint3 m_pAllocator = &MemAllocator; m_NumSets = NumSets; m_TotalResources = 0; - for(Uint32 t=0; t < NumSets; ++t) + for (Uint32 t=0; t < NumSets; ++t) m_TotalResources += SetSizes[t]; auto MemorySize = NumSets * sizeof(DescriptorSet) + m_TotalResources * sizeof(Resource); VERIFY_EXPR(MemorySize == GetRequiredMemorySize(NumSets, SetSizes)); if (MemorySize > 0) { m_pMemory = ALLOCATE( *m_pAllocator, "Memory for shader resource cache data", MemorySize); - auto *pSets = reinterpret_cast(m_pMemory); - auto *pCurrResPtr = reinterpret_cast(pSets + m_NumSets); + auto* pSets = reinterpret_cast(m_pMemory); + auto* pCurrResPtr = reinterpret_cast(pSets + m_NumSets); for (Uint32 t = 0; t < NumSets; ++t) { new(&GetDescriptorSet(t)) DescriptorSet(SetSizes[t], SetSizes[t] > 0 ? pCurrResPtr : nullptr); @@ -80,7 +80,7 @@ void ShaderResourceCacheVk::InitializeSets(IMemoryAllocator& MemAllocator, Uint3 void ShaderResourceCacheVk::InitializeResources(Uint32 Set, Uint32 Offset, Uint32 ArraySize, SPIRVShaderResourceAttribs::ResourceType Type) { - auto &DescrSet = GetDescriptorSet(Set); + auto& DescrSet = GetDescriptorSet(Set); for (Uint32 res = 0; res < ArraySize; ++res) new(&DescrSet.GetResource(Offset + res)) Resource{Type}; } @@ -89,8 +89,8 @@ ShaderResourceCacheVk::~ShaderResourceCacheVk() { if (m_pMemory) { - auto *pResources = GetFirstResourcePtr(); - for(Uint32 res=0; res < m_TotalResources; ++res) + auto* pResources = GetFirstResourcePtr(); + for (Uint32 res=0; res < m_TotalResources; ++res) pResources[res].~Resource(); for (Uint32 t = 0; t < m_NumSets; ++t) GetDescriptorSet(t).~DescriptorSet(); @@ -282,7 +282,7 @@ VkDescriptorBufferInfo ShaderResourceCacheVk::Resource::GetUniformBufferDescript // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the offset member // of each element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment (13.2.4) DescrBuffInfo.offset = 0; - DescrBuffInfo.range = pBuffVk->GetDesc().uiSizeInBytes; + DescrBuffInfo.range = pBuffVk->GetDesc().uiSizeInBytes; return DescrBuffInfo; } @@ -330,7 +330,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetImageDescriptorWriteIn { // Immutable samplers are permanently bound into the set layout; later binding a sampler // into an immutable sampler slot in a descriptor set is not allowed (13.2.1) - auto *pSamplerVk = ValidatedCast(pTexViewVk->GetSampler()); + auto* pSamplerVk = ValidatedCast(pTexViewVk->GetSampler()); if (pSamplerVk != nullptr) { // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, @@ -386,8 +386,8 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetSamplerDescriptorWrite auto* pSamplerVk = pObject.RawPtr(); VkDescriptorImageInfo DescrImgInfo; // For VK_DESCRIPTOR_TYPE_SAMPLER, only the sample member of each element of VkWriteDescriptorSet::pImageInfo is accessed (13.2.4) - DescrImgInfo.sampler = pSamplerVk->GetVkSampler(); - DescrImgInfo.imageView = VK_NULL_HANDLE; + DescrImgInfo.sampler = pSamplerVk->GetVkSampler(); + DescrImgInfo.imageView = VK_NULL_HANDLE; DescrImgInfo.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; return DescrImgInfo; } @@ -406,11 +406,11 @@ Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(DeviceContextVkImpl *pCtxV // In each descriptor set, all uniform buffers for every shader stage come first, // followed by all storage buffers for every shader stage, followed by all other resources Uint32 OffsetInd = 0; - for(Uint32 set=0; set < m_NumSets; ++set) + for (Uint32 set=0; set < m_NumSets; ++set) { const auto& DescrSet = GetDescriptorSet(set); Uint32 res = 0; - while(res < DescrSet.GetSize()) + while (res < DescrSet.GetSize()) { const auto& Res = DescrSet.GetResource(res); if (Res.Type != SPIRVShaderResourceAttribs::ResourceType::UniformBuffer) -- cgit v1.2.3 From 876034c5e736200d471057b8cf555ded566345fa Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 13:33:32 -0800 Subject: Updated ShaderVariableVk: not creating variables for immutable samplers + code cleanup --- .../include/ShaderVariableVk.h | 14 ++-- .../GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 83 ++++++++++++---------- 2 files changed, 51 insertions(+), 46 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h index 5f7a0628..bb555881 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h @@ -30,7 +30,7 @@ // * ShaderVariableManagerVk keeps list of variables of specific types // * Every ShaderVariableVkImpl references VkResource from ShaderResourceLayoutVk // * ShaderVariableManagerVk keeps pointer to ShaderResourceCacheVk -// * ShaderVariableManagerVk is used by ShaderVkImpl to manage static resources and by +// * ShaderVariableManagerVk is used by PipelineStateVkImpl to manage static resources and by // ShaderResourceBindingVkImpl to manage mutable and dynamic resources // // __________________________ __________________________________________________________________________ @@ -83,7 +83,7 @@ public: ShaderVariableVkImpl* GetVariable(const Char* Name); ShaderVariableVkImpl* GetVariable(Uint32 Index); - void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags); + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, @@ -98,10 +98,10 @@ private: Uint32 GetVariableIndex(const ShaderVariableVkImpl& Variable); IObject& m_Owner; - // Variable mgr is owned by either Shader object (in which case m_pResourceLayout points to - // static resource layout owned by the same shader object), or by SRB object (in which case + // Variable mgr is owned by either Pipeline state object (in which case m_pResourceLayout points to + // static resource layout owned by the same PSO object), or by SRB object (in which case // m_pResourceLayout points to corresponding layout in pipeline state). Since SRB keeps strong - // reference to PSO, the layout is guaranteed be alive while SRB is alive + // reference to PSO, the layout is guaranteed to be alive while SRB is alive const ShaderResourceLayoutVk* m_pResourceLayout= nullptr; ShaderResourceCacheVk* m_pResourceCache = nullptr; @@ -147,7 +147,7 @@ public: return m_ParentManager.m_Owner.Release(); } - void QueryInterface(const INTERFACE_ID &IID, IObject **ppInterface)override final + void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final { if (ppInterface == nullptr) return; @@ -165,7 +165,7 @@ public: return m_Resource.GetVariableType(); } - virtual void Set(IDeviceObject *pObject)override final + virtual void Set(IDeviceObject* pObject)override final { VERIFY_EXPR(m_ParentManager.m_pResourceCache != nullptr); m_Resource.BindResource(pObject, 0, *m_ParentManager.m_pResourceCache); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index 22acaf5c..6698dd53 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -29,42 +29,43 @@ namespace Diligent { -size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, +size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - Uint32& NumVariables) + Uint32 NumAllowedTypes, + Uint32& NumVariables) { NumVariables = 0; - Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const bool UsingSeparateSamplers = Layout.IsUsingSeparateSamplers(); + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { if (IsAllowedType(VarType, AllowedTypeBits)) { auto NumResources = Layout.GetResourceCount(VarType); - if (Layout.IsUsingSeparateSamplers()) - NumVariables += NumResources; - else + for (Uint32 r=0; r < NumResources; ++r) { - // When using HLSL-style combined image samplers, we need to skip separate samplers - for( Uint32 r=0; r < NumResources; ++r ) - { - const auto& SrcRes = Layout.GetResource(VarType, r); - if (SrcRes.SpirvAttribs.Type != SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) - ++NumVariables; - } + const auto& SrcRes = Layout.GetResource(VarType, r); + + // When using HLSL-style combined image samplers, we need to skip separate samplers. + // Also always skip immutable separate samplers. + if (SrcRes.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && + (!UsingSeparateSamplers || SrcRes.IsImmutableSamplerAssigned()) ) + continue; + + ++NumVariables; } } } - return NumVariables*sizeof(ShaderVariableVkImpl); + return NumVariables * sizeof(ShaderVariableVkImpl); } // Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes -void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout, - IMemoryAllocator& Allocator, +void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache) + Uint32 NumAllowedTypes, + ShaderResourceCacheVk& ResourceCache) { m_pResourceLayout = &SrcLayout; m_pResourceCache = &ResourceCache; @@ -79,23 +80,26 @@ void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout if(m_NumVariables == 0) return; - auto *pRawMem = ALLOCATE(Allocator, "Raw memory buffer for shader variables", MemSize); + auto* pRawMem = ALLOCATE(Allocator, "Raw memory buffer for shader variables", MemSize); m_pVariables = reinterpret_cast(pRawMem); Uint32 VarInd = 0; - for(SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) + const bool UsingSeparateSamplers = SrcLayout.IsUsingSeparateSamplers(); + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { if (!IsAllowedType(VarType, AllowedTypeBits)) continue; Uint32 NumResources = SrcLayout.GetResourceCount(VarType); - for( Uint32 r=0; r < NumResources; ++r ) + for (Uint32 r=0; r < NumResources; ++r) { const auto& SrcRes = SrcLayout.GetResource(VarType, r); - if (!SrcLayout.IsUsingSeparateSamplers() && SrcRes.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) + // Skip separate samplers when using combined HLSL-style image samplers. Also always skip immutable separate samplers. + if (SrcRes.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && + (!UsingSeparateSamplers || SrcRes.IsImmutableSamplerAssigned()) ) continue; - ::new (m_pVariables + VarInd) ShaderVariableVkImpl(*this, SrcRes ); + ::new (m_pVariables + VarInd) ShaderVariableVkImpl(*this, SrcRes); ++VarInd; } } @@ -111,9 +115,9 @@ void ShaderVariableManagerVk::Destroy(IMemoryAllocator &Allocator) { VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor"); - if(m_pVariables != nullptr) + if (m_pVariables != nullptr) { - for(Uint32 v=0; v < m_NumVariables; ++v) + for (Uint32 v=0; v < m_NumVariables; ++v) m_pVariables[v].~ShaderVariableVkImpl(); Allocator.Free(m_pVariables); m_pVariables = nullptr; @@ -125,7 +129,7 @@ ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name) ShaderVariableVkImpl* pVar = nullptr; for (Uint32 v = 0; v < m_NumVariables; ++v) { - auto &Var = m_pVariables[v]; + auto& Var = m_pVariables[v]; const auto& Res = Var.m_Resource; if (strcmp(Res.SpirvAttribs.Name, Name) == 0) { @@ -168,11 +172,11 @@ Uint32 ShaderVariableManagerVk::GetVariableIndex(const ShaderVariableVkImpl& Var } } -void ShaderVariableManagerVk::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags) +void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) { VERIFY_EXPR(m_pResourceCache != nullptr); - if( !pResourceMapping ) + if (!pResourceMapping) { LOG_ERROR_MESSAGE( "Failed to bind resources: resource mapping is null" ); return; @@ -181,34 +185,35 @@ void ShaderVariableManagerVk::BindResources( IResourceMapping* pResourceMapping, if ( (Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0 ) Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL; - for(Uint32 v=0; v < m_NumVariables; ++v) + for (Uint32 v=0; v < m_NumVariables; ++v) { - auto &Var = m_pVariables[v]; + auto& Var = m_pVariables[v]; const auto& Res = Var.m_Resource; - // Skip immutable separate samplers - if (Res.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler && Res.IsImmutableSamplerAssigned()) - continue; + // There should be no immutable separate samplers + VERIFY(Res.SpirvAttribs.Type != SPIRVShaderResourceAttribs::ResourceType::SeparateSampler || !Res.IsImmutableSamplerAssigned(), + "There must be no shader resource variables for immutable separate samplers"); if ( (Flags & (1 << Res.GetVariableType())) == 0 ) continue; for (Uint32 ArrInd = 0; ArrInd < Res.SpirvAttribs.ArraySize; ++ArrInd) { - if( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, *m_pResourceCache) ) + if ( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, *m_pResourceCache) ) continue; const auto* VarName = Res.SpirvAttribs.Name; RefCntAutoPtr pObj; pResourceMapping->GetResource( VarName, &pObj, ArrInd ); - if( pObj ) + if (pObj) { Res.BindResource(pObj, ArrInd, *m_pResourceCache); } else { - if( (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, *m_pResourceCache) ) - LOG_ERROR_MESSAGE( "Unable to bind resource to shader variable '", Res.SpirvAttribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping" ); + if ( (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, *m_pResourceCache) ) + LOG_ERROR_MESSAGE( "Unable to bind resource to shader variable '", Res.SpirvAttribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping. " + "Do not use BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED flag to suppress the message if this is not an issue." ); } } } -- cgit v1.2.3 From a32b0a27713a7e5414923a7b50f31bb6830e45e8 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 14:16:17 -0800 Subject: Updated ShaderVariableVk and ShaderResourceBindingVkImpl --- .../include/DescriptorPoolManager.h | 1 + .../include/ShaderResourceBindingVkImpl.h | 5 ++- .../include/ShaderResourceCacheVk.h | 9 +++-- .../include/ShaderVariableVk.h | 29 +++++++-------- .../src/PipelineStateVkImpl.cpp | 5 +-- .../src/ShaderResourceBindingVkImpl.cpp | 43 +++++++++++----------- .../GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 35 +++++++++--------- 7 files changed, 63 insertions(+), 64 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h index 24c3e157..bcb0a919 100644 --- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h +++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h @@ -41,6 +41,7 @@ class RenderDeviceVkImpl; // This class manages descriptor set allocation. // The class destructor calls DescriptorSetAllocator::FreeDescriptorSet() that moves // the set into the release queue. +// sizeof(DescriptorSetAllocation) == 32 (x64) class DescriptorSetAllocation { public: diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h index b3933747..5719a1e4 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h @@ -48,7 +48,7 @@ public: ShaderResourceBindingVkImpl(IReferenceCounters* pRefCounters, class PipelineStateVkImpl* pPSO, bool IsPSOInternal); ~ShaderResourceBindingVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override final; virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final; @@ -66,8 +66,9 @@ public: private: - ShaderResourceCacheVk m_ShaderResourceCache; + ShaderResourceCacheVk m_ShaderResourceCache; ShaderVariableManagerVk* m_pShaderVarMgrs = nullptr; + // Shader variable manager index in m_pShaderVarMgrs[] array for every shader stage Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; bool m_bStaticResourcesInitialized = false; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h index 21f97b04..0843939f 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h @@ -109,7 +109,7 @@ public: VkDescriptorImageInfo GetSamplerDescriptorWriteInfo() const; }; - // sizeof(DescriptorSet) == 40 (x64, msvc, Release) + // sizeof(DescriptorSet) == 48 (x64, msvc, Release) class DescriptorSet { public: @@ -147,11 +147,12 @@ public: m_DescriptorSetAllocation = std::move(Allocation); } - const Uint32 m_NumResources = 0; +/* 0 */ const Uint32 m_NumResources = 0; private: - Resource* const m_pResources = nullptr; - DescriptorSetAllocation m_DescriptorSetAllocation; +/* 8 */ Resource* const m_pResources = nullptr; +/*16 */ DescriptorSetAllocation m_DescriptorSetAllocation; +/*48 */ // End of structure }; inline DescriptorSet& GetDescriptorSet(Uint32 Index) diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h index bb555881..74dac81d 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h @@ -68,17 +68,16 @@ class ShaderVariableVkImpl; class ShaderVariableManagerVk { public: - ShaderVariableManagerVk(IObject &Owner) : - m_Owner(Owner) - {} + ShaderVariableManagerVk(IObject& Owner, + const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheVk& ResourceCache); + ~ShaderVariableManagerVk(); - void Initialize(const ShaderResourceLayoutVk& Layout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache); - void Destroy(IMemoryAllocator& Allocator); + void DestroyVariables(IMemoryAllocator& Allocator); ShaderVariableVkImpl* GetVariable(const Char* Name); ShaderVariableVkImpl* GetVariable(Uint32 Index); @@ -102,8 +101,8 @@ private: // static resource layout owned by the same PSO object), or by SRB object (in which case // m_pResourceLayout points to corresponding layout in pipeline state). Since SRB keeps strong // reference to PSO, the layout is guaranteed to be alive while SRB is alive - const ShaderResourceLayoutVk* m_pResourceLayout= nullptr; - ShaderResourceCacheVk* m_pResourceCache = nullptr; + const ShaderResourceLayoutVk& m_ResourceLayout; + ShaderResourceCacheVk& m_ResourceCache; // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block // memory allocator is used. This ensures that all resources from different shader resource bindings reside in @@ -112,7 +111,7 @@ private: Uint32 m_NumVariables = 0; #ifdef _DEBUG - IMemoryAllocator* m_pDbgAllocator = nullptr; + IMemoryAllocator& m_DbgAllocator; #endif }; @@ -167,15 +166,13 @@ public: virtual void Set(IDeviceObject* pObject)override final { - VERIFY_EXPR(m_ParentManager.m_pResourceCache != nullptr); - m_Resource.BindResource(pObject, 0, *m_ParentManager.m_pResourceCache); + m_Resource.BindResource(pObject, 0, m_ParentManager.m_ResourceCache); } virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final { - VERIFY_EXPR(m_ParentManager.m_pResourceCache != nullptr); for (Uint32 Elem = 0; Elem < NumElements; ++Elem) - m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, *m_ParentManager.m_pResourceCache); + m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); } virtual Uint32 GetArraySize()const override final diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index fe05a3bd..5cb00c8a 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -176,8 +176,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk(ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources); pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, PipelineDesc.ResourceLayout, m_StaticResCaches[s]); - auto* pStaticVarMgr = new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this); - pStaticVarMgr->Initialize(*pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache); + new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache); } ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), PipelineDesc.ResourceLayout, ShaderSPIRVs.data(), m_PipelineLayout); @@ -461,7 +460,7 @@ PipelineStateVkImpl::~PipelineStateVkImpl() for (Uint32 s=0; s < m_NumShaders; ++s) { m_StaticResCaches[s].~ShaderResourceCacheVk(); - m_StaticVarsMgrs[s].Destroy(GetRawAllocator()); + m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator()); m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); } RawAllocator.Free(m_ShaderResourceLayouts); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 3077a5dd..e7f0ac89 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -21,7 +21,6 @@ * of the possibility of such damages. */ -#include #include "pch.h" #include "ShaderResourceBindingVkImpl.h" #include "PipelineStateVkImpl.h" @@ -31,8 +30,8 @@ namespace Diligent { -ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl( IReferenceCounters* pRefCounters, PipelineStateVkImpl* pPSO, bool IsPSOInternal) : - TBase( pRefCounters, pPSO, IsPSOInternal ), +ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pRefCounters, PipelineStateVkImpl* pPSO, bool IsPSOInternal) : + TBase (pRefCounters, pPSO, IsPSOInternal), m_ShaderResourceCache(ShaderResourceCacheVk::DbgCacheContentType::SRBResources) { auto* ppShaders = pPSO->GetShaders(); @@ -44,30 +43,27 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl( IReferenceCounters* pR auto& ResourceCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); pPSO->GetPipelineLayout().InitResourceCache(pRenderDeviceVkImpl, m_ShaderResourceCache, ResourceCacheDataAllocator, pPSO->GetDesc().Name); - auto *pVarMgrsRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", m_NumShaders * sizeof(ShaderVariableManagerVk)); + auto* pVarMgrsRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", m_NumShaders * sizeof(ShaderVariableManagerVk)); m_pShaderVarMgrs = reinterpret_cast(pVarMgrsRawMem); for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto *pShader = ppShaders[s]; + auto* pShader = ppShaders[s]; auto ShaderType = pShader->GetDesc().ShaderType; auto ShaderInd = GetShaderTypeIndex(ShaderType); - - auto &VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + m_ResourceLayoutIndex[ShaderInd] = static_cast(s); + + auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); - const auto &SrcLayout = pPSO->GetShaderResLayout(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 - new (m_pShaderVarMgrs + s) ShaderVariableManagerVk(*this); - // Initialize vars manager to reference mutable and dynamic variables // Note that the cache has space for all variable types - std::array VarTypes = {{SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}}; - m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes.data(), static_cast(VarTypes.size()), m_ShaderResourceCache); - - m_ResourceLayoutIndex[ShaderInd] = static_cast(s); + 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); } } @@ -76,8 +72,8 @@ ShaderResourceBindingVkImpl::~ShaderResourceBindingVkImpl() PipelineStateVkImpl* pPSO = ValidatedCast(m_pPSO); for(Uint32 s = 0; s < m_NumShaders; ++s) { - auto &VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); - m_pShaderVarMgrs[s].Destroy(VarDataAllocator); + auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + m_pShaderVarMgrs[s].DestroyVariables(VarDataAllocator); m_pShaderVarMgrs[s].~ShaderVariableManagerVk(); } @@ -101,13 +97,14 @@ void ShaderResourceBindingVkImpl::BindResources(Uint32 ShaderFlags, IResourceMap } } -IShaderResourceVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, const char *Name) +IShaderResourceVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType, const char* Name) { auto ShaderInd = GetShaderTypeIndex(ShaderType); auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; if (ResLayoutInd < 0) { - LOG_WARNING_MESSAGE("Unable to find mutable/dynamic variable '", Name, "': shader stage ", GetShaderTypeLiteralName(ShaderType), " is inactive"); + LOG_WARNING_MESSAGE("Unable to find mutable/dynamic variable '", Name, "': shader stage ", GetShaderTypeLiteralName(ShaderType), + " is inactive in Pipeline State '", m_pPSO->GetDesc().Name, "'."); return nullptr; } return m_pShaderVarMgrs[ResLayoutInd].GetVariable(Name); @@ -119,7 +116,8 @@ Uint32 ShaderResourceBindingVkImpl::GetVariableCount(SHADER_TYPE ShaderType) con auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; if (ResLayoutInd < 0) { - LOG_WARNING_MESSAGE("Unable to get the number of mutable/dynamic variables: shader stage ", GetShaderTypeLiteralName(ShaderType), " is inactive"); + LOG_WARNING_MESSAGE("Unable to get the number of mutable/dynamic variables: shader stage ", GetShaderTypeLiteralName(ShaderType), + " is inactive in Pipeline State '", m_pPSO->GetDesc().Name, "'."); return 0; } return m_pShaderVarMgrs[ResLayoutInd].GetVariableCount(); @@ -131,7 +129,8 @@ IShaderResourceVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE Sh auto ResLayoutInd = m_ResourceLayoutIndex[ShaderInd]; if (ResLayoutInd < 0) { - LOG_ERROR("Unable to get mutable/dynamic variable at index ", Index, ": shader stage ", GetShaderTypeLiteralName(ShaderType), " is inactive"); + LOG_WARNING_MESSAGE("Unable to get mutable/dynamic variable at index ", Index, ": shader stage ", GetShaderTypeLiteralName(ShaderType), + " is inactive in Pipeline State '", m_pPSO->GetDesc().Name, "'."); return nullptr; } return m_pShaderVarMgrs[ResLayoutInd].GetVariable(Index); @@ -151,7 +150,9 @@ void ShaderResourceBindingVkImpl::InitializeStaticResources(const IPipelineState } else { - DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB"); + DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state '", pPipelineState->GetDesc().Name, "' " + "is not compatible with the pipeline state '", m_pPSO->GetDesc().Name, "' this SRB was created from and cannot be " + "used to initialize static resources."); } auto* pPSOVK = ValidatedCast(pPipelineState); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index 6698dd53..d005dc26 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -61,18 +61,19 @@ size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayout } // Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes -void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache) -{ - m_pResourceLayout = &SrcLayout; - m_pResourceCache = &ResourceCache; +ShaderVariableManagerVk::ShaderVariableManagerVk(IObject& Owner, + const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheVk& ResourceCache) : + m_Owner(Owner), + m_ResourceLayout(SrcLayout), + m_ResourceCache(ResourceCache) #ifdef _DEBUG - m_pDbgAllocator = &Allocator; + , m_DbgAllocator(Allocator) #endif - +{ const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); VERIFY_EXPR(m_NumVariables == 0); auto MemSize = GetRequiredMemorySize(SrcLayout, AllowedVarTypes, NumAllowedTypes, m_NumVariables); @@ -108,12 +109,12 @@ void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& ShaderVariableManagerVk::~ShaderVariableManagerVk() { - VERIFY(m_pVariables == nullptr, "Destroy() has not been called"); + VERIFY(m_pVariables == nullptr, "DestroyVariables() has not been called"); } -void ShaderVariableManagerVk::Destroy(IMemoryAllocator &Allocator) +void ShaderVariableManagerVk::DestroyVariables(IMemoryAllocator& Allocator) { - VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor"); + VERIFY(&m_DbgAllocator == &Allocator, "Incosistent alloctor"); if (m_pVariables != nullptr) { @@ -174,8 +175,6 @@ Uint32 ShaderVariableManagerVk::GetVariableIndex(const ShaderVariableVkImpl& Var void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) { - VERIFY_EXPR(m_pResourceCache != nullptr); - if (!pResourceMapping) { LOG_ERROR_MESSAGE( "Failed to bind resources: resource mapping is null" ); @@ -199,7 +198,7 @@ void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, for (Uint32 ArrInd = 0; ArrInd < Res.SpirvAttribs.ArraySize; ++ArrInd) { - if ( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, *m_pResourceCache) ) + if ( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, m_ResourceCache) ) continue; const auto* VarName = Res.SpirvAttribs.Name; @@ -207,11 +206,11 @@ void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, pResourceMapping->GetResource( VarName, &pObj, ArrInd ); if (pObj) { - Res.BindResource(pObj, ArrInd, *m_pResourceCache); + Res.BindResource(pObj, ArrInd, m_ResourceCache); } else { - if ( (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, *m_pResourceCache) ) + if ( (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, m_ResourceCache) ) LOG_ERROR_MESSAGE( "Unable to bind resource to shader variable '", Res.SpirvAttribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping. " "Do not use BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED flag to suppress the message if this is not an issue." ); } -- cgit v1.2.3 From abb107753cc44317a2793884c25f90c732bc9b52 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 14:38:36 -0800 Subject: Some cosmetic updates to PipelineStateVkImpl & ShaderVkImpl --- .../include/PipelineStateVkImpl.h | 10 ++--- .../GraphicsEngineVulkan/include/ShaderVkImpl.h | 2 +- .../src/PipelineStateVkImpl.cpp | 51 +++++++++++----------- .../src/ShaderResourceBindingVkImpl.cpp | 2 +- 4 files changed, 33 insertions(+), 32 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index 07b0f414..d03066fe 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -53,7 +53,7 @@ class PipelineStateVkImpl final : public PipelineStateBase; - PipelineStateVkImpl( IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc &PipelineDesc ); + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc); ~PipelineStateVkImpl(); virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; @@ -62,9 +62,9 @@ public: virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; - virtual VkRenderPass GetVkRenderPass()const override final{return m_RenderPass;} + virtual VkRenderPass GetVkRenderPass()const override final { return m_RenderPass; } - virtual VkPipeline GetVkPipeline()const override final { return m_Pipeline; } + virtual VkPipeline GetVkPipeline() const override final { return m_Pipeline; } virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags)override final; @@ -143,8 +143,8 @@ private: PipelineLayout m_PipelineLayout; Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; - bool m_HasStaticResources = false; - bool m_HasNonStaticResources = false; + bool m_HasStaticResources = false; + bool m_HasNonStaticResources = false; }; } diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index c646820c..041c7011 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -44,7 +44,7 @@ class ShaderVkImpl final : public ShaderBase public: using TShaderBase = ShaderBase; - ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreateInfo &CreationAttribs); + ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreateInfo& CreationAttribs); ~ShaderVkImpl(); IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderVk, TShaderBase); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 5cb00c8a..f28b2068 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -49,11 +49,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( // Prepare render pass create info (7.1) VkRenderPassCreateInfo RenderPassCI = {}; - RenderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - RenderPassCI.pNext = nullptr; - RenderPassCI.flags = 0; // reserved for future use + RenderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + RenderPassCI.pNext = nullptr; + RenderPassCI.flags = 0; // reserved for future use RenderPassCI.attachmentCount = (DSVFormat != TEX_FORMAT_UNKNOWN ? 1 : 0) + NumRenderTargets; - uint32_t AttachmentInd = 0; + + uint32_t AttachmentInd = 0; VkSampleCountFlagBits SampleCountFlags = static_cast(1 << (SampleCount - 1)); VkAttachmentReference* pDepthAttachmentReference = nullptr; if (DSVFormat != TEX_FORMAT_UNKNOWN) @@ -86,12 +87,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( { auto& ColorAttachment = Attachments[AttachmentInd]; - ColorAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - ColorAttachment.format = TexFormatToVkFormat(RTVFormats[rt]); + ColorAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT + ColorAttachment.format = TexFormatToVkFormat(RTVFormats[rt]); ColorAttachment.samples = SampleCountFlags; - ColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area - // will be preserved. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_READ_BIT. + ColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area + // will be preserved. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_READ_BIT. ColorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render // area are written to memory. For attachments with a color format, // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. @@ -102,15 +103,15 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( auto& ColorAttachmentRef = AttachmentReferences[AttachmentInd]; ColorAttachmentRef.attachment = AttachmentInd; - ColorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + ColorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } - RenderPassCI.pAttachments = Attachments.data(); - RenderPassCI.subpassCount = 1; - RenderPassCI.pSubpasses = &SubpassDesc; + RenderPassCI.pAttachments = Attachments.data(); + RenderPassCI.subpassCount = 1; + RenderPassCI.pSubpasses = &SubpassDesc; RenderPassCI.dependencyCount = 0; // the number of dependencies between pairs of subpasses, or zero indicating no dependencies. - RenderPassCI.pDependencies = nullptr; // an array of dependencyCount number of VkSubpassDependency structures describing - // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. + RenderPassCI.pDependencies = nullptr; // an array of dependencyCount number of VkSubpassDependency structures describing + // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. SubpassDesc.flags = 0; // All bits for this type are defined by extensions @@ -166,7 +167,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(LogicalDevice); auto* pShaderVk = GetShader(s); ShaderResources[s] = pShaderVk->GetShaderResources(); - ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); + ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); const auto ShaderType = pShaderVk->GetDesc().ShaderType; const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); @@ -187,9 +188,9 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters std::array ShaderVariableDataSizes = {}; for (Uint32 s = 0; s < m_NumShaders; ++s) { - std::array AllowedVarTypes = { {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; + 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.data(), static_cast(AllowedVarTypes.size()), UnusedNumVars); + ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(m_ShaderResourceLayouts[s], AllowedVarTypes, _countof(AllowedVarTypes), UnusedNumVars); } Uint32 NumSets = 0; @@ -246,7 +247,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters m_ShaderModules[s] = LogicalDevice.CreateShaderModule(ShaderModuleCI, pShaderVk->GetDesc().Name); StageCI.module = m_ShaderModules[s]; - StageCI.pName = pShaderVk->GetEntryPoint(); + StageCI.pName = pShaderVk->GetEntryPoint(); StageCI.pSpecializationInfo = nullptr; } @@ -265,9 +266,9 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters 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.basePipelineIndex = 0; // an index into the pCreateInfos parameter to use as a pipeline to derive from - PipelineCI.stage = ShaderStages[0]; + PipelineCI.stage = ShaderStages[0]; PipelineCI.layout = m_PipelineLayout.GetVkPipelineLayout(); m_Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, m_Desc.Name); @@ -294,11 +295,11 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters #endif PipelineCI.stageCount = m_NumShaders; - PipelineCI.pStages = ShaderStages.data(); - PipelineCI.layout = m_PipelineLayout.GetVkPipelineLayout(); + PipelineCI.pStages = ShaderStages.data(); + PipelineCI.layout = m_PipelineLayout.GetVkPipelineLayout(); VkPipelineVertexInputStateCreateInfo VertexInputStateCI = {}; - std::array BindingDescriptions; + std::array BindingDescriptions; std::array AttributeDescription; InputLayoutDesc_To_VkVertexInputStateCI(GraphicsPipeline.InputLayout, VertexInputStateCI, BindingDescriptions, AttributeDescription); PipelineCI.pVertexInputState = &VertexInputStateCI; @@ -487,7 +488,7 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState *pPSO)const if (pPSO == this) return true; - const PipelineStateVkImpl *pPSOVk = ValidatedCast(pPSO); + const PipelineStateVkImpl* pPSOVk = ValidatedCast(pPSO); if (m_ShaderResourceLayoutHash != pPSOVk->m_ShaderResourceLayoutHash) return false; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index e7f0ac89..54b09c69 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -62,7 +62,7 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pRe // 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 - SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + 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); } } -- cgit v1.2.3 From 11c5047df020d1dc814a3e252e0bd981e1b12218 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 19:32:10 -0800 Subject: Added debug checks to verify that all resources in ShaderResouceCacheVk have been initialized --- .../GraphicsEngineVulkan/include/PipelineLayout.h | 4 +-- .../include/ShaderResourceCacheVk.h | 6 ++++- .../include/ShaderResourceLayoutVk.h | 17 +++++++------ .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 16 ++++++------ .../src/ShaderResourceBindingVkImpl.cpp | 4 +++ .../src/ShaderResourceCacheVk.cpp | 26 +++++++++++++++++-- .../src/ShaderResourceLayoutVk.cpp | 29 +++++++++++++--------- 7 files changed, 69 insertions(+), 33 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index a875cb90..a5aec374 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -59,7 +59,7 @@ public: void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkStaticSampler, + VkSampler vkImmutableSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, Uint32& Binding, @@ -189,7 +189,7 @@ private: void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkStaticSampler, + VkSampler vkImmutableSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, Uint32& Binding, diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h index 0843939f..1bedbcac 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h @@ -49,6 +49,7 @@ // Descriptor set for static and mutable resources is assigned during cache initialization // Descriptor set for dynamic resources is assigned at every draw call +#include #include "DescriptorPoolManager.h" #include "SPIRVShaderResources.h" @@ -171,6 +172,7 @@ public: #ifdef _DEBUG // Only for debug purposes: indicates what types of resources are stored in the cache DbgCacheContentType DbgGetContentType()const{return m_DbgContentType;} + void DbgVerifyResourceInitialization()const; #endif template @@ -192,7 +194,9 @@ private: #ifdef _DEBUG // Only for debug purposes: indicates what types of resources are stored in the cache - const DbgCacheContentType m_DbgContentType; + const DbgCacheContentType m_DbgContentType; + // Debug array that stores flags indicating if resources in the cache have been initialized + std::vector> m_DbgInitializedResources; #endif }; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index b9f0ea10..a33f9841 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -107,7 +107,7 @@ namespace Diligent { /// Diligent::ShaderResourceLayoutVk class -// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) - TODO: verify +// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) class ShaderResourceLayoutVk { public: @@ -338,15 +338,16 @@ private: return reinterpret_cast(ResourceMemoryEnd)[n]; } - const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; - std::unique_ptr > m_ResourceBuffer; +/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; +/* 8 */ std::unique_ptr > m_ResourceBuffer; - // We must use shared_ptr to reference ShaderResources instance, because - // there may be multiple objects referencing the same set of resources - std::shared_ptr m_pResources; + // 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; - std::array m_NumResources = {}; - Uint32 m_NumImmutableSamplers = 0; +/*40 */ std::array m_NumResources = {}; +/*48 */ Uint32 m_NumImmutableSamplers = 0; +/*56*/ // End of class }; } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index ef7fd8ec..d8383418 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -316,7 +316,7 @@ size_t PipelineLayout::DescriptorSetLayoutManager::GetHash()const void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkStaticSampler, + VkSampler vkImmutableSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, Uint32& Binding, @@ -336,15 +336,15 @@ void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIR VkBinding.descriptorCount = ResAttribs.ArraySize; // There are no limitations on what combinations of stages can use a descriptor binding (13.2.1) VkBinding.stageFlags = ShaderTypeToVkShaderStageFlagBit(ShaderType); - if (vkStaticSampler != VK_NULL_HANDLE) + if (vkImmutableSampler != VK_NULL_HANDLE) { // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and // descriptorCount is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a valid pointer // to an array of descriptorCount valid VkSampler handles (13.2.1) - auto *pStaticSamplers = reinterpret_cast(ALLOCATE(m_MemAllocator, "Memory buffer for immutable samplers", sizeof(VkSampler) * VkBinding.descriptorCount)); + auto *pImmutableSamplers = reinterpret_cast(ALLOCATE(m_MemAllocator, "Memory buffer for immutable samplers", sizeof(VkSampler) * VkBinding.descriptorCount)); for(uint32_t s=0; s < VkBinding.descriptorCount; ++s) - pStaticSamplers[s] = vkStaticSampler; - VkBinding.pImmutableSamplers = pStaticSamplers; + pImmutableSamplers[s] = vkImmutableSampler; + VkBinding.pImmutableSamplers = pImmutableSamplers; } else VkBinding.pImmutableSamplers = nullptr; @@ -366,7 +366,7 @@ void PipelineLayout::Release(RenderDeviceVkImpl *pDeviceVkImpl, Uint64 CommandQu void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkStaticSampler, + VkSampler vkImmutableSampler, SHADER_TYPE ShaderType, Uint32& DescriptorSet, // Output parameter Uint32& Binding, // Output parameter @@ -374,9 +374,9 @@ void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResA std::vector& SPIRV) { VERIFY( (ResAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || - ResAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) || vkStaticSampler == VK_NULL_HANDLE, + ResAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) || vkImmutableSampler == VK_NULL_HANDLE, "Immutable sampler should only be specified for combined image samplers or separate samplers"); - m_LayoutMgr.AllocateResourceSlot(ResAttribs, VariableType,vkStaticSampler, ShaderType, DescriptorSet, Binding, OffsetInCache); + m_LayoutMgr.AllocateResourceSlot(ResAttribs, VariableType ,vkImmutableSampler, ShaderType, DescriptorSet, Binding, OffsetInCache); SPIRV[ResAttribs.BindingDecorationOffset] = Binding; SPIRV[ResAttribs.DescriptorSetDecorationOffset] = DescriptorSet; } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 54b09c69..0193bb55 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -65,6 +65,10 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pRe 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); } +#ifdef _DEBUG + m_ShaderResourceCache.DbgVerifyResourceInitialization(); +#endif + } ShaderResourceBindingVkImpl::~ShaderResourceBindingVkImpl() diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 47d098f9..2bfa922e 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -57,13 +57,16 @@ void ShaderResourceCacheVk::InitializeSets(IMemoryAllocator& MemAllocator, Uint3 // Ns = m_NumSets VERIFY(m_pAllocator == nullptr && m_pMemory == nullptr, "Cache already initialized"); - m_pAllocator = &MemAllocator; - m_NumSets = NumSets; + m_pAllocator = &MemAllocator; + m_NumSets = NumSets; m_TotalResources = 0; for (Uint32 t=0; t < NumSets; ++t) m_TotalResources += SetSizes[t]; auto MemorySize = NumSets * sizeof(DescriptorSet) + m_TotalResources * sizeof(Resource); VERIFY_EXPR(MemorySize == GetRequiredMemorySize(NumSets, SetSizes)); +#ifdef _DEBUG + m_DbgInitializedResources.resize(m_NumSets); +#endif if (MemorySize > 0) { m_pMemory = ALLOCATE( *m_pAllocator, "Memory for shader resource cache data", MemorySize); @@ -73,6 +76,9 @@ void ShaderResourceCacheVk::InitializeSets(IMemoryAllocator& MemAllocator, Uint3 { new(&GetDescriptorSet(t)) DescriptorSet(SetSizes[t], SetSizes[t] > 0 ? pCurrResPtr : nullptr); pCurrResPtr += SetSizes[t]; +#ifdef _DEBUG + m_DbgInitializedResources[t].resize(SetSizes[t]); +#endif } VERIFY_EXPR((char*)pCurrResPtr == (char*)m_pMemory + MemorySize); } @@ -82,9 +88,25 @@ void ShaderResourceCacheVk::InitializeResources(Uint32 Set, Uint32 Offset, Uint3 { auto& DescrSet = GetDescriptorSet(Set); for (Uint32 res = 0; res < ArraySize; ++res) + { new(&DescrSet.GetResource(Offset + res)) Resource{Type}; +#ifdef _DEBUG + m_DbgInitializedResources[Set][Offset + res] = true; +#endif + } } +#ifdef _DEBUG +void ShaderResourceCacheVk::DbgVerifyResourceInitialization()const +{ + for (const auto &SetFlags : m_DbgInitializedResources) + { + for (auto ResInitialized : SetFlags) + VERIFY(ResInitialized, "Not all resources in the cache have been initialized. This is a bug."); + } +} +#endif + ShaderResourceCacheVk::~ShaderResourceCacheVk() { if (m_pMemory) diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index bc6c0a54..3e1aba42 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -93,9 +93,8 @@ static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE ShaderResourceLayoutVk::~ShaderResourceLayoutVk() { - auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); for (Uint32 r=0; r < GetTotalResourceCount(); ++r) - Resources[r].~VkResource(); + GetResource(r).~VkResource(); for(Uint32 s=0; s < m_NumImmutableSamplers; ++s) GetImmutableSampler(s).~ImmutableSamplerPtrType(); @@ -116,14 +115,17 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrGetShaderType(); const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); - // Count number of resources to allocate all needed memory + // Count the number of resources to allocate all needed memory m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) { auto VarType = GetShaderVariableType(ShaderType, ResAttribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (IsAllowedType(VarType, AllowedTypeBits)) { - VERIFY( Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds max representable value"); + // For immutable separate samplers we still allocate VkResource instances, but they are never used + // or exposed to the app + + VERIFY( Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds maximum representable value"); ++m_NumResources[VarType]; } } @@ -134,11 +136,11 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr::max()}, "Total number of resources exceeds Uint16 max representable value" ); + VERIFY(TotalResources <= Uint32{std::numeric_limits::max()}, "Total number of resources exceeds Uint16 maximum representable value" ); m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES] = static_cast(TotalResources); m_NumImmutableSamplers = 0; - for(Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + for (Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) { const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; if ((StSamDesc.ShaderStages & ShaderType) != 0) @@ -152,7 +154,7 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr >(pRawMem, Allocator); - for(Uint32 s=0; s < m_NumImmutableSamplers; ++s) + for (Uint32 s=0; s < m_NumImmutableSamplers; ++s) { // We need to initialize immutable samplers auto& UninitializedImmutableSampler = GetImmutableSampler(s); @@ -189,10 +191,10 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr::max(), "Descriptor set (", DescriptorSet, ") excceeds max representable value"); - VERIFY(Binding <= std::numeric_limits::max(), "Binding (", Binding, ") excceeds max representable value"); + 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"); #ifdef _DEBUG // Verify that bindings and cache offsets monotonically increase in every descriptor set @@ -904,7 +909,7 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou auto DstOffset = DstRes.CacheOffset + ArrInd; IDeviceObject* pCachedResource = DstResourceCache.GetDescriptorSet(DstRes.DescriptorSet).GetResource(DstOffset).pObject; - if(pCachedResource != pObject) + if (pCachedResource != pObject) { VERIFY(pCachedResource == nullptr, "Static resource has already been initialized, and the resource to be assigned from the shader does not match previously assigned resource"); DstRes.BindResource(pObject, ArrInd, DstResourceCache); -- cgit v1.2.3 From e4683811e233259f49552b77f1f037c475551815 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 21:33:11 -0800 Subject: A bunch of updates to ShaderResourceLayoutVk --- .../include/ShaderResourceLayoutVk.h | 6 +- .../src/ShaderResourceLayoutVk.cpp | 171 +++++++++++---------- 2 files changed, 98 insertions(+), 79 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index a33f9841..729997f9 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -263,6 +263,9 @@ public: #ifdef DEVELOPMENT bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache)const; + static void dvpVerifyResourceLayoutDesc(Uint32 NumShaders, + const std::shared_ptr pShaderResources[], + const PipelineResourceLayoutDesc& ResourceLayoutDesc); #endif Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType)const @@ -324,7 +327,8 @@ private: IMemoryAllocator& Allocator, const PipelineResourceLayoutDesc& ResourceLayoutDesc, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes); + Uint32 NumAllowedTypes, + bool AllocateImmutableSamplers); Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, Uint32 CurrResourceCount, diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 3e1aba42..48d117f6 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -104,7 +104,8 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrGetShaderType(); - const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + const auto ShaderType = m_pResources->GetShaderType(); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); // Count the number of resources to allocate all needed memory m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) @@ -122,10 +123,9 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr::max()}, "Number of resources exceeds maximum representable value"); + VERIFY( Uint32{m_NumResources[VarType]} + 1 <= Uint32{std::numeric_limits::max()}, "Number of resources exceeds Uint16 maximum representable value"); ++m_NumResources[VarType]; } } @@ -140,11 +140,14 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptr(TotalResources); m_NumImmutableSamplers = 0; - for (Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + if (AllocateImmutableSamplers) { - const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; - if ((StSamDesc.ShaderStages & ShaderType) != 0) - ++m_NumImmutableSamplers; + for (Uint32 s=0; s < ResourceLayoutDesc.NumStaticSamplers; ++s) + { + const auto& StSamDesc = ResourceLayoutDesc.StaticSamplers[s]; + if ((StSamDesc.ShaderStages & ShaderType) != 0) + ++m_NumImmutableSamplers; + } } size_t MemSize = TotalResources * sizeof(VkResource) + m_NumImmutableSamplers * sizeof(ImmutableSamplerPtrType); @@ -168,15 +171,18 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr 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); + const auto ShaderType = m_pResources->GetShaderType(); + const auto* CombinedSamplerSuffix = m_pResources->GetCombinedSamplerSuffix(); m_pResources->ProcessResources( [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) @@ -191,8 +197,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr= 0); @@ -214,7 +219,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr(VarType + 1)) { - VERIFY(CurrResInd[VarType] == m_NumResources[VarType], "Not all resources are initialized, which will cause a crash when dtor is called"); + VERIFY(CurrResInd[VarType] == m_NumResources[VarType], "Not all resources have been initialized, which will cause a crash when dtor is called"); } #endif @@ -225,27 +230,22 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptr pShaderResources[], - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - std::vector SPIRVs[], - class PipelineLayout& PipelineLayout) -{ #ifdef DEVELOPMENT +void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(Uint32 NumShaders, + const std::shared_ptr pShaderResources[], + const PipelineResourceLayoutDesc& ResourceLayoutDesc) +{ for (Uint32 v = 0; v < ResourceLayoutDesc.NumVariables; ++v) { - bool VariableFound = false; const auto& VarDesc = ResourceLayoutDesc.Variables[v]; if (VarDesc.ShaderStages == SHADER_TYPE_UNKNOWN) { - LOG_WARNING_MESSAGE("No allowed shader stages are specified for variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), "."); + LOG_WARNING_MESSAGE("No allowed shader stages are specified for ", GetShaderVariableTypeLiteralName(VarDesc.Type), " variable '", VarDesc.Name, "'."); continue; } - for(Uint32 s=0; s < NumShaders && !VariableFound; ++s) + bool VariableFound = false; + for (Uint32 s=0; s < NumShaders && !VariableFound; ++s) { const auto& Resources = *pShaderResources[s]; if ( (VarDesc.ShaderStages & Resources.GetShaderType()) != 0 ) @@ -259,7 +259,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } if (!VariableFound) { - LOG_WARNING_MESSAGE("Variable '", VarDesc.Name, "' labeled as ", GetShaderVariableTypeLiteralName(VarDesc.Type), " is not found in any of the specified shader stages: ", GetShaderStagesString(VarDesc.ShaderStages)); + LOG_WARNING_MESSAGE(GetShaderVariableTypeLiteralName(VarDesc.Type), " variable '", VarDesc.Name, "' is not found in any of the designated shader stages (", GetShaderStagesString(VarDesc.ShaderStages), ")"); } } @@ -273,7 +273,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* } bool SamplerFound = false; - for(Uint32 s=0; s < NumShaders && !SamplerFound; ++s) + for (Uint32 s=0; s < NumShaders && !SamplerFound; ++s) { const auto& Resources = *pShaderResources[s]; if ( (StSamDesc.ShaderStages & Resources.GetShaderType()) == 0 ) @@ -289,27 +289,38 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* if (!SamplerFound) { - // Check if static sampler is assigned to a separate sampler or - // separate image depending on whether HLSL-style combined samplers - // are used + // Check if static 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(); ++i) + for (Uint32 i = 0; i < Resources.GetNumSepSmplrs() && !SamplerFound; ++i) { const auto& SepSmpl = Resources.GetSepSmplr(i); SamplerFound = StreqSuff(SepSmpl.Name, StSamDesc.SamplerOrTextureName, CombinedSamplerSuffix); - if (SamplerFound) - break; } } } if (!SamplerFound) { - LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, "' is not found in any of the specified shader stages: ", GetShaderStagesString(StSamDesc.ShaderStages)); + LOG_WARNING_MESSAGE("Static sampler '", StSamDesc.SamplerOrTextureName, "' is not found in any of the designated shader stages (", GetShaderStagesString(StSamDesc.ShaderStages), ")"); } } +} #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) +{ +#ifdef DEVELOPMENT + dvpVerifyResourceLayoutDesc(NumShaders, pShaderResources, ResourceLayoutDesc); +#endif const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes = nullptr; const Uint32 NumAllowedTypes = 0; @@ -317,7 +328,8 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* for (Uint32 s=0; s < NumShaders; ++s) { - Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes); + constexpr bool AllocateImmutableSamplers = true; + Layouts[s].AllocateMemory(std::move(pShaderResources[s]), LayoutDataAllocator, ResourceLayoutDesc, AllowedVarTypes, NumAllowedTypes, AllocateImmutableSamplers); } VERIFY_EXPR(NumShaders <= MaxShadersInPipeline); @@ -332,15 +344,15 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* const SPIRVShaderResources& Resources, const SPIRVShaderResourceAttribs& Attribs) { - Uint32 Binding = 0; - Uint32 DescriptorSet = 0; - Uint32 CacheOffset = 0; const auto ShaderType = Resources.GetShaderType(); const SHADER_RESOURCE_VARIABLE_TYPE VarType = GetShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix()); if (!IsAllowedType(VarType, AllowedTypeBits)) return; - Uint32 SamplerInd = VkResource::InvalidSamplerInd; + Uint32 Binding = 0; + Uint32 DescriptorSet = 0; + Uint32 CacheOffset = 0; + Uint32 SamplerInd = VkResource::InvalidSamplerInd; if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage) { @@ -467,7 +479,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* 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)) { - VERIFY(CurrResInd[s][VarType] == Layout.m_NumResources[VarType], "Not all resources are initialized, which will cause a crash when dtor is called"); + VERIFY(CurrResInd[s][VarType] == Layout.m_NumResources[VarType], "Not all resources have been initialized, which will cause a crash when dtor is called. This is a bug."); } } #endif @@ -524,17 +536,17 @@ void ShaderResourceLayoutVk::VkResource::UpdateDescriptorHandle(VkDescriptorSet VERIFY_EXPR(vkDescrSet != VK_NULL_HANDLE); VkWriteDescriptorSet WriteDescrSet; - WriteDescrSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - WriteDescrSet.pNext = nullptr; - WriteDescrSet.dstSet = vkDescrSet; - WriteDescrSet.dstBinding = Binding; - WriteDescrSet.dstArrayElement = ArrayElement; - WriteDescrSet.descriptorCount = 1; + WriteDescrSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + WriteDescrSet.pNext = nullptr; + WriteDescrSet.dstSet = vkDescrSet; + WriteDescrSet.dstBinding = Binding; + WriteDescrSet.dstArrayElement = ArrayElement; + WriteDescrSet.descriptorCount = 1; // descriptorType must be the same type as that specified in VkDescriptorSetLayoutBinding for dstSet at dstBinding. // The type of the descriptor also controls which array the descriptors are taken from. (13.2.4) - WriteDescrSet.descriptorType = PipelineLayout::GetVkDescriptorType(SpirvAttribs); - WriteDescrSet.pImageInfo = pImageInfo; - WriteDescrSet.pBufferInfo = pBufferInfo; + WriteDescrSet.descriptorType = PipelineLayout::GetVkDescriptorType(SpirvAttribs); + WriteDescrSet.pImageInfo = pImageInfo; + WriteDescrSet.pBufferInfo = pBufferInfo; WriteDescrSet.pTexelBufferView = pTexelBufferView; ParentResLayout.m_LogicalDevice.UpdateDescriptorSets(1, &WriteDescrSet, 0, nullptr); @@ -729,13 +741,14 @@ void ShaderResourceLayoutVk::VkResource::CacheImage(IDeviceObject* if (SamplerInd != InvalidSamplerInd) { - VERIFY_EXPR(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); - VERIFY_EXPR(!IsImmutableSamplerAssigned()); - auto* pSampler = pTexViewVk->GetSampler(); + VERIFY(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage, + "Only separate images can be assigned separate samplers when using HLSL-style combined samplers."); + VERIFY(!IsImmutableSamplerAssigned(), "Separate image can't be assigned an immutable sampler."); const auto& SamplerAttribs = ParentResLayout.GetResource(GetVariableType(), SamplerInd); VERIFY_EXPR(SamplerAttribs.SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler); if (!SamplerAttribs.IsImmutableSamplerAssigned()) { + auto* pSampler = pTexViewVk->GetSampler(); if (pSampler != nullptr) { CacheSampler(SamplerAttribs, pSampler); @@ -757,6 +770,7 @@ void ShaderResourceLayoutVk::VkResource::CacheSeparateSampler(IDeviceObject* Uint32 ArrayInd)const { VERIFY(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, "Separate sampler resource is expected"); + VERIFY(!IsImmutableSamplerAssigned(), "This separate sampler is assigned an immutable sampler"); if (UpdateCachedResource(DstRes, ArrayInd, pSampler, IID_Sampler, "sampler")) { @@ -821,6 +835,7 @@ void ShaderResourceLayoutVk::VkResource::BindResource(IDeviceObject* pObj, Uint3 CacheImage(pObj, DstRes, vkDescrSet, ArrayIndex, [&](const VkResource& SeparateSampler, ISampler* pSampler) { + VERIFY(!SeparateSampler.IsImmutableSamplerAssigned(), "This separate sampler is assigned an immutable sampler '", SeparateSampler.SpirvAttribs.Name, "'"); VERIFY_EXPR(SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateImage); DEV_CHECK_ERR(SeparateSampler.SpirvAttribs.ArraySize == 1 || SeparateSampler.SpirvAttribs.ArraySize == SpirvAttribs.ArraySize, "Array size (", SeparateSampler.SpirvAttribs.ArraySize,") of separate sampler variable '", @@ -865,10 +880,10 @@ bool ShaderResourceLayoutVk::VkResource::IsBound(Uint32 ArrayIndex, const Shader if (DescriptorSet < ResourceCache.GetNumDescriptorSets()) { - auto& Set = ResourceCache.GetDescriptorSet(DescriptorSet); + const auto& Set = ResourceCache.GetDescriptorSet(DescriptorSet); if (CacheOffset + ArrayIndex < Set.GetSize()) { - auto& CachedRes = Set.GetResource(CacheOffset + ArrayIndex); + const auto& CachedRes = Set.GetResource(CacheOffset + ArrayIndex); return CachedRes.pObject != nullptr; } } @@ -889,7 +904,7 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou for (Uint32 r=0; r < NumStaticResources; ++r) { // Get resource attributes - auto& DstRes = GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); + const auto& DstRes = GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); const auto& SrcRes = SrcLayout.GetResource(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); VERIFY(SrcRes.Binding == SrcRes.SpirvAttribs.Type, "Unexpected binding"); VERIFY(SrcRes.SpirvAttribs.ArraySize == DstRes.SpirvAttribs.ArraySize, "Inconsistent array size"); @@ -984,14 +999,14 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& VERIFY_EXPR(vkDynamicDescriptorSet != VK_NULL_HANDLE); #ifdef _DEBUG - static constexpr size_t ImgUpdateBatchSize = 4; - static constexpr size_t BuffUpdateBatchSize = 2; - static constexpr size_t TexelBuffUpdateBatchSize = 2; + static constexpr size_t ImgUpdateBatchSize = 4; + static constexpr size_t BuffUpdateBatchSize = 2; + static constexpr size_t TexelBuffUpdateBatchSize = 2; static constexpr size_t WriteDescriptorSetBatchSize = 2; #else - static constexpr size_t ImgUpdateBatchSize = 128; - static constexpr size_t BuffUpdateBatchSize = 64; - static constexpr size_t TexelBuffUpdateBatchSize = 32; + static constexpr size_t ImgUpdateBatchSize = 128; + static constexpr size_t BuffUpdateBatchSize = 64; + static constexpr size_t TexelBuffUpdateBatchSize = 32; static constexpr size_t WriteDescriptorSetBatchSize = 32; #endif @@ -1002,9 +1017,9 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& std::array WriteDescrSetArr; Uint32 ResNum = 0, ArrElem = 0; - auto DescrImgIt = DescrImgInfoArr.begin(); - auto DescrBuffIt = DescrBuffInfoArr.begin(); - auto BuffViewIt = DescrBuffViewArr.begin(); + auto DescrImgIt = DescrImgInfoArr.begin(); + auto DescrBuffIt = DescrBuffInfoArr.begin(); + auto BuffViewIt = DescrBuffViewArr.begin(); auto WriteDescrSetIt = WriteDescrSetArr.begin(); #ifdef _DEBUG @@ -1034,11 +1049,11 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& WriteDescrSetIt->descriptorType = PipelineLayout::GetVkDescriptorType(Res.SpirvAttribs); // For every resource type, try to batch as many descriptor updates as we can - switch(Res.SpirvAttribs.Type) + switch (Res.SpirvAttribs.Type) { case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer: WriteDescrSetIt->pBufferInfo = &(*DescrBuffIt); - while(ArrElem < Res.SpirvAttribs.ArraySize && DescrBuffIt != DescrBuffInfoArr.end()) + while (ArrElem < Res.SpirvAttribs.ArraySize && DescrBuffIt != DescrBuffInfoArr.end()) { const auto& CachedRes = SetResources.GetResource(Res.CacheOffset + ArrElem); *DescrBuffIt = CachedRes.GetUniformBufferDescriptorWriteInfo(); @@ -1049,7 +1064,7 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& case SPIRVShaderResourceAttribs::ResourceType::StorageBuffer: WriteDescrSetIt->pBufferInfo = &(*DescrBuffIt); - while(ArrElem < Res.SpirvAttribs.ArraySize && DescrBuffIt != DescrBuffInfoArr.end()) + while (ArrElem < Res.SpirvAttribs.ArraySize && DescrBuffIt != DescrBuffInfoArr.end()) { const auto& CachedRes = SetResources.GetResource(Res.CacheOffset + ArrElem); *DescrBuffIt = CachedRes.GetStorageBufferDescriptorWriteInfo(); @@ -1061,7 +1076,7 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& case SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer: case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer: WriteDescrSetIt->pTexelBufferView = &(*BuffViewIt); - while(ArrElem < Res.SpirvAttribs.ArraySize && BuffViewIt != DescrBuffViewArr.end()) + while (ArrElem < Res.SpirvAttribs.ArraySize && BuffViewIt != DescrBuffViewArr.end()) { const auto& CachedRes = SetResources.GetResource(Res.CacheOffset + ArrElem); *BuffViewIt = CachedRes.GetBufferViewWriteInfo(); @@ -1114,13 +1129,13 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& } WriteDescrSetIt->descriptorCount = ArrElem - WriteDescrSetIt->dstArrayElement; - if(ArrElem == Res.SpirvAttribs.ArraySize) + if (ArrElem == Res.SpirvAttribs.ArraySize) { ArrElem = 0; ++ResNum; } // descriptorCount == 0 for immutable separate samplers - if(WriteDescrSetIt->descriptorCount > 0) + if (WriteDescrSetIt->descriptorCount > 0) ++WriteDescrSetIt; // If we ran out of space in any of the arrays or if we processed all resources, @@ -1132,7 +1147,7 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& WriteDescrSetIt == WriteDescrSetArr.end()) { auto DescrWriteCount = static_cast(std::distance(WriteDescrSetArr.begin(), WriteDescrSetIt)); - if(DescrWriteCount > 0) + if (DescrWriteCount > 0) m_LogicalDevice.UpdateDescriptorSets(DescrWriteCount, WriteDescrSetArr.data(), 0, nullptr); DescrImgIt = DescrImgInfoArr.begin(); -- cgit v1.2.3 From fcb0730b65c01f8e7f3a7d8085141b960100fec7 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 2 Mar 2019 23:59:59 -0800 Subject: Minor update to ShaderResourceLayoutVk --- .../GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 48d117f6..9f212fd4 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -69,10 +69,10 @@ static Int32 FindImmutableSampler(SHADER_TYPE ShaderType, return -1; } -static SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType(SHADER_TYPE ShaderType, - const SPIRVShaderResourceAttribs& Attribs, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const char* CombinedSamplerSuffix) +static SHADER_RESOURCE_VARIABLE_TYPE FindShaderVariableType(SHADER_TYPE ShaderType, + const SPIRVShaderResourceAttribs& Attribs, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const char* CombinedSamplerSuffix) { if (Attribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler) { @@ -120,7 +120,7 @@ void ShaderResourceLayoutVk::AllocateMemory(std::shared_ptrProcessResources( [&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) { - auto VarType = GetShaderVariableType(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 @@ -187,7 +187,7 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(std::shared_ptrProcessResources( [&](const SPIRVShaderResourceAttribs& Attribs, Uint32) { - auto VarType = GetShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); + auto VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, CombinedSamplerSuffix); if (!IsAllowedType(VarType, AllowedTypeBits)) return; @@ -345,7 +345,7 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* const SPIRVShaderResourceAttribs& Attribs) { const auto ShaderType = Resources.GetShaderType(); - const SHADER_RESOURCE_VARIABLE_TYPE VarType = GetShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix()); + const SHADER_RESOURCE_VARIABLE_TYPE VarType = FindShaderVariableType(ShaderType, Attribs, ResourceLayoutDesc, Resources.GetCombinedSamplerSuffix()); if (!IsAllowedType(VarType, AllowedTypeBits)) return; -- cgit v1.2.3 From 04330a7e1d0198e721fd8d10379ab751b6826a35 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 3 Mar 2019 13:16:34 -0800 Subject: Cleaned up QueryInterface declarations --- Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h | 2 +- Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h | 2 +- Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h | 2 +- Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h index a5669f6c..3c649ab1 100644 --- a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h @@ -48,7 +48,7 @@ public: uint32_t QueueFamilyIndex); ~CommandQueueVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; // Returns the fence value that will be signaled next time virtual Uint64 GetNextFenceValue()override final { return m_NextFenceValue; } diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h index aada3ab5..d309c638 100644 --- a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h @@ -49,7 +49,7 @@ public: void* pNativeWndHandle); ~SwapChainVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; virtual void Present(Uint32 SyncInterval)override final; virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; diff --git a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h index 650829e1..8989c245 100644 --- a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h @@ -50,7 +50,7 @@ public: bool bIsDefaultView); ~TextureViewVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; VkImageView GetVulkanImageView()const override final{return m_ImageView;} diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h index 4d040a0e..4d19fe91 100644 --- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h @@ -62,7 +62,7 @@ public: ~TextureVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; virtual VkImage GetVkImage()const override final{ return m_VulkanImage; } virtual void* GetNativeHandle()override final -- cgit v1.2.3 From a407080d12bc2b762f84131cfa62c1f3069c4a09 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 3 Mar 2019 13:18:12 -0800 Subject: Minor change to DeviceContextVkImpl.h --- Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index bc8c42ac..84e8bfdd 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -68,7 +68,7 @@ public: std::shared_ptr GenerateMipsHelper); ~DeviceContextVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID& IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; virtual void SetPipelineState(IPipelineState* pPipelineState)override final; -- cgit v1.2.3 From b21f54c63be0e81a26f505ea019049d4f663bf3b Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 3 Mar 2019 14:01:58 -0800 Subject: Implemented shader resource reflectio API in Vk backend --- .../GraphicsEngineVulkan/include/ShaderVkImpl.h | 11 ++--- Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 57 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index 041c7011..03fc2189 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -49,17 +49,12 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderVk, TShaderBase); - virtual Uint32 GetResourceCount()const + virtual Uint32 GetResourceCount()const override final { - UNSUPPORTED("Not yet implemented"); - return 0; + return m_pShaderResources->GetTotalResources(); } - virtual const ShaderResourceDesc* GetResources()const - { - UNSUPPORTED("Not yet implemented"); - return nullptr; - } + virtual ShaderResourceDesc GetResource(Uint32 Index)const override final; virtual const std::vector& GetSPIRV()const override final { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index 3cf4c3f0..9ec51af6 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -129,4 +129,61 @@ ShaderVkImpl::~ShaderVkImpl() { } +ShaderResourceDesc ShaderVkImpl::GetResource(Uint32 Index)const +{ + auto ResCount = GetResourceCount(); + DEV_CHECK_ERR(Index < ResCount, "Resource index (", Index, ") is out of range"); + ShaderResourceDesc ResourceDesc; + if (Index < ResCount) + { + const auto& SPIRVResource = m_pShaderResources->GetResource(Index); + ResourceDesc.Name = SPIRVResource.Name; + ResourceDesc.ArraySize = SPIRVResource.ArraySize; + static_assert(SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes == 9, "Please update switch statement below"); + switch (SPIRVResource.Type) + { + case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; + break; + + case SPIRVShaderResourceAttribs::ResourceType::StorageBuffer: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::StorageImage: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_UAV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::SampledImage: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::AtomicCounter: + LOG_WARNING_MESSAGE("There is no appropriate shader resource type for atomic counter resource '", SPIRVResource.Name, "'"); + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::SeparateImage: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_TEXTURE_SRV; + break; + + case SPIRVShaderResourceAttribs::ResourceType::SeparateSampler: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; + break; + + default: + UNEXPECTED("Unknown SPIRV resource type"); + } + } + return ResourceDesc; +} + } -- cgit v1.2.3 From f551f6353eaf4efe9b7f26d48822b96ebb0706a0 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 4 Mar 2019 22:38:04 -0800 Subject: Updated D3D11, D3D12, and Vk EngineFactory headers & structures --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 4 +- .../include/DeviceContextVkImpl.h | 2 +- .../include/RenderDeviceVkImpl.h | 12 +- .../interface/EngineFactoryVk.h | 128 +++++++ .../interface/RenderDeviceFactoryVk.h | 128 ------- .../src/DeviceContextVkImpl.cpp | 20 +- .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 372 +++++++++++++++++++++ .../src/RenderDeviceFactoryVk.cpp | 372 --------------------- .../src/RenderDeviceVkImpl.cpp | 52 +-- .../src/ShaderResourceLayoutVk.cpp | 2 +- .../GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp | 8 +- 11 files changed, 550 insertions(+), 550 deletions(-) create mode 100644 Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h delete mode 100644 Graphics/GraphicsEngineVulkan/interface/RenderDeviceFactoryVk.h create mode 100644 Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp delete mode 100644 Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index 18887fea..be94ed10 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -51,10 +51,10 @@ set(INTERFACE interface/BufferViewVk.h interface/CommandQueueVk.h interface/DeviceContextVk.h + interface/EngineFactoryVk.h interface/FenceVk.h interface/PipelineStateVk.h interface/RenderDeviceVk.h - interface/RenderDeviceFactoryVk.h interface/SamplerVk.h interface/ShaderVk.h interface/ShaderResourceBindingVk.h @@ -71,6 +71,7 @@ set(SRC src/CommandQueueVkImpl.cpp src/DescriptorPoolManager.cpp src/DeviceContextVkImpl.cpp + src/EngineFactoryVk.cpp src/FenceVkImpl.cpp src/VulkanDynamicHeap.cpp src/FramebufferCache.cpp @@ -79,7 +80,6 @@ set(SRC src/PipelineStateVkImpl.cpp src/RenderDeviceVkImpl.cpp src/RenderPassCache.cpp - src/RenderDeviceFactoryVk.cpp src/SamplerVkImpl.cpp src/ShaderVkImpl.cpp src/ShaderResourceBindingVkImpl.cpp diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 84e8bfdd..09eaa1a5 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -62,7 +62,7 @@ public: DeviceContextVkImpl(IReferenceCounters* pRefCounters, class RenderDeviceVkImpl* pDevice, bool bIsDeferred, - const EngineVkAttribs& Attribs, + const EngineVkCreateInfo& EngineCI, Uint32 ContextId, Uint32 CommandQueueId, std::shared_ptr GenerateMipsHelper); diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h index c0e2847b..167949df 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h @@ -55,11 +55,11 @@ class RenderDeviceVkImpl final : public RenderDeviceNextGenBase, ICommandQueueVk>; - RenderDeviceVkImpl( IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - const EngineVkAttribs& CreationAttribs, - size_t CommandQueueCount, - ICommandQueueVk** pCmdQueues, + RenderDeviceVkImpl( IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + const EngineVkCreateInfo& EngineCI, + size_t CommandQueueCount, + ICommandQueueVk** pCmdQueues, std::shared_ptr Instance, std::unique_ptr PhysicalDevice, std::shared_ptr LogicalDevice, @@ -134,7 +134,7 @@ private: std::unique_ptr m_PhysicalDevice; std::shared_ptr m_LogicalVkDevice; - EngineVkAttribs m_EngineAttribs; + EngineVkCreateInfo m_EngineAttribs; FramebufferCache m_FramebufferCache; RenderPassCache m_RenderPassCache; diff --git a/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h b/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h new file mode 100644 index 00000000..861f5514 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h @@ -0,0 +1,128 @@ +/* Copyright 2015-2019 Egor Yusov +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. +* +* In no event and under no legal theory, whether in tort (including negligence), +* contract, or otherwise, unless required by applicable law (such as deliberate +* and grossly negligent acts) or agreed to in writing, shall any Contributor be +* liable for any damages, including any direct, indirect, special, incidental, +* or consequential damages of any character arising as a result of this License or +* out of the use or inability to use the software (including but not limited to damages +* for loss of goodwill, work stoppage, computer failure or malfunction, or any and +* all other commercial damages or losses), even if such Contributor has been advised +* of the possibility of such damages. +*/ + +#pragma once + +/// \file +/// Declaration of functions that initialize Direct3D12-based engine implementation + +#include + +#include "../../GraphicsEngine/interface/RenderDevice.h" +#include "../../GraphicsEngine/interface/DeviceContext.h" +#include "../../GraphicsEngine/interface/SwapChain.h" + +#if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER)) + + // https://gcc.gnu.org/wiki/Visibility +# define API_QUALIFIER __attribute__((visibility("default"))) + +#elif PLATFORM_WIN32 + +# define API_QUALIFIER + +#else +# error Unsupported platform +#endif + +namespace Diligent +{ + +class IEngineFactoryVk +{ +public: + virtual void CreateDeviceAndContextsVk(const EngineVkCreateInfo& EngineCI, + IRenderDevice **ppDevice, + IDeviceContext **ppContexts, + Uint32 NumDeferredContexts) = 0; + + //virtual void AttachToVulkanDevice(void *pVkNativeDevice, + // class ICommandQueueVk *pCommandQueue, + // const EngineVkCreateInfo& EngineCI, + // IRenderDevice **ppDevice, + // IDeviceContext **ppContexts, + // Uint32 NumDeferredContexts) = 0; + + virtual void CreateSwapChainVk(IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + ISwapChain** ppSwapChain) = 0; + +}; + + +#if ENGINE_DLL && PLATFORM_WIN32 && defined(_MSC_VER) + +# define EXPLICITLY_LOAD_ENGINE_VK_DLL 1 + + typedef IEngineFactoryVk* (*GetEngineFactoryVkType)(); + + static bool LoadGraphicsEngineVk(GetEngineFactoryVkType& GetFactoryFunc) + { + GetFactoryFunc = nullptr; + std::string LibName = "GraphicsEngineVk_"; + +# if _WIN64 + LibName += "64"; +# else + LibName += "32"; +# endif + +# ifdef _DEBUG + LibName += "d"; +# else + LibName += "r"; +# endif + + LibName += ".dll"; + auto hModule = LoadLibraryA(LibName.c_str()); + if (hModule == NULL) + { + std::stringstream ss; + ss << "Failed to load " << LibName << " library.\n"; + OutputDebugStringA(ss.str().c_str()); + return false; + } + + GetFactoryFunc = reinterpret_cast(GetProcAddress(hModule, "GetEngineFactoryVk")); + if (GetFactoryFunc == NULL) + { + std::stringstream ss; + ss << "Failed to load GetEngineFactoryVk() from " << LibName << " library.\n"; + OutputDebugStringA(ss.str().c_str()); + FreeLibrary(hModule); + return false; + } + + return true; + } + +#else + + API_QUALIFIER + IEngineFactoryVk* GetEngineFactoryVk(); + +#endif + +} diff --git a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceFactoryVk.h b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceFactoryVk.h deleted file mode 100644 index b5de2664..00000000 --- a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceFactoryVk.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. -* -* In no event and under no legal theory, whether in tort (including negligence), -* contract, or otherwise, unless required by applicable law (such as deliberate -* and grossly negligent acts) or agreed to in writing, shall any Contributor be -* liable for any damages, including any direct, indirect, special, incidental, -* or consequential damages of any character arising as a result of this License or -* out of the use or inability to use the software (including but not limited to damages -* for loss of goodwill, work stoppage, computer failure or malfunction, or any and -* all other commercial damages or losses), even if such Contributor has been advised -* of the possibility of such damages. -*/ - -#pragma once - -/// \file -/// Declaration of functions that initialize Direct3D12-based engine implementation - -#include - -#include "../../GraphicsEngine/interface/RenderDevice.h" -#include "../../GraphicsEngine/interface/DeviceContext.h" -#include "../../GraphicsEngine/interface/SwapChain.h" - -#if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER)) - - // https://gcc.gnu.org/wiki/Visibility -# define API_QUALIFIER __attribute__((visibility("default"))) - -#elif PLATFORM_WIN32 - -# define API_QUALIFIER - -#else -# error Unsupported platform -#endif - -namespace Diligent -{ - -class IEngineFactoryVk -{ -public: - virtual void CreateDeviceAndContextsVk(const EngineVkAttribs& CreationAttribs, - IRenderDevice **ppDevice, - IDeviceContext **ppContexts, - Uint32 NumDeferredContexts) = 0; - - //virtual void AttachToVulkanDevice(void *pVkNativeDevice, - // class ICommandQueueVk *pCommandQueue, - // const EngineVkAttribs& EngineAttribs, - // IRenderDevice **ppDevice, - // IDeviceContext **ppContexts, - // Uint32 NumDeferredContexts) = 0; - - virtual void CreateSwapChainVk(IRenderDevice *pDevice, - IDeviceContext *pImmediateContext, - const SwapChainDesc& SwapChainDesc, - void* pNativeWndHandle, - ISwapChain **ppSwapChain) = 0; - -}; - - -#if ENGINE_DLL && PLATFORM_WIN32 && defined(_MSC_VER) - -# define EXPLICITLY_LOAD_ENGINE_VK_DLL 1 - - typedef IEngineFactoryVk* (*GetEngineFactoryVkType)(); - - static bool LoadGraphicsEngineVk(GetEngineFactoryVkType &GetFactoryFunc) - { - GetFactoryFunc = nullptr; - std::string LibName = "GraphicsEngineVk_"; - -# if _WIN64 - LibName += "64"; -# else - LibName += "32"; -# endif - -# ifdef _DEBUG - LibName += "d"; -# else - LibName += "r"; -# endif - - LibName += ".dll"; - auto hModule = LoadLibraryA(LibName.c_str()); - if (hModule == NULL) - { - std::stringstream ss; - ss << "Failed to load " << LibName << " library.\n"; - OutputDebugStringA(ss.str().c_str()); - return false; - } - - GetFactoryFunc = reinterpret_cast(GetProcAddress(hModule, "GetEngineFactoryVk")); - if (GetFactoryFunc == NULL) - { - std::stringstream ss; - ss << "Failed to load GetEngineFactoryVk() from " << LibName << " library.\n"; - OutputDebugStringA(ss.str().c_str()); - FreeLibrary(hModule); - return false; - } - - return true; - } - -#else - - API_QUALIFIER - IEngineFactoryVk* GetEngineFactoryVk(); - -#endif - -} diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 0200476d..daabca38 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -45,20 +45,20 @@ namespace Diligent return ss.str(); } - DeviceContextVkImpl::DeviceContextVkImpl( IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDeviceVkImpl, - bool bIsDeferred, - const EngineVkAttribs& Attribs, - Uint32 ContextId, - Uint32 CommandQueueId, - std::shared_ptr GenerateMipsHelper) : + DeviceContextVkImpl::DeviceContextVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVkImpl, + bool bIsDeferred, + const EngineVkCreateInfo& EngineCI, + Uint32 ContextId, + Uint32 CommandQueueId, + std::shared_ptr GenerateMipsHelper) : TDeviceContextBase { pRefCounters, pDeviceVkImpl, ContextId, CommandQueueId, - bIsDeferred ? std::numeric_limits::max() : Attribs.NumCommandsToFlushCmdBuffer, + bIsDeferred ? std::numeric_limits::max() : EngineCI.NumCommandsToFlushCmdBuffer, bIsDeferred }, m_CommandBuffer { pDeviceVkImpl->GetLogicalDevice().GetEnabledGraphicsShaderStages() }, @@ -76,13 +76,13 @@ namespace Diligent { *pDeviceVkImpl, GetContextObjectName("Upload heap", bIsDeferred, ContextId), - Attribs.UploadHeapPageSize + EngineCI.UploadHeapPageSize }, m_DynamicHeap { pDeviceVkImpl->GetDynamicMemoryManager(), GetContextObjectName("Dynamic heap", bIsDeferred, ContextId), - Attribs.DynamicHeapPageSize + EngineCI.DynamicHeapPageSize }, m_DynamicDescrSetAllocator { diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp new file mode 100644 index 00000000..acb6265a --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -0,0 +1,372 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +/// \file +/// Routines that initialize Vulkan-based engine implementation + +#include "pch.h" +#include +#include "EngineFactoryVk.h" +#include "RenderDeviceVkImpl.h" +#include "DeviceContextVkImpl.h" +#include "SwapChainVkImpl.h" +#include "EngineMemory.h" +#include "CommandQueueVkImpl.h" +#include "VulkanUtilities/VulkanInstance.h" +#include "VulkanUtilities/VulkanPhysicalDevice.h" + +namespace Diligent +{ + +/// Engine factory for Vk implementation +class EngineFactoryVkImpl : public IEngineFactoryVk +{ +public: + static EngineFactoryVkImpl* GetInstance() + { + static EngineFactoryVkImpl TheFactory; + return &TheFactory; + } + + void CreateDeviceAndContextsVk(const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts)override final; + + void AttachToVulkanDevice(std::shared_ptr Instance, + std::unique_ptr PhysicalDevice, + std::shared_ptr LogicalDevice, + size_t CommandQueueCount, + ICommandQueueVk** ppCommandQueues, + const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts);//override final; + + void CreateSwapChainVk(IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SwapChainDesc, + void* pNativeWndHandle, + ISwapChain** ppSwapChain)override final; +}; + +/// Creates render device and device contexts for Vulkan backend + +/// \param [in] EngineCI - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. The new immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to the deferred contexts are written afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts) +{ + VERIFY( ppDevice && ppContexts, "Null pointer provided" ); + if( !ppDevice || !ppContexts ) + return; + +#if 0 + for (Uint32 Type = Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; Type < Vk_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++Type) + { + auto CPUHeapAllocSize = EngineCI.CPUDescriptorHeapAllocationSize[Type]; + Uint32 MaxSize = 1 << 20; + if (CPUHeapAllocSize > 1 << 20) + { + LOG_ERROR("CPU Heap allocation size is too large (", CPUHeapAllocSize, "). Max allowed size is ", MaxSize); + return; + } + + if ((CPUHeapAllocSize % 16) != 0) + { + LOG_ERROR("CPU Heap allocation size (", CPUHeapAllocSize, ") is expected to be multiple of 16"); + return; + } + } +#endif + + SetRawAllocator(EngineCI.pRawMemAllocator); + + *ppDevice = nullptr; + memset(ppContexts, 0, sizeof(*ppContexts) * (1 + NumDeferredContexts)); + + try + { + auto Instance = VulkanUtilities::VulkanInstance::Create( + EngineCI.EnableValidation, + EngineCI.GlobalExtensionCount, + EngineCI.ppGlobalExtensionNames, + reinterpret_cast(EngineCI.pVkAllocator)); + + auto vkDevice = Instance->SelectPhysicalDevice(); + auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(vkDevice); + + // If an implementation exposes any queue family that supports graphics operations, + // at least one queue family of at least one physical device exposed by the implementation + // must support both graphics and compute operations. + + VkDeviceQueueCreateInfo QueueInfo{}; + QueueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + QueueInfo.flags = 0; // reserved for future use + // All commands that are allowed on a queue that supports transfer operations are also allowed on a + // queue that supports either graphics or compute operations.Thus, if the capabilities of a queue family + // include VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT, then reporting the VK_QUEUE_TRANSFER_BIT + // capability separately for that queue family is optional (4.1). + QueueInfo.queueFamilyIndex = PhysicalDevice->FindQueueFamily(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT); + QueueInfo.queueCount = 1; + const float defaultQueuePriority = 1.0f; // Ask for highest priority for our queue. (range [0,1]) + QueueInfo.pQueuePriorities = &defaultQueuePriority; + + VkDeviceCreateInfo DeviceCreateInfo = {}; + DeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + DeviceCreateInfo.flags = 0; // Reserved for future use + // https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#extended-functionality-device-layer-deprecation + DeviceCreateInfo.enabledLayerCount = 0; // Deprecated and ignored. + DeviceCreateInfo.ppEnabledLayerNames = nullptr; // Deprecated and ignored + DeviceCreateInfo.queueCreateInfoCount = 1; + DeviceCreateInfo.pQueueCreateInfos = &QueueInfo; + VkPhysicalDeviceFeatures DeviceFeatures = {}; + DeviceFeatures.depthBiasClamp = EngineCI.EnabledFeatures.depthBiasClamp ? VK_TRUE : VK_FALSE; + DeviceFeatures.fillModeNonSolid = EngineCI.EnabledFeatures.fillModeNonSolid ? VK_TRUE : VK_FALSE; + DeviceFeatures.depthClamp = EngineCI.EnabledFeatures.depthClamp ? VK_TRUE : VK_FALSE; + DeviceFeatures.independentBlend = EngineCI.EnabledFeatures.independentBlend ? VK_TRUE : VK_FALSE; + DeviceFeatures.samplerAnisotropy = EngineCI.EnabledFeatures.samplerAnisotropy ? VK_TRUE : VK_FALSE; + DeviceFeatures.geometryShader = EngineCI.EnabledFeatures.geometryShader ? VK_TRUE : VK_FALSE; + DeviceFeatures.tessellationShader = EngineCI.EnabledFeatures.tessellationShader ? VK_TRUE : VK_FALSE; + DeviceFeatures.dualSrcBlend = EngineCI.EnabledFeatures.dualSrcBlend ? VK_TRUE : VK_FALSE; + DeviceFeatures.multiViewport = EngineCI.EnabledFeatures.multiViewport ? VK_TRUE : VK_FALSE; + DeviceFeatures.imageCubeArray = EngineCI.EnabledFeatures.imageCubeArray ? VK_TRUE : VK_FALSE; + DeviceFeatures.textureCompressionBC = EngineCI.EnabledFeatures.textureCompressionBC ? VK_TRUE : VK_FALSE; + DeviceFeatures.vertexPipelineStoresAndAtomics = EngineCI.EnabledFeatures.vertexPipelineStoresAndAtomics ? VK_TRUE : VK_FALSE; + DeviceFeatures.fragmentStoresAndAtomics = EngineCI.EnabledFeatures.fragmentStoresAndAtomics ? VK_TRUE : VK_FALSE; + DeviceFeatures.shaderStorageImageExtendedFormats = EngineCI.EnabledFeatures.shaderStorageImageExtendedFormats ? VK_TRUE : VK_FALSE; + DeviceCreateInfo.pEnabledFeatures = &DeviceFeatures; // NULL or a pointer to a VkPhysicalDeviceFeatures structure that contains + // boolean indicators of all the features to be enabled. + + std::vector DeviceExtensions = + { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_MAINTENANCE1_EXTENSION_NAME // To allow negative viewport height + }; + DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data(); + DeviceCreateInfo.enabledExtensionCount = static_cast(DeviceExtensions.size()); + + auto vkAllocator = Instance->GetVkAllocator(); + auto vkPhysicalDevice = PhysicalDevice->GetVkDeviceHandle(); + auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(vkPhysicalDevice, DeviceCreateInfo, vkAllocator); + + RefCntAutoPtr pCmdQueueVk; + auto &RawMemAllocator = GetRawAllocator(); + pCmdQueueVk = NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(LogicalDevice, QueueInfo.queueFamilyIndex); + + std::array CommandQueues = {{pCmdQueueVk}}; + AttachToVulkanDevice(Instance, std::move(PhysicalDevice), LogicalDevice, CommandQueues.size(), CommandQueues.data(), EngineCI, ppDevice, ppContexts, NumDeferredContexts); + + FenceDesc Desc; + Desc.Name = "Command queue fence"; + // Render device owns command queue that in turn owns the fence, so it is an internal device object + bool IsDeviceInternal = true; + auto* pRenderDeviceVk = ValidatedCast(*ppDevice); + RefCntAutoPtr pFenceVk( NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal) ); + pCmdQueueVk->SetFence(std::move(pFenceVk)); + } + catch(std::runtime_error& ) + { + return; + } +} + +/// Attaches to existing Vulkan device + +/// \param [in] Instance - shared pointer to a VulkanUtilities::VulkanInstance object +/// \param [in] PhysicalDevice - pointer to the object representing physical device +/// \param [in] LogicalDevice - shared pointer to a VulkanUtilities::VulkanLogicalDevice object +/// \param [in] pCommandQueue - pointer to the implementation of command queue +/// \param [in] EngineCI - Engine creation attributes. +/// \param [out] ppDevice - Address of the memory location where pointer to +/// the created device will be written +/// \param [out] ppContexts - Address of the memory location where pointers to +/// the contexts will be written. Pointer to the immediate +/// context goes at position 0. If NumDeferredContexts > 0, +/// pointers to the deferred contexts go afterwards. +/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number +/// of deferred contexts is requested, pointers to the +/// contexts are written to ppContexts array starting +/// at position 1 +void EngineFactoryVkImpl::AttachToVulkanDevice(std::shared_ptr Instance, + std::unique_ptr PhysicalDevice, + std::shared_ptr LogicalDevice, + size_t CommandQueueCount, + ICommandQueueVk** ppCommandQueues, + const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts, + Uint32 NumDeferredContexts) +{ + VERIFY( ppCommandQueues && ppDevice && ppContexts, "Null pointer provided" ); + if(!LogicalDevice || !ppCommandQueues || !ppDevice || !ppContexts ) + return; + + *ppDevice = nullptr; + memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); + + try + { + auto &RawMemAllocator = GetRawAllocator(); + RenderDeviceVkImpl *pRenderDeviceVk( NEW_RC_OBJ(RawMemAllocator, "RenderDeviceVkImpl instance", RenderDeviceVkImpl)(RawMemAllocator, EngineCI, CommandQueueCount, ppCommandQueues, Instance, std::move(PhysicalDevice), LogicalDevice, NumDeferredContexts ) ); + pRenderDeviceVk->QueryInterface(IID_RenderDevice, reinterpret_cast(ppDevice) ); + + std::shared_ptr GenerateMipsHelper(new GenerateMipsVkHelper(*pRenderDeviceVk)); + + RefCntAutoPtr pImmediateCtxVk( NEW_RC_OBJ(RawMemAllocator, "DeviceContextVkImpl instance", DeviceContextVkImpl)(pRenderDeviceVk, false, EngineCI, 0, 0, GenerateMipsHelper) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceVk will + // keep a weak reference to the context + pImmediateCtxVk->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts) ); + pRenderDeviceVk->SetImmediateContext(pImmediateCtxVk); + + for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) + { + RefCntAutoPtr pDeferredCtxVk( NEW_RC_OBJ(RawMemAllocator, "DeviceContextVkImpl instance", DeviceContextVkImpl)(pRenderDeviceVk, true, EngineCI, 1+DeferredCtx, 0, GenerateMipsHelper) ); + // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceVk will + // keep a weak reference to the context + pDeferredCtxVk->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts + 1 + DeferredCtx) ); + pRenderDeviceVk->SetDeferredContext(DeferredCtx, pDeferredCtxVk); + } + } + catch( const std::runtime_error & ) + { + if( *ppDevice ) + { + (*ppDevice)->Release(); + *ppDevice = nullptr; + } + for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) + { + if( ppContexts[ctx] != nullptr ) + { + ppContexts[ctx]->Release(); + ppContexts[ctx] = nullptr; + } + } + + LOG_ERROR( "Failed to create device and contexts" ); + } +} + + +/// Creates a swap chain for Direct3D12-based engine implementation + +/// \param [in] pDevice - Pointer to the render device +/// \param [in] pImmediateContext - Pointer to the immediate device context +/// \param [in] SCDesc - Swap chain description +/// \param [in] pNativeWndHandle - Platform-specific native handle of the window +/// the swap chain will be associated with: +/// * On Win32 platform, this should be window handle (HWND) +/// * On Universal Windows Platform, this should be reference to the +/// core window (Windows::UI::Core::CoreWindow) +/// +/// \param [out] ppSwapChain - Address of the memory location where pointer to the new +/// swap chain will be written +void EngineFactoryVkImpl::CreateSwapChainVk(IRenderDevice* pDevice, + IDeviceContext* pImmediateContext, + const SwapChainDesc& SCDesc, + void* pNativeWndHandle, + ISwapChain** ppSwapChain) +{ + VERIFY( ppSwapChain, "Null pointer provided" ); + if( !ppSwapChain ) + return; + + *ppSwapChain = nullptr; + + try + { + auto *pDeviceVk = ValidatedCast( pDevice ); + auto *pDeviceContextVk = ValidatedCast(pImmediateContext); + auto &RawMemAllocator = GetRawAllocator(); + auto *pSwapChainVk = NEW_RC_OBJ(RawMemAllocator, "SwapChainVkImpl instance", SwapChainVkImpl)(SCDesc, pDeviceVk, pDeviceContextVk, pNativeWndHandle); + pSwapChainVk->QueryInterface( IID_SwapChain, reinterpret_cast(ppSwapChain) ); + + pDeviceContextVk->SetSwapChain(pSwapChainVk); + // Bind default render target + pDeviceContextVk->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); + // Set default viewport + pDeviceContextVk->SetViewports( 1, nullptr, 0, 0 ); + + auto NumDeferredCtx = pDeviceVk->GetNumDeferredContexts(); + for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) + { + if (auto pDeferredCtx = pDeviceVk->GetDeferredContext(ctx)) + { + auto *pDeferredCtxVk = pDeferredCtx.RawPtr(); + pDeferredCtxVk->SetSwapChain(pSwapChainVk); + // We cannot bind default render target here because + // there is no guarantee that deferred context will be used + // in this frame. It is an error to bind + // RTV of an inactive buffer in the swap chain + } + } + } + catch( const std::runtime_error & ) + { + if( *ppSwapChain ) + { + (*ppSwapChain)->Release(); + *ppSwapChain = nullptr; + } + + LOG_ERROR( "Failed to create the swap chain" ); + } +} + + +#ifdef DOXYGEN +/// Loads Direct3D12-based engine implementation and exports factory functions +/// \param [out] GetFactoryFunc - Pointer to the function that returns factory for Vk engine implementation. +/// See EngineFactoryVkImpl. +/// \remarks Depending on the configuration and platform, the function loads different dll: +/// Platform\\Configuration | Debug | Release +/// --------------------------|-------------------------------|---------------------------- +/// x86 | GraphicsEngineVk_32d.dll | GraphicsEngineVk_32r.dll +/// x64 | GraphicsEngineVk_64d.dll | GraphicsEngineVk_64r.dll +/// +void LoadGraphicsEngineVk(GetEngineFactoryVkType &GetFactoryFunc) +{ + // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO + #error This function must never be compiled; +} +#endif + +API_QUALIFIER +IEngineFactoryVk* GetEngineFactoryVk() +{ + return EngineFactoryVkImpl::GetInstance(); +} + +} diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp deleted file mode 100644 index a4ab8ae3..00000000 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -/// \file -/// Routines that initialize Vulkan-based engine implementation - -#include "pch.h" -#include -#include "RenderDeviceFactoryVk.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "SwapChainVkImpl.h" -#include "EngineMemory.h" -#include "CommandQueueVkImpl.h" -#include "VulkanUtilities/VulkanInstance.h" -#include "VulkanUtilities/VulkanPhysicalDevice.h" - -namespace Diligent -{ - -/// Engine factory for Vk implementation -class EngineFactoryVkImpl : public IEngineFactoryVk -{ -public: - static EngineFactoryVkImpl* GetInstance() - { - static EngineFactoryVkImpl TheFactory; - return &TheFactory; - } - - void CreateDeviceAndContextsVk( const EngineVkAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts)override final; - - void AttachToVulkanDevice(std::shared_ptr Instance, - std::unique_ptr PhysicalDevice, - std::shared_ptr LogicalDevice, - size_t CommandQueueCount, - ICommandQueueVk** ppCommandQueues, - const EngineVkAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts);//override final; - - void CreateSwapChainVk( IRenderDevice* pDevice, - IDeviceContext* pImmediateContext, - const SwapChainDesc& SwapChainDesc, - void* pNativeWndHandle, - ISwapChain** ppSwapChain )override final; -}; - -/// Creates render device and device contexts for Vulkan backend - -/// \param [in] CreationAttribs - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. The new immediate -/// context goes at position 0. If NumDeferredContexts > 0, -/// pointers to the deferred contexts are written afterwards. -/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number -/// of deferred contexts is requested, pointers to the -/// contexts are written to ppContexts array starting -/// at position 1 -void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts) -{ - VERIFY( ppDevice && ppContexts, "Null pointer provided" ); - if( !ppDevice || !ppContexts ) - return; - -#if 0 - for (Uint32 Type = Vk_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; Type < Vk_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++Type) - { - auto CPUHeapAllocSize = CreationAttribs.CPUDescriptorHeapAllocationSize[Type]; - Uint32 MaxSize = 1 << 20; - if (CPUHeapAllocSize > 1 << 20) - { - LOG_ERROR("CPU Heap allocation size is too large (", CPUHeapAllocSize, "). Max allowed size is ", MaxSize); - return; - } - - if ((CPUHeapAllocSize % 16) != 0) - { - LOG_ERROR("CPU Heap allocation size (", CPUHeapAllocSize, ") is expected to be multiple of 16"); - return; - } - } -#endif - - SetRawAllocator(CreationAttribs.pRawMemAllocator); - - *ppDevice = nullptr; - memset(ppContexts, 0, sizeof(*ppContexts) * (1 + NumDeferredContexts)); - - try - { - auto Instance = VulkanUtilities::VulkanInstance::Create( - CreationAttribs.EnableValidation, - CreationAttribs.GlobalExtensionCount, - CreationAttribs.ppGlobalExtensionNames, - reinterpret_cast(CreationAttribs.pVkAllocator)); - - auto vkDevice = Instance->SelectPhysicalDevice(); - auto PhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(vkDevice); - - // If an implementation exposes any queue family that supports graphics operations, - // at least one queue family of at least one physical device exposed by the implementation - // must support both graphics and compute operations. - - VkDeviceQueueCreateInfo QueueInfo{}; - QueueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - QueueInfo.flags = 0; // reserved for future use - // All commands that are allowed on a queue that supports transfer operations are also allowed on a - // queue that supports either graphics or compute operations.Thus, if the capabilities of a queue family - // include VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT, then reporting the VK_QUEUE_TRANSFER_BIT - // capability separately for that queue family is optional (4.1). - QueueInfo.queueFamilyIndex = PhysicalDevice->FindQueueFamily(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT); - QueueInfo.queueCount = 1; - const float defaultQueuePriority = 1.0f; // Ask for highest priority for our queue. (range [0,1]) - QueueInfo.pQueuePriorities = &defaultQueuePriority; - - VkDeviceCreateInfo DeviceCreateInfo = {}; - DeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - DeviceCreateInfo.flags = 0; // Reserved for future use - // https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#extended-functionality-device-layer-deprecation - DeviceCreateInfo.enabledLayerCount = 0; // Deprecated and ignored. - DeviceCreateInfo.ppEnabledLayerNames = nullptr; // Deprecated and ignored - DeviceCreateInfo.queueCreateInfoCount = 1; - DeviceCreateInfo.pQueueCreateInfos = &QueueInfo; - VkPhysicalDeviceFeatures DeviceFeatures = {}; - DeviceFeatures.depthBiasClamp = CreationAttribs.EnabledFeatures.depthBiasClamp ? VK_TRUE : VK_FALSE; - DeviceFeatures.fillModeNonSolid = CreationAttribs.EnabledFeatures.fillModeNonSolid ? VK_TRUE : VK_FALSE; - DeviceFeatures.depthClamp = CreationAttribs.EnabledFeatures.depthClamp ? VK_TRUE : VK_FALSE; - DeviceFeatures.independentBlend = CreationAttribs.EnabledFeatures.independentBlend ? VK_TRUE : VK_FALSE; - DeviceFeatures.samplerAnisotropy = CreationAttribs.EnabledFeatures.samplerAnisotropy ? VK_TRUE : VK_FALSE; - DeviceFeatures.geometryShader = CreationAttribs.EnabledFeatures.geometryShader ? VK_TRUE : VK_FALSE; - DeviceFeatures.tessellationShader = CreationAttribs.EnabledFeatures.tessellationShader ? VK_TRUE : VK_FALSE; - DeviceFeatures.dualSrcBlend = CreationAttribs.EnabledFeatures.dualSrcBlend ? VK_TRUE : VK_FALSE; - DeviceFeatures.multiViewport = CreationAttribs.EnabledFeatures.multiViewport ? VK_TRUE : VK_FALSE; - DeviceFeatures.imageCubeArray = CreationAttribs.EnabledFeatures.imageCubeArray ? VK_TRUE : VK_FALSE; - DeviceFeatures.textureCompressionBC = CreationAttribs.EnabledFeatures.textureCompressionBC ? VK_TRUE : VK_FALSE; - DeviceFeatures.vertexPipelineStoresAndAtomics = CreationAttribs.EnabledFeatures.vertexPipelineStoresAndAtomics ? VK_TRUE : VK_FALSE; - DeviceFeatures.fragmentStoresAndAtomics = CreationAttribs.EnabledFeatures.fragmentStoresAndAtomics ? VK_TRUE : VK_FALSE; - DeviceFeatures.shaderStorageImageExtendedFormats = CreationAttribs.EnabledFeatures.shaderStorageImageExtendedFormats ? VK_TRUE : VK_FALSE; - DeviceCreateInfo.pEnabledFeatures = &DeviceFeatures; // NULL or a pointer to a VkPhysicalDeviceFeatures structure that contains - // boolean indicators of all the features to be enabled. - - std::vector DeviceExtensions = - { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_KHR_MAINTENANCE1_EXTENSION_NAME // To allow negative viewport height - }; - DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data(); - DeviceCreateInfo.enabledExtensionCount = static_cast(DeviceExtensions.size()); - - auto vkAllocator = Instance->GetVkAllocator(); - auto vkPhysicalDevice = PhysicalDevice->GetVkDeviceHandle(); - auto LogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(vkPhysicalDevice, DeviceCreateInfo, vkAllocator); - - RefCntAutoPtr pCmdQueueVk; - auto &RawMemAllocator = GetRawAllocator(); - pCmdQueueVk = NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(LogicalDevice, QueueInfo.queueFamilyIndex); - - std::array CommandQueues = {{pCmdQueueVk}}; - AttachToVulkanDevice(Instance, std::move(PhysicalDevice), LogicalDevice, CommandQueues.size(), CommandQueues.data(), CreationAttribs, ppDevice, ppContexts, NumDeferredContexts); - - FenceDesc Desc; - Desc.Name = "Command queue fence"; - // Render device owns command queue that in turn owns the fence, so it is an internal device object - bool IsDeviceInternal = true; - auto* pRenderDeviceVk = ValidatedCast(*ppDevice); - RefCntAutoPtr pFenceVk( NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal) ); - pCmdQueueVk->SetFence(std::move(pFenceVk)); - } - catch(std::runtime_error& ) - { - return; - } -} - -/// Attaches to existing Vulkan device - -/// \param [in] Instance - shared pointer to a VulkanUtilities::VulkanInstance object -/// \param [in] PhysicalDevice - pointer to the object representing physical device -/// \param [in] LogicalDevice - shared pointer to a VulkanUtilities::VulkanLogicalDevice object -/// \param [in] pCommandQueue - pointer to the implementation of command queue -/// \param [in] EngineAttribs - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Pointer to the immediate -/// context goes at position 0. If NumDeferredContexts > 0, -/// pointers to the deferred contexts go afterwards. -/// \param [in] NumDeferredContexts - Number of deferred contexts. If non-zero number -/// of deferred contexts is requested, pointers to the -/// contexts are written to ppContexts array starting -/// at position 1 -void EngineFactoryVkImpl::AttachToVulkanDevice(std::shared_ptr Instance, - std::unique_ptr PhysicalDevice, - std::shared_ptr LogicalDevice, - size_t CommandQueueCount, - ICommandQueueVk** ppCommandQueues, - const EngineVkAttribs& EngineAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts, - Uint32 NumDeferredContexts) -{ - VERIFY( ppCommandQueues && ppDevice && ppContexts, "Null pointer provided" ); - if(!LogicalDevice || !ppCommandQueues || !ppDevice || !ppContexts ) - return; - - *ppDevice = nullptr; - memset(ppContexts, 0, sizeof(*ppContexts) * (1+NumDeferredContexts)); - - try - { - auto &RawMemAllocator = GetRawAllocator(); - RenderDeviceVkImpl *pRenderDeviceVk( NEW_RC_OBJ(RawMemAllocator, "RenderDeviceVkImpl instance", RenderDeviceVkImpl)(RawMemAllocator, EngineAttribs, CommandQueueCount, ppCommandQueues, Instance, std::move(PhysicalDevice), LogicalDevice, NumDeferredContexts ) ); - pRenderDeviceVk->QueryInterface(IID_RenderDevice, reinterpret_cast(ppDevice) ); - - std::shared_ptr GenerateMipsHelper(new GenerateMipsVkHelper(*pRenderDeviceVk)); - - RefCntAutoPtr pImmediateCtxVk( NEW_RC_OBJ(RawMemAllocator, "DeviceContextVkImpl instance", DeviceContextVkImpl)(pRenderDeviceVk, false, EngineAttribs, 0, 0, GenerateMipsHelper) ); - // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceVk will - // keep a weak reference to the context - pImmediateCtxVk->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts) ); - pRenderDeviceVk->SetImmediateContext(pImmediateCtxVk); - - for (Uint32 DeferredCtx = 0; DeferredCtx < NumDeferredContexts; ++DeferredCtx) - { - RefCntAutoPtr pDeferredCtxVk( NEW_RC_OBJ(RawMemAllocator, "DeviceContextVkImpl instance", DeviceContextVkImpl)(pRenderDeviceVk, true, EngineAttribs, 1+DeferredCtx, 0, GenerateMipsHelper) ); - // We must call AddRef() (implicitly through QueryInterface()) because pRenderDeviceVk will - // keep a weak reference to the context - pDeferredCtxVk->QueryInterface(IID_DeviceContext, reinterpret_cast(ppContexts + 1 + DeferredCtx) ); - pRenderDeviceVk->SetDeferredContext(DeferredCtx, pDeferredCtxVk); - } - } - catch( const std::runtime_error & ) - { - if( *ppDevice ) - { - (*ppDevice)->Release(); - *ppDevice = nullptr; - } - for(Uint32 ctx=0; ctx < 1 + NumDeferredContexts; ++ctx) - { - if( ppContexts[ctx] != nullptr ) - { - ppContexts[ctx]->Release(); - ppContexts[ctx] = nullptr; - } - } - - LOG_ERROR( "Failed to create device and contexts" ); - } -} - - -/// Creates a swap chain for Direct3D12-based engine implementation - -/// \param [in] pDevice - Pointer to the render device -/// \param [in] pImmediateContext - Pointer to the immediate device context -/// \param [in] SCDesc - Swap chain description -/// \param [in] pNativeWndHandle - Platform-specific native handle of the window -/// the swap chain will be associated with: -/// * On Win32 platform, this should be window handle (HWND) -/// * On Universal Windows Platform, this should be reference to the -/// core window (Windows::UI::Core::CoreWindow) -/// -/// \param [out] ppSwapChain - Address of the memory location where pointer to the new -/// swap chain will be written -void EngineFactoryVkImpl::CreateSwapChainVk( IRenderDevice* pDevice, - IDeviceContext* pImmediateContext, - const SwapChainDesc& SCDesc, - void* pNativeWndHandle, - ISwapChain** ppSwapChain ) -{ - VERIFY( ppSwapChain, "Null pointer provided" ); - if( !ppSwapChain ) - return; - - *ppSwapChain = nullptr; - - try - { - auto *pDeviceVk = ValidatedCast( pDevice ); - auto *pDeviceContextVk = ValidatedCast(pImmediateContext); - auto &RawMemAllocator = GetRawAllocator(); - auto *pSwapChainVk = NEW_RC_OBJ(RawMemAllocator, "SwapChainVkImpl instance", SwapChainVkImpl)(SCDesc, pDeviceVk, pDeviceContextVk, pNativeWndHandle); - pSwapChainVk->QueryInterface( IID_SwapChain, reinterpret_cast(ppSwapChain) ); - - pDeviceContextVk->SetSwapChain(pSwapChainVk); - // Bind default render target - pDeviceContextVk->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); - // Set default viewport - pDeviceContextVk->SetViewports( 1, nullptr, 0, 0 ); - - auto NumDeferredCtx = pDeviceVk->GetNumDeferredContexts(); - for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) - { - if (auto pDeferredCtx = pDeviceVk->GetDeferredContext(ctx)) - { - auto *pDeferredCtxVk = pDeferredCtx.RawPtr(); - pDeferredCtxVk->SetSwapChain(pSwapChainVk); - // We cannot bind default render target here because - // there is no guarantee that deferred context will be used - // in this frame. It is an error to bind - // RTV of an inactive buffer in the swap chain - } - } - } - catch( const std::runtime_error & ) - { - if( *ppSwapChain ) - { - (*ppSwapChain)->Release(); - *ppSwapChain = nullptr; - } - - LOG_ERROR( "Failed to create the swap chain" ); - } -} - - -#ifdef DOXYGEN -/// Loads Direct3D12-based engine implementation and exports factory functions -/// \param [out] GetFactoryFunc - Pointer to the function that returns factory for Vk engine implementation. -/// See EngineFactoryVkImpl. -/// \remarks Depending on the configuration and platform, the function loads different dll: -/// Platform\\Configuration | Debug | Release -/// --------------------------|-------------------------------|---------------------------- -/// x86 | GraphicsEngineVk_32d.dll | GraphicsEngineVk_32r.dll -/// x64 | GraphicsEngineVk_64d.dll | GraphicsEngineVk_64r.dll -/// -void LoadGraphicsEngineVk(GetEngineFactoryVkType &GetFactoryFunc) -{ - // This function is only required because DoxyGen refuses to generate documentation for a static function when SHOW_FILES==NO - #error This function must never be compiled; -} -#endif - -API_QUALIFIER -IEngineFactoryVk* GetEngineFactoryVk() -{ - return EngineFactoryVkImpl::GetInstance(); -} - -} diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 89ed5d01..a126a937 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -39,7 +39,7 @@ namespace Diligent RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* pRefCounters, IMemoryAllocator& RawMemAllocator, - const EngineVkAttribs& CreationAttribs, + const EngineVkCreateInfo& EngineCI, size_t CommandQueueCount, ICommandQueueVk** CmdQueues, std::shared_ptr Instance, @@ -66,7 +66,7 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* m_VulkanInstance(Instance), m_PhysicalDevice(std::move(PhysicalDevice)), m_LogicalVkDevice(std::move(LogicalDevice)), - m_EngineAttribs(CreationAttribs), + m_EngineAttribs(EngineCI), m_FramebufferCache(*this), m_RenderPassCache(*this), m_DescriptorSetAllocator @@ -75,18 +75,18 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* "Main descriptor pool", std::vector { - {VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumSeparateSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumCombinedSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.MainDescriptorPoolSize.NumSampledImageDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, CreationAttribs.MainDescriptorPoolSize.NumStorageImageDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, CreationAttribs.MainDescriptorPoolSize.NumUniformTexelBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, CreationAttribs.MainDescriptorPoolSize.NumStorageTexelBufferDescriptors}, - //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, CreationAttribs.MainDescriptorPoolSize.NumUniformBufferDescriptors}, - //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, CreationAttribs.MainDescriptorPoolSize.NumStorageBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumUniformBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumStorageBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_SAMPLER, EngineCI.MainDescriptorPoolSize.NumSeparateSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, EngineCI.MainDescriptorPoolSize.NumCombinedSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, EngineCI.MainDescriptorPoolSize.NumSampledImageDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, EngineCI.MainDescriptorPoolSize.NumStorageImageDescriptors}, + {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, EngineCI.MainDescriptorPoolSize.NumUniformTexelBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, EngineCI.MainDescriptorPoolSize.NumStorageTexelBufferDescriptors}, + //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, EngineCI.MainDescriptorPoolSize.NumUniformBufferDescriptors}, + //{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}, }, - CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets, + EngineCI.MainDescriptorPoolSize.MaxDescriptorSets, true }, m_DynamicDescriptorPool @@ -95,27 +95,27 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* "Dynamic descriptor pool", std::vector { - {VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumSampledImageDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumStorageImageDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors}, - //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors}, - //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_SAMPLER, EngineCI.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, EngineCI.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, EngineCI.DynamicDescriptorPoolSize.NumSampledImageDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, EngineCI.DynamicDescriptorPoolSize.NumStorageImageDescriptors}, + {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, EngineCI.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, EngineCI.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors}, + //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, EngineCI.DynamicDescriptorPoolSize.NumUniformBufferDescriptors}, + //{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}, }, - CreationAttribs.DynamicDescriptorPoolSize.MaxDescriptorSets, + EngineCI.DynamicDescriptorPoolSize.MaxDescriptorSets, false // Pools can only be reset }, m_TransientCmdPoolMgr(*this, "Transient command buffer pool manager", CmdQueues[0]->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT), - m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), CreationAttribs.DeviceLocalMemoryPageSize, CreationAttribs.HostVisibleMemoryPageSize, CreationAttribs.DeviceLocalMemoryReserveSize, CreationAttribs.HostVisibleMemoryReserveSize), + m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), EngineCI.DeviceLocalMemoryPageSize, EngineCI.HostVisibleMemoryPageSize, EngineCI.DeviceLocalMemoryReserveSize, EngineCI.HostVisibleMemoryReserveSize), m_DynamicMemoryManager { GetRawAllocator(), *this, - CreationAttribs.DynamicHeapSize, + EngineCI.DynamicHeapSize, ~Uint64{0} } { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index 9f212fd4..e65aaa91 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -920,7 +920,7 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou const auto& SrcCachedRes = SrcCachedSet.GetResource(SrcOffset); IDeviceObject* pObject = SrcCachedRes.pObject.RawPtr(); if (!pObject) - LOG_ERROR_MESSAGE("No resource assigned to static shader variable '", SrcRes.SpirvAttribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", SrcRes.SpirvAttribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); auto DstOffset = DstRes.CacheOffset + ArrInd; IDeviceObject* pCachedResource = DstResourceCache.GetDescriptorSet(DstRes.DescriptorSet).GetResource(DstOffset).pObject; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp index 5fccdad8..57b55f15 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp @@ -165,22 +165,22 @@ VulkanDynamicMemoryManager::MasterBlock VulkanDynamicMemoryManager::AllocateMast Block = TBase::AllocateMasterBlock(SizeInBytes, Alignment); if (!Block.IsValid()) { - LOG_ERROR_MESSAGE("Space in dynamic heap is exausted! After idling for ", std::fixed, std::setprecision(1), IdleDuration.count()*1000.0, " ms still no space is available. Increase the size of the heap by setting EngineVkAttribs::DynamicHeapSize to a greater value or optimize dynamic resource usage"); + LOG_ERROR_MESSAGE("Space in dynamic heap is exausted! After idling for ", std::fixed, std::setprecision(1), IdleDuration.count()*1000.0, " ms still no space is available. Increase the size of the heap by setting EngineVkCreateInfo::DynamicHeapSize to a greater value or optimize dynamic resource usage"); } else { - LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted. Allocation forced idling the GPU. Increase the size of the heap by setting EngineVkAttribs::DynamicHeapSize to a greater value or optimize dynamic resource usage"); + LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted. Allocation forced idling the GPU. Increase the size of the heap by setting EngineVkCreateInfo::DynamicHeapSize to a greater value or optimize dynamic resource usage"); } } else { if(SleepIterations == 0) { - LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted forcing mid-frame shrinkage. Increase the size of the heap buffer by setting EngineVkAttribs::DynamicHeapSize to a greater value or optimize dynamic resource usage"); + LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted forcing mid-frame shrinkage. Increase the size of the heap buffer by setting EngineVkCreateInfo::DynamicHeapSize to a greater value or optimize dynamic resource usage"); } else { - LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted. Allocation forced wait time of ", std::fixed, std::setprecision(1), IdleDuration.count()*1000.0, " ms. Increase the size of the heap by setting EngineVkAttribs::DynamicHeapSize to a greater value or optimize dynamic resource usage"); + LOG_WARNING_MESSAGE("Space in dynamic heap is almost exausted. Allocation forced wait time of ", std::fixed, std::setprecision(1), IdleDuration.count()*1000.0, " ms. Increase the size of the heap by setting EngineVkCreateInfo::DynamicHeapSize to a greater value or optimize dynamic resource usage"); } } } -- cgit v1.2.3 From bdbca67b0e03baec3b9dd803e803d267210e892b Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 4 Mar 2019 23:19:07 -0800 Subject: Added ShaderFlags parameter to IPipelineState::BindStaticResources --- Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h | 2 +- Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h | 5 +++++ Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 10 +++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index d03066fe..e9be63a3 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -66,7 +66,7 @@ public: virtual VkPipeline GetVkPipeline() const override final { return m_Pipeline; } - virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags)override final; + virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags)override final; virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index 729997f9..8f7d2940 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -285,6 +285,11 @@ public: return m_pResources->GetShaderName(); } + SHADER_TYPE GetShaderType()const + { + return m_pResources->GetShaderType(); + } + const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r)const { VERIFY_EXPR( r < m_NumResources[VarType] ); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index f28b2068..776db721 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -618,12 +618,16 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind } } -void PipelineStateVkImpl::BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags) +void PipelineStateVkImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { for (Uint32 s=0; s < m_NumShaders; ++s) { - auto& StaticVarMgr = GetStaticVarMgr(s); - StaticVarMgr.BindResources(pResourceMapping, Flags); + auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); + if ((ShaderType & ShaderFlags) != 0) + { + auto& StaticVarMgr = GetStaticVarMgr(s); + StaticVarMgr.BindResources(pResourceMapping, Flags); + } } } -- cgit v1.2.3 From 76a1a90ee26e3f2e78fab018bbbfc43ddc85d849 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 6 Mar 2019 10:03:57 -0800 Subject: Removed unused m_ResourceLayout member from ShaderVariableManagerVk and ShaderVariableManagerD3D12 plus a bunch of minor updates to fix clang warnings --- Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h | 10 ++++------ Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h index 74dac81d..0b7e3aa0 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h @@ -64,7 +64,7 @@ namespace Diligent class ShaderVariableVkImpl; -// sizeof(ShaderVariableManagerVk) == 40 (x64, msvc, Release) +// sizeof(ShaderVariableManagerVk) == 32 (x64, msvc, Release) class ShaderVariableManagerVk { public: @@ -97,11 +97,9 @@ private: Uint32 GetVariableIndex(const ShaderVariableVkImpl& Variable); IObject& m_Owner; - // Variable mgr is owned by either Pipeline state object (in which case m_pResourceLayout points to - // static resource layout owned by the same PSO object), or by SRB object (in which case - // m_pResourceLayout points to corresponding layout in pipeline state). Since SRB keeps strong - // reference to PSO, the layout is guaranteed to be alive while SRB is alive - const ShaderResourceLayoutVk& m_ResourceLayout; + // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references + // static resource cache owned by the same PSO object), or by SRB object (in which case + // m_ResourceCache references the cache in the SRB). Thus the cache is guaranteed to be alive. ShaderResourceCacheVk& m_ResourceCache; // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index d005dc26..9d6bbf96 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -68,7 +68,6 @@ ShaderVariableManagerVk::ShaderVariableManagerVk(IObject& Uint32 NumAllowedTypes, ShaderResourceCacheVk& ResourceCache) : m_Owner(Owner), - m_ResourceLayout(SrcLayout), m_ResourceCache(ResourceCache) #ifdef _DEBUG , m_DbgAllocator(Allocator) -- cgit v1.2.3 From 5026a05381f82bbcdc2ff804363c96a3c1b9fa67 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 6 Mar 2019 10:17:37 -0800 Subject: Minor comment updates --- Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h index 0b7e3aa0..03f5018f 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h @@ -99,7 +99,8 @@ private: IObject& m_Owner; // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references // static resource cache owned by the same PSO object), or by SRB object (in which case - // m_ResourceCache references the cache in the SRB). Thus the cache is guaranteed to be alive. + // m_ResourceCache references the cache in the SRB). Thus the cache and the resource layout + // (which the variables reference) are guaranteed to be alive while the manager is alive. ShaderResourceCacheVk& m_ResourceCache; // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block -- cgit v1.2.3