summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-03-06 22:06:26 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:16 +0000
commit30a65df99cfc678a431a89b0cff02a515416c78a (patch)
tree2d3ed68bf8ec028879e22ff6d1ec386df723677e /Graphics/GraphicsEngineVulkan
parentMoved GetResourceAttribution() function to PipelineStateBase to eliminate dup... (diff)
downloadDiligentCore-30a65df99cfc678a431a89b0cff02a515416c78a.tar.gz
DiligentCore-30a65df99cfc678a431a89b0cff02a515416c78a.zip
Unified resource signature handling by pipeline state in D3D12, Vk and GL
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp57
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp27
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp91
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp142
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp2
6 files changed, 102 insertions, 239 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
index 25bbcb6b..3ef58d49 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
@@ -29,15 +29,16 @@
/// \file
/// Declaration of Diligent::PipelineLayoutVk class
+
#include <array>
-#include "PipelineResourceSignatureVkImpl.hpp"
#include "VulkanUtilities/VulkanObjectWrappers.hpp"
namespace Diligent
{
-class ShaderResourceCacheVk;
+class RenderDeviceVkImpl;
+class PipelineResourceSignatureVkImpl;
/// Implementation of the Diligent::PipelineLayoutVk class
class PipelineLayoutVk
@@ -46,68 +47,32 @@ public:
PipelineLayoutVk();
~PipelineLayoutVk();
- void Create(RenderDeviceVkImpl* pDeviceVk, PIPELINE_TYPE PipelineType, IPipelineResourceSignature** ppSignatures, Uint32 SignatureCount);
+ void Create(RenderDeviceVkImpl* pDeviceVk, RefCntAutoPtr<PipelineResourceSignatureVkImpl> ppSignatures[], Uint32 SignatureCount);
void Release(RenderDeviceVkImpl* pDeviceVkImpl, Uint64 CommandQueueMask);
- size_t GetHash() const;
-
VkPipelineLayout GetVkPipelineLayout() const { return m_VkPipelineLayout; }
- Uint32 GetSignatureCount() const { return m_SignatureCount; }
- PipelineResourceSignatureVkImpl* GetSignature(Uint32 index) const
+ // Returns the index of the first descriptor set used by the resource signature at the given bind index
+ Uint32 GetFirstDescrSetIndex(Uint32 Index) const
{
- VERIFY_EXPR(index < m_SignatureCount);
- return m_Signatures[index].RawPtr<PipelineResourceSignatureVkImpl>();
- }
-
- // Returns the index of the first descriptor set used by the given resource signature
- Uint32 GetFirstDescrSetIndex(const PipelineResourceSignatureVkImpl* pPRS) const
- {
- VERIFY_EXPR(pPRS != nullptr);
- Uint32 Index = pPRS->GetDesc().BindingIndex;
-
- VERIFY_EXPR(Index < m_SignatureCount);
- VERIFY_EXPR(m_Signatures[Index] != nullptr);
- VERIFY_EXPR(!m_Signatures[Index]->IsIncompatibleWith(*pPRS));
-
+ VERIFY_EXPR(Index <= m_DbgMaxBindIndex);
return m_FirstDescrSetIndex[Index];
}
- struct ResourceInfo
- {
- PipelineResourceSignatureVkImpl* Signature = nullptr;
- SHADER_RESOURCE_TYPE Type = SHADER_RESOURCE_TYPE_UNKNOWN;
- // Index in m_Desc.Resources for a resource, or ~0U for an immutable sampler.
- Uint32 ResIndex = ~0U;
- Uint32 DescrSetIndex = ~0U;
- Uint32 BindingIndex = ~0U;
-
- explicit operator bool() const
- {
- return Signature != nullptr && Type != SHADER_RESOURCE_TYPE_UNKNOWN;
- }
- };
- ResourceInfo GetResourceInfo(const char* Name, SHADER_TYPE Stage) const;
- ResourceInfo GetImmutableSamplerInfo(const char* Name, SHADER_TYPE Stage) const;
-
private:
- using SignatureArray = std::array<RefCntAutoPtr<PipelineResourceSignatureVkImpl>, MAX_RESOURCE_SIGNATURES>;
- using FirstDescrSetIndexArrayType = std::array<Uint8, MAX_RESOURCE_SIGNATURES>;
-
VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout;
+ using FirstDescrSetIndexArrayType = std::array<Uint8, MAX_RESOURCE_SIGNATURES>;
// Index of the first descriptor set, for every resource signature.
FirstDescrSetIndexArrayType m_FirstDescrSetIndex = {};
- // The number of resource signatures used by this pipeline layout
- // (Maximum is MAX_RESOURCE_SIGNATURES)
- Uint8 m_SignatureCount = 0;
-
// The total number of descriptor sets used by this pipeline layout
// (Maximum is MAX_RESOURCE_SIGNATURES * 2)
Uint8 m_DescrSetCount = 0;
- SignatureArray m_Signatures;
+#ifdef DILIGENT_DEBUG
+ Uint32 m_DbgMaxBindIndex = 0;
+#endif
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
index d2f289af..f36611df 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
@@ -44,6 +44,7 @@
#include "VulkanUtilities/VulkanCommandBuffer.hpp"
#include "RenderDeviceVkImpl.hpp"
#include "PipelineLayoutVk.hpp"
+#include "PipelineResourceSignatureVkImpl.hpp"
namespace Diligent
{
@@ -66,21 +67,12 @@ public:
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_PipelineStateVk, TPipelineStateBase)
- /// Implementation of IPipelineState::IsCompatibleWith() in Vulkan backend.
- virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final;
-
/// Implementation of IPipelineStateVk::GetRenderPass().
virtual IRenderPassVk* DILIGENT_CALL_TYPE GetRenderPass() const override final { return GetRenderPassPtr().RawPtr<IRenderPassVk>(); }
/// Implementation of IPipelineStateVk::GetVkPipeline().
virtual VkPipeline DILIGENT_CALL_TYPE GetVkPipeline() const override final { return m_Pipeline; }
- /// Implementation of IPipelineState::GetResourceSignatureCount() in Vulkan backend.
- virtual Uint32 DILIGENT_CALL_TYPE GetResourceSignatureCount() const override final { return m_PipelineLayout.GetSignatureCount(); }
-
- /// Implementation of IPipelineState::GetResourceSignature() in Vulkan backend.
- virtual IPipelineResourceSignature* DILIGENT_CALL_TYPE GetResourceSignature(Uint32 Index) const override final { return m_PipelineLayout.GetSignature(Index); }
-
const PipelineLayoutVk& GetPipelineLayout() const { return m_PipelineLayout; }
static RenderPassDesc GetImplicitRenderPassDesc(Uint32 NumRenderTargets,
@@ -115,7 +107,7 @@ public:
// Performs validation of SRB resource parameters that are not possible to validate
// when resource is bound.
using SRBArray = std::array<ShaderResourceBindingVkImpl*, MAX_RESOURCE_SIGNATURES>;
- void DvpVerifySRBResources(SRBArray& SRBs) const;
+ void DvpVerifySRBResources(const SRBArray& SRBs) const;
#endif
private:
@@ -127,9 +119,9 @@ private:
void InitPipelineLayout(const PipelineStateCreateInfo& CreateInfo,
TShaderStages& ShaderStages);
- void CreateDefaultSignature(const PipelineStateCreateInfo& CreateInfo,
- const TShaderStages& ShaderStages,
- IPipelineResourceSignature** ppSignature);
+ RefCntAutoPtr<PipelineResourceSignatureVkImpl> CreateDefaultSignature(
+ const PipelineStateCreateInfo& CreateInfo,
+ const TShaderStages& ShaderStages);
void Destruct();
@@ -139,8 +131,8 @@ private:
#ifdef DILIGENT_DEVELOPMENT
// Shader resources for all shaders in all shader stages
std::vector<std::shared_ptr<const SPIRVShaderResources>> m_ShaderResources;
- // Resource info for every resource in m_ShaderResources, in the same order
- std::vector<PipelineLayoutVk::ResourceInfo> m_ResInfo;
+ // Resource attributions for every resource in m_ShaderResources, in the same order
+ std::vector<ResourceAttribution> m_ResourceAttibutions;
#endif
};
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 878cf9a9..0ac9c0fb 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -318,14 +318,14 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState)
const auto& Layout = pPipelineStateVk->GetPipelineLayout();
auto& BindInfo = GetDescriptorSetBindInfo(PSODesc.PipelineType);
- const auto SignCount = Layout.GetSignatureCount();
+ const auto SignCount = pPipelineStateVk->GetResourceSignatureCount();
BindInfo.vkPipelineLayout = Layout.GetVkPipelineLayout();
BindInfo.ActiveSRBMask = 0;
for (Uint32 i = 0; i < SignCount; ++i)
{
- auto* pSignature = Layout.GetSignature(i);
+ auto* pSignature = pPipelineStateVk->GetResourceSignature(i);
if (pSignature == nullptr || pSignature->GetNumDescriptorSets() == 0)
continue;
@@ -333,7 +333,7 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState)
auto& ResInfo = BindInfo.Resources[i];
- ResInfo.DescriptorSetBaseInd = Layout.GetFirstDescrSetIndex(pSignature);
+ ResInfo.DescriptorSetBaseInd = Layout.GetFirstDescrSetIndex(pSignature->GetDesc().BindingIndex);
ResInfo.DynamicOffsetCount = pSignature->GetDynamicOffsetCount();
}
@@ -349,7 +349,7 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState)
Uint32 sign = 0;
for (; sign < SignCount; ++sign)
{
- const auto* pLayoutSign = Layout.GetSignature(sign);
+ const auto* pLayoutSign = pPipelineStateVk->GetResourceSignature(sign);
const auto* pSRBSign = BindInfo.SRBs[sign] != nullptr ? BindInfo.SRBs[sign]->GetSignature() : nullptr;
if ((pLayoutSign == nullptr || pLayoutSign->GetNumDescriptorSets() == 0) != (pSRBSign == nullptr || pSRBSign->GetNumDescriptorSets() == 0))
@@ -414,7 +414,7 @@ void DeviceContextVkImpl::CommitDescriptorSets(DescriptorSetBindInfo& BindInfo)
while (StaleSRBFlags != 0)
{
Uint32 sign = PlatformMisc::GetLSB(StaleSRBFlags);
- VERIFY_EXPR(sign < m_pPipelineState->GetPipelineLayout().GetSignatureCount());
+ VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
StaleSRBFlags &= ~(Uint32{1} << sign);
auto& ResInfo = BindInfo.Resources[sign];
@@ -461,17 +461,16 @@ void DeviceContextVkImpl::DvpValidateCommittedShaderResources()
if (m_State.CommittedResourcesValidated)
return;
- const auto& Layout = m_pPipelineState->GetPipelineLayout();
- auto& BindInfo = GetDescriptorSetBindInfo(m_pPipelineState->GetDesc().PipelineType);
- const auto SignCount = Layout.GetSignatureCount();
+ const auto& BindInfo = GetDescriptorSetBindInfo(m_pPipelineState->GetDesc().PipelineType);
+ const auto SignCount = m_pPipelineState->GetResourceSignatureCount();
for (Uint32 i = 0; i < SignCount; ++i)
{
- auto* pLayoutSign = Layout.GetSignature(i);
- if (pLayoutSign == nullptr)
+ const auto* pSign = m_pPipelineState->GetResourceSignature(i);
+ if (pSign == nullptr)
continue;
- if (pLayoutSign->GetNumDescriptorSets() == 0)
+ if (pSign->GetNumDescriptorSets() == 0)
{
// Skip signatures without any resources
continue;
@@ -487,7 +486,7 @@ void DeviceContextVkImpl::DvpValidateCommittedShaderResources()
const auto* pSRBSign = pSRB->GetSignature();
DEV_CHECK_ERR(pSRBSign != nullptr, "SRB must not be null");
- if (!pLayoutSign->IsCompatibleWith(*pSRBSign))
+ if (!pSign->IsCompatibleWith(*pSRBSign))
{
LOG_ERROR_MESSAGE("Shader resource binding at index ", i, " with signature '", pSRBSign->GetDesc().Name,
"' is not compatible with pipeline layout in current pipeline '", m_pPipelineState->GetDesc().Name, "'.");
@@ -496,12 +495,12 @@ void DeviceContextVkImpl::DvpValidateCommittedShaderResources()
DEV_CHECK_ERR((BindInfo.StaleSRBMask & BindInfo.ActiveSRBMask) == 0, "CommitDescriptorSets() must be called before validation.");
const auto& ResInfo = BindInfo.Resources[i];
- const auto DSCount = pLayoutSign->GetNumDescriptorSets();
+ const auto DSCount = pSign->GetNumDescriptorSets();
for (Uint32 s = 0; s < DSCount; ++s)
{
DEV_CHECK_ERR(ResInfo.vkSets[s] != VK_NULL_HANDLE,
"descriptor set with index ", s, " is not bound for resource signature '",
- pLayoutSign->GetDesc().Name, "', binding index ", i, ".");
+ pSign->GetDesc().Name, "', binding index ", i, ".");
}
DEV_CHECK_ERR(ResInfo.LastBoundDSBaseInd == ResInfo.DescriptorSetBaseInd,
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
index f8fae8ee..14183e97 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
@@ -34,6 +34,7 @@
#include "RenderDeviceVkImpl.hpp"
#include "VulkanTypeConversions.hpp"
#include "StringTools.hpp"
+#include "PipelineResourceSignatureVkImpl.hpp"
namespace Diligent
{
@@ -56,16 +57,9 @@ void PipelineLayoutVk::Release(RenderDeviceVkImpl* pDeviceVk, Uint64 CommandQueu
}
}
-void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, PIPELINE_TYPE PipelineType, IPipelineResourceSignature** ppSignatures, Uint32 SignatureCount)
+void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, RefCntAutoPtr<PipelineResourceSignatureVkImpl> ppSignatures[], Uint32 SignatureCount)
{
- VERIFY(m_SignatureCount == 0 && m_DescrSetCount == 0 && !m_VkPipelineLayout,
- "This pipeline layout is already initialized");
-
- auto MaxSignatureBindIndex =
- PipelineResourceSignatureVkImpl::CopyResourceSignatures(PipelineType, SignatureCount, ppSignatures,
- m_Signatures.data(), m_Signatures.size());
- m_SignatureCount = static_cast<Uint8>(MaxSignatureBindIndex + 1);
- VERIFY_EXPR(m_SignatureCount == MaxSignatureBindIndex + 1);
+ VERIFY(m_DescrSetCount == 0 && !m_VkPipelineLayout, "This pipeline layout is already initialized");
std::array<VkDescriptorSetLayout, MAX_RESOURCE_SIGNATURES * PipelineResourceSignatureVkImpl::MAX_DESCRIPTOR_SETS> DescSetLayouts;
@@ -73,9 +67,9 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, PIPELINE_TYPE Pipel
Uint32 DynamicUniformBufferCount = 0;
Uint32 DynamicStorageBufferCount = 0;
- for (Uint32 i = 0; i < m_SignatureCount; ++i)
+ for (Uint32 i = 0; i < SignatureCount; ++i)
{
- const auto& pSignature = m_Signatures[i];
+ const auto& pSignature = ppSignatures[i];
if (pSignature == nullptr)
continue;
@@ -91,6 +85,9 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, PIPELINE_TYPE Pipel
DynamicUniformBufferCount += pSignature->GetDynamicUniformBufferCount();
DynamicStorageBufferCount += pSignature->GetDynamicStorageBufferCount();
+#ifdef DILIGENT_DEBUG
+ m_DbgMaxBindIndex = std::max(m_DbgMaxBindIndex, Uint32{pSignature->GetDesc().BindingIndex});
+#endif
}
VERIFY_EXPR(DescSetLayoutCount <= MAX_RESOURCE_SIGNATURES * 2);
@@ -130,76 +127,4 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, PIPELINE_TYPE Pipel
m_DescrSetCount = static_cast<Uint8>(DescSetLayoutCount);
}
-size_t PipelineLayoutVk::GetHash() const
-{
- if (m_SignatureCount == 0)
- return 0;
-
- size_t hash = 0;
- HashCombine(hash, m_SignatureCount);
- for (Uint32 i = 0; i < m_SignatureCount; ++i)
- {
- if (m_Signatures[i] != nullptr)
- HashCombine(hash, m_Signatures[i]->GetHash());
- else
- HashCombine(hash, 0);
- }
- return hash;
-}
-
-PipelineLayoutVk::ResourceInfo PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage) const
-{
- ResourceInfo Info;
- for (Uint32 sign = 0, SignCount = GetSignatureCount(); sign < SignCount && !Info; ++sign)
- {
- auto* const pSignature = GetSignature(sign);
- if (pSignature == nullptr)
- continue;
-
- for (Uint32 r = 0, ResCount = pSignature->GetTotalResourceCount(); r < ResCount; ++r)
- {
- const auto& ResDesc = pSignature->GetResourceDesc(r);
- const auto& Attr = pSignature->GetResourceAttribs(r);
-
- if ((ResDesc.ShaderStages & Stage) != 0 && strcmp(ResDesc.Name, Name) == 0)
- {
- Info.Signature = pSignature;
- Info.Type = ResDesc.ResourceType;
- Info.ResIndex = r;
- Info.BindingIndex = Attr.BindingIndex;
- Info.DescrSetIndex = m_FirstDescrSetIndex[sign] + Attr.DescrSet;
- break;
- }
- }
- }
- return Info;
-}
-
-PipelineLayoutVk::ResourceInfo PipelineLayoutVk::GetImmutableSamplerInfo(const char* Name, SHADER_TYPE Stage) const
-{
- ResourceInfo Info;
- for (Uint32 sign = 0, SignCount = GetSignatureCount(); sign < SignCount && !Info; ++sign)
- {
- auto* const pSignature = GetSignature(sign);
- if (pSignature == nullptr)
- continue;
-
- for (Uint32 s = 0, SampCount = pSignature->GetImmutableSamplerCount(); s < SampCount; ++s)
- {
- const auto& Desc = pSignature->GetImmutableSamplerDesc(s);
- const auto& Attr = pSignature->GetImmutableSamplerAttribs(s);
-
- if (Attr.Ptr && (Desc.ShaderStages & Stage) != 0 && StreqSuff(Name, Desc.SamplerOrTextureName, pSignature->GetCombinedSamplerSuffix()))
- {
- Info.Signature = pSignature;
- Info.Type = SHADER_RESOURCE_TYPE_SAMPLER;
- Info.BindingIndex = Attr.BindingIndex;
- Info.DescrSetIndex = m_FirstDescrSetIndex[sign] + Attr.DescrSet;
- break;
- }
- }
- }
- return Info;
-}
-
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 3a3f8092..364d6f1b 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -735,9 +735,9 @@ RenderPassDesc PipelineStateVkImpl::GetImplicitRenderPassDesc(
return RPDesc;
}
-void PipelineStateVkImpl::CreateDefaultSignature(const PipelineStateCreateInfo& CreateInfo,
- const TShaderStages& ShaderStages,
- IPipelineResourceSignature** ppSignature)
+RefCntAutoPtr<PipelineResourceSignatureVkImpl> PipelineStateVkImpl::CreateDefaultSignature(
+ const PipelineStateCreateInfo& CreateInfo,
+ const TShaderStages& ShaderStages)
{
struct UniqueResource
{
@@ -837,6 +837,7 @@ void PipelineStateVkImpl::CreateDefaultSignature(const PipelineStateCreateInfo&
}
}
+ RefCntAutoPtr<PipelineResourceSignatureVkImpl> pSignature;
if (Resources.size())
{
String SignName = String{"Implicit signature for PSO '"} + m_Desc.Name + '\'';
@@ -852,38 +853,30 @@ void PipelineStateVkImpl::CreateDefaultSignature(const PipelineStateCreateInfo&
ResSignDesc.UseCombinedTextureSamplers = pCombinedSamplerSuffix != nullptr;
ResSignDesc.CombinedSamplerSuffix = pCombinedSamplerSuffix;
- GetDevice()->CreatePipelineResourceSignature(ResSignDesc, ppSignature, true);
+ // Always initialize default resource signature as internal device object.
+ // This is necessary to avoud cyclic references.
+ // This may never be a problem as the PSO keeps the reference to the device if necessary.
+ constexpr bool bIsDeviceInternal = true;
+ GetDevice()->CreatePipelineResourceSignature(ResSignDesc, pSignature.DblPtr<IPipelineResourceSignature>(), bIsDeviceInternal);
- if (*ppSignature == nullptr)
+ if (pSignature == nullptr)
LOG_ERROR_AND_THROW("Failed to create resource signature for pipeline state");
}
+
+ return pSignature;
}
void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& CreateInfo,
TShaderStages& ShaderStages)
{
- std::array<IPipelineResourceSignature*, MAX_RESOURCE_SIGNATURES> Signatures = {};
- RefCntAutoPtr<IPipelineResourceSignature> pImplicitSignature;
-
- Uint32 SignatureCount = CreateInfo.ResourceSignaturesCount;
-
- for (Uint32 i = 0; i < SignatureCount; ++i)
- {
- Signatures[i] = CreateInfo.ppResourceSignatures[i];
- }
-
- if (SignatureCount == 0 || CreateInfo.ppResourceSignatures == nullptr)
+ if (m_UsingImplicitSignature)
{
- CreateDefaultSignature(CreateInfo, ShaderStages, &pImplicitSignature);
- if (pImplicitSignature != nullptr)
- {
- VERIFY_EXPR(pImplicitSignature->GetDesc().BindingIndex == 0);
- Signatures[0] = pImplicitSignature;
- SignatureCount = 1;
- }
+ VERIFY_EXPR(m_SignatureCount == 1);
+ m_Signatures[0] = CreateDefaultSignature(CreateInfo, ShaderStages);
+ VERIFY_EXPR(!m_Signatures[0] || m_Signatures[0]->GetDesc().BindingIndex == 0);
}
- m_PipelineLayout.Create(GetDevice(), CreateInfo.PSODesc.PipelineType, Signatures.data(), SignatureCount);
+ m_PipelineLayout.Create(GetDevice(), m_Signatures, m_SignatureCount);
// Verify that pipeline layout is compatible with shader resources and
// remap resource bindings.
@@ -908,46 +901,56 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
pShaderResources->ProcessResources(
[&](const SPIRVShaderResourceAttribs& SPIRVAttribs, Uint32) //
{
- auto Info = m_PipelineLayout.GetResourceInfo(SPIRVAttribs.Name, ShaderType);
- if (!Info && SPIRVAttribs.Type == SPIRVShaderResourceAttribs::SeparateSampler)
- {
- DEV_CHECK_ERR(SPIRVAttribs.ArraySize == 1, "Immutable sampler arrays must also be added to resource list");
- Info = m_PipelineLayout.GetImmutableSamplerInfo(SPIRVAttribs.Name, ShaderType);
- if (Info)
- {
- VERIFY(Info.BindingIndex != ~0u && Info.DescrSetIndex != ~0u,
- "Binding index and/or descriptor set index are not initialized. This indicates that the immutable sampler "
- "is also present in the list of resources, so it should've been found by GetResourceInfo().");
- }
- }
- if (!Info)
+ auto ResAttribution = GetResourceAttribution(SPIRVAttribs.Name, ShaderType);
+ if (!ResAttribution)
{
LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource '", SPIRVAttribs.Name,
"' that is not present in any pipeline resource signature used to create pipeline state '",
m_Desc.Name, "'.");
}
+ const auto& SignDesc = ResAttribution.pSignature->GetDesc();
+
SHADER_RESOURCE_TYPE Type;
PIPELINE_RESOURCE_FLAGS Flags;
GetShaderResourceTypeAndFlags(SPIRVAttribs.Type, Type, Flags);
- if (Type != Info.Type)
- {
- LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", SPIRVAttribs.Name,
- "' and type '", GetShaderResourceTypeLiteralName(Type), "' that is not compatible with type '",
- GetShaderResourceTypeLiteralName(Info.Type), "' specified in pipeline resource signature '", Info.Signature->GetDesc().Name, "'.");
- }
- if (Info.ResIndex != ~0u)
+ Uint32 ResourceBinding = ~0u;
+ Uint32 DescriptorSet = ~0u;
+ if (ResAttribution.ResourceIndex != ResourceAttribution::InvalidResourceIndex)
{
- const auto& ResDesc = Info.Signature->GetResourceDesc(Info.ResIndex);
+ const auto& ResDesc = ResAttribution.pSignature->GetResourceDesc(ResAttribution.ResourceIndex);
ValidatePipelineResourceCompatibility(ResDesc, Type, Flags, SPIRVAttribs.ArraySize,
- pShader->GetDesc().Name, Info.Signature->GetDesc().Name);
+ pShader->GetDesc().Name, SignDesc.Name);
+
+ const auto& ResAttribs{ResAttribution.pSignature->GetResourceAttribs(ResAttribution.ResourceIndex)};
+ ResourceBinding = ResAttribs.BindingIndex;
+ DescriptorSet = ResAttribs.DescrSet;
+ }
+ else if (ResAttribution.ImmutableSamplerIndex != ResourceAttribution::InvalidResourceIndex)
+ {
+ if (Type != SHADER_RESOURCE_TYPE_SAMPLER)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", SPIRVAttribs.Name,
+ "' and type '", GetShaderResourceTypeLiteralName(Type),
+ "' that is not compatible with immutable sampler defined in pipeline resource signature '",
+ SignDesc.Name, "'.");
+ }
+ const auto& SamAttribs{ResAttribution.pSignature->GetImmutableSamplerAttribs(ResAttribution.ImmutableSamplerIndex)};
+ ResourceBinding = SamAttribs.BindingIndex;
+ DescriptorSet = SamAttribs.DescrSet;
+ }
+ else
+ {
+ UNEXPECTED("Either immutable sampler or resource index should be valid");
}
- SPIRV[SPIRVAttribs.BindingDecorationOffset] = Info.BindingIndex;
- SPIRV[SPIRVAttribs.DescriptorSetDecorationOffset] = Info.DescrSetIndex;
+
+ VERIFY_EXPR(ResourceBinding != ~0u && DescriptorSet != ~0u);
+ SPIRV[SPIRVAttribs.BindingDecorationOffset] = ResourceBinding;
+ SPIRV[SPIRVAttribs.DescriptorSetDecorationOffset] = m_PipelineLayout.GetFirstDescrSetIndex(SignDesc.BindingIndex) + DescriptorSet;
#ifdef DILIGENT_DEVELOPMENT
- m_ResInfo.emplace_back(Info);
+ m_ResourceAttibutions.emplace_back(ResAttribution);
#endif
});
}
@@ -963,8 +966,6 @@ PipelineStateVkImpl::TShaderStages PipelineStateVkImpl::InitInternalObjects(
TShaderStages ShaderStages;
ExtractShaders<ShaderVkImpl>(CreateInfo, ShaderStages);
- InitPipelineLayout(CreateInfo, ShaderStages);
-
FixedLinearAllocator MemPool{GetRawAllocator()};
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
@@ -975,6 +976,8 @@ PipelineStateVkImpl::TShaderStages PipelineStateVkImpl::InitInternalObjects(
InitializePipelineDesc(CreateInfo, MemPool);
+ InitPipelineLayout(CreateInfo, ShaderStages);
+
// Create shader modules and initialize shader stages
InitPipelineShaderStages(LogicalDevice, ShaderStages, ShaderModules, vkShaderStages);
@@ -1062,45 +1065,24 @@ void PipelineStateVkImpl::Destruct()
TPipelineStateBase::Destruct();
}
-bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const
-{
- VERIFY_EXPR(pPSO != nullptr);
-
- if (pPSO == this)
- return true;
-
- const auto& lhs = m_PipelineLayout;
- const auto& rhs = ValidatedCast<const PipelineStateVkImpl>(pPSO)->m_PipelineLayout;
-
- if (lhs.GetSignatureCount() != rhs.GetSignatureCount())
- return false;
-
- for (Uint32 s = 0, SigCount = lhs.GetSignatureCount(); s < SigCount; ++s)
- {
- if (!lhs.GetSignature(s)->IsCompatibleWith(*rhs.GetSignature(s)))
- return false;
- }
- return true;
-}
-
#ifdef DILIGENT_DEVELOPMENT
-void PipelineStateVkImpl::DvpVerifySRBResources(SRBArray& SRBs) const
+void PipelineStateVkImpl::DvpVerifySRBResources(const SRBArray& SRBs) const
{
- auto res_info = m_ResInfo.begin();
+ auto res_info = m_ResourceAttibutions.begin();
for (const auto& pResources : m_ShaderResources)
{
pResources->ProcessResources(
[&](const SPIRVShaderResourceAttribs& ResAttribs, Uint32) //
{
- if (res_info->ResIndex != ~0u) // There are also immutable samplers in the list
+ if (!res_info->IsImmutableSampler()) // There are also immutable samplers in the list
{
- VERIFY_EXPR(res_info->Signature != nullptr);
- const auto& SignDesc = res_info->Signature->GetDesc();
+ VERIFY_EXPR(res_info->pSignature != nullptr);
+ const auto& SignDesc = res_info->pSignature->GetDesc();
const auto SignBindIndex = SignDesc.BindingIndex;
if (auto* pSRB = SRBs[SignBindIndex])
{
- res_info->Signature->DvpValidateCommittedResource(ResAttribs, res_info->ResIndex, pSRB->GetResourceCache(),
- pResources->GetShaderName(), m_Desc.Name);
+ res_info->pSignature->DvpValidateCommittedResource(ResAttribs, res_info->ResourceIndex, pSRB->GetResourceCache(),
+ pResources->GetShaderName(), m_Desc.Name);
}
else
{
@@ -1111,7 +1093,7 @@ void PipelineStateVkImpl::DvpVerifySRBResources(SRBArray& SRBs) const
} //
);
}
- VERIFY_EXPR(res_info == m_ResInfo.end());
+ VERIFY_EXPR(res_info == m_ResourceAttibutions.end());
}
#endif
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp
index e6d053ee..3becabff 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp
@@ -87,7 +87,7 @@ RenderPassVkImpl* RenderPassCache::GetRenderPass(const RenderPassCacheKey& Key)
}
RefCntAutoPtr<RenderPassVkImpl> pRenderPass;
- m_DeviceVkImpl.CreateRenderPass(RPDesc, pRenderPass.GetRawDblPtr<IRenderPass>(), /* IsDeviceInternal = */ true);
+ m_DeviceVkImpl.CreateRenderPass(RPDesc, pRenderPass.RawDblPtr<IRenderPass>(), /* IsDeviceInternal = */ true);
VERIFY_EXPR(pRenderPass != nullptr);
it = m_Cache.emplace(Key, std::move(pRenderPass)).first;
}