summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-01-25 15:58:28 +0000
committerazhirnov <zh1dron@gmail.com>2021-01-26 06:59:23 +0000
commitdfb3f98a83a646abff564a159d556f03432826ac (patch)
tree713b0153c116e16775e6cdd8ce07321728e15b75 /Graphics/GraphicsEngineVulkan
parentDevice contetxt Vk: fixed issue with unitialized SRBs in m_DescrSetBindInfo (diff)
downloadDiligentCore-dfb3f98a83a646abff564a159d556f03432826ac.tar.gz
DiligentCore-dfb3f98a83a646abff564a159d556f03432826ac.zip
removed empty signature, added test for partially compatible pipeline layouts
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp29
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp1
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp17
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp75
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp45
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp6
8 files changed, 124 insertions, 76 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
index 146742b3..70ff48f4 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp
@@ -486,23 +486,24 @@ private:
// Do not use strong references!
using ShaderResourceArray = std::array<ShaderResourceBindingVkImpl*, MAX_RESOURCE_SIGNATURES>;
using VkDescSetArray = std::array<VkDescriptorSet, MAX_RESOURCE_SIGNATURES * MAX_DESCR_SET_PER_SIGNATURE>;
- using BoolArray = std::bitset<MAX_RESOURCE_SIGNATURES>;
+ using Bitfield = Uint8;
+ static_assert(sizeof(Bitfield) * 8 >= MAX_RESOURCE_SIGNATURES, "AZ TODO");
- ShaderResourceArray Resources = {};
- VkDescSetArray vkSets = {};
- BoolArray PendingVkSet = {}; // 'true' if new descriptor set must be bound
- BoolArray PendingDynamicDescriptors = {}; // 'true' if dynamic descriptor set must be bound // AZ TODO: remove ?
- BoolArray DynamicBuffersPresent = {};
+ Bitfield ActiveSRBMask = 0; // indicates which SRB is active in current PSO
+ Bitfield PendingSRB = 0; // 1 bit if new descriptor set must be bound
+ Bitfield DynamicBuffersPresent = 0;
+ ShaderResourceArray Resources = {};
+ VkDescSetArray vkSets = {};
DescriptorSetBindInfo()
{}
void Reset()
{
- PendingVkSet.reset();
- DynamicBuffersPresent.reset();
- PendingDynamicDescriptors.reset();
- Resources.fill({});
+ ActiveSRBMask = 0;
+ PendingSRB = 0;
+ DynamicBuffersPresent = 0;
+ Resources.fill(nullptr);
#ifdef DILIGENT_DEBUG
vkSets.fill(VK_NULL_HANDLE);
@@ -511,8 +512,14 @@ private:
__forceinline bool RequireUpdate(bool Intact = false) const
{
- return PendingVkSet.any() || PendingDynamicDescriptors.any() || (DynamicBuffersPresent.any() && !Intact);
+ return (PendingSRB & ActiveSRBMask) || ((DynamicBuffersPresent & ActiveSRBMask) && !Intact);
}
+
+ void SetPendingSRB(Uint32 Index) { PendingSRB |= static_cast<Bitfield>(1u << Index); }
+ void ResetPendingSRB(Uint32 Index) { PendingSRB &= static_cast<Bitfield>(~(1u << Index)); }
+
+ void SetDynamicBuffersPresent(Uint32 Index) { DynamicBuffersPresent |= static_cast<Bitfield>(1u << Index); }
+ void ResetDynamicBuffersPresent(Uint32 Index) { DynamicBuffersPresent &= static_cast<Bitfield>(~(1u << Index)); }
};
void BindShaderResources(PipelineStateVkImpl* pPipelineStateVk);
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
index 1658dd06..660815f6 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
@@ -53,7 +53,6 @@ public:
VkPipelineLayout GetVkPipelineLayout() const { return m_VkPipelineLayout; }
Uint32 GetSignatureCount() const { return m_SignatureCount; }
- //Uint32 GetDescriptorSetCount() const { return m_DescrSetCount; }
PipelineResourceSignatureVkImpl* GetSignature(Uint32 index) const
{
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
index 438b09e9..cafb6518 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
@@ -79,6 +79,23 @@ public:
/// Implementation of IPipelineState::GetResourceSignature() in Vulkan backend.
virtual IPipelineResourceSignature* DILIGENT_CALL_TYPE GetResourceSignature(Uint32 Index) const override final { return m_PipelineLayout.GetSignature(Index); }
+ /// Implementation of IPipelineState::CreateShaderResourceBinding() in Vulkan backend.
+ virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
+ bool InitStaticResources) override final;
+
+ /// Implementation of IPipelineState::GetStaticVariableByName() in Vulkan backend.
+ virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType,
+ const Char* Name) override final;
+
+ /// Implementation of IPipelineState::GetStaticVariableByIndex() in Vulkan backend.
+ virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType,
+ Uint32 Index) override final;
+
+ /// Implementation of IPipelineState::GetStaticVariableCount() in Vulkan backend.
+ virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final;
+
+ virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final;
+
const PipelineLayoutVk& GetPipelineLayout() const { return m_PipelineLayout; }
static RenderPassDesc GetImplicitRenderPassDesc(Uint32 NumRenderTargets,
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index baa3b786..126bff8c 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -233,9 +233,6 @@ public:
return m_Properties;
}
- IPipelineResourceSignature* GetEmptySignature() const { return m_pEmptySignature.RawPtr<IPipelineResourceSignature>(); }
- PipelineResourceSignatureVkImpl* GetEmptySignatureVk() const { return m_pEmptySignature.RawPtr<PipelineResourceSignatureVkImpl>(); }
-
private:
template <typename PSOCreateInfoType>
void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState);
@@ -272,8 +269,6 @@ private:
std::unique_ptr<IDXCompiler> m_pDxCompiler;
Properties m_Properties;
-
- RefCntAutoPtr<IPipelineResourceSignature> m_pEmptySignature;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index ad6be668..315ffeae 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -352,12 +352,12 @@ __forceinline void DeviceContextVkImpl::BindShaderResources(PipelineStateVkImpl*
{
VERIFY_EXPR(pPipelineStateVk != nullptr);
- const auto& Layout = pPipelineStateVk->GetPipelineLayout();
- const auto BindIndex = PipelineTypeToBindPointIndex(pPipelineStateVk->GetDesc().PipelineType);
- auto& BindInfo = m_DescrSetBindInfo[BindIndex];
- auto& Resources = BindInfo.Resources;
- const auto SignCount = Layout.GetSignatureCount();
- Uint32 CompatSignCount = SignCount;
+ const auto& Layout = pPipelineStateVk->GetPipelineLayout();
+ const auto BindIndex = PipelineTypeToBindPointIndex(pPipelineStateVk->GetDesc().PipelineType);
+ auto& BindInfo = m_DescrSetBindInfo[BindIndex];
+ const auto SignCount = Layout.GetSignatureCount();
+
+ BindInfo.ActiveSRBMask = (1u << SignCount) - 1;
// Layout compatibility means that descriptor sets can be bound to a command buffer
// for use by any pipeline created with a compatible pipeline layout, and without having bound
@@ -366,33 +366,32 @@ __forceinline void DeviceContextVkImpl::BindShaderResources(PipelineStateVkImpl*
// (14.2.2. Pipeline Layouts, clause 'Pipeline Layout Compatibility')
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#descriptorsets-compatibility
-
#ifdef DILIGENT_DEBUG
- // unbind incompatible descriptor sets
+ auto& Resources = BindInfo.Resources;
+ Uint32 CompatSignCount = SignCount;
+
+ // find first incompatible shader resource bindings
for (Uint32 i = 0; i < SignCount; ++i)
{
const auto* LayoutSign = Layout.GetSignature(i);
- const auto* ResSign = Resources[i] != nullptr ? Resources[i]->GetSignature() : ValidatedCast<RenderDeviceVkImpl>(GetDevice())->GetEmptySignatureVk();
-
- VERIFY_EXPR(LayoutSign != nullptr);
- VERIFY_EXPR(ResSign != nullptr);
+ if (LayoutSign == nullptr)
+ continue;
- if (LayoutSign->IsIncompatibleWith(*ResSign))
+ if (Resources[i] == nullptr || LayoutSign->IsIncompatibleWith(*Resources[i]->GetSignature()))
{
CompatSignCount = i;
break;
}
}
- // reset unused states
- for (Uint32 i = CompatSignCount; i < MAX_RESOURCE_SIGNATURES; ++i)
+ // unbind incompatible shader resource bindings
+ for (Uint32 i = CompatSignCount; i < SignCount; ++i)
{
- BindInfo.PendingVkSet[i] = false;
- BindInfo.PendingDynamicDescriptors[i] = false;
- BindInfo.DynamicBuffersPresent[i] = false;
-
Resources[i] = nullptr;
+ BindInfo.ResetPendingSRB(i);
+ BindInfo.ResetDynamicBuffersPresent(i);
+
BindInfo.vkSets[i * MAX_DESCR_SET_PER_SIGNATURE + 0] = VK_NULL_HANDLE;
BindInfo.vkSets[i * MAX_DESCR_SET_PER_SIGNATURE + 1] = VK_NULL_HANDLE;
}
@@ -410,12 +409,15 @@ void DeviceContextVkImpl::BindDescriptorSetsWithDynamicOffsets(DescriptorSetBind
auto& Offsets = m_DynamicBufferOffsets;
const auto VkLayout = Layout.GetVkPipelineLayout();
- for (Uint32 i = 0; i < SignCount; ++i)
+ while (true)
{
- VERIFY_EXPR(Resources[i] != nullptr);
+ Uint32 i = PlatformMisc::GetLSB(Uint32{BindInfo.PendingSRB});
- if ((BindInfo.PendingVkSet[i] || BindInfo.PendingDynamicDescriptors[i]) && Resources[i] != nullptr)
+ if (i < SignCount)
{
+ VERIFY_EXPR(Resources[i] != nullptr);
+ BindInfo.ResetPendingSRB(i);
+
const auto* pSignature = Resources[i]->GetSignature();
const Uint32 DescrSetIdx = Layout.GetFirstDescrSetIndex(pSignature);
const auto& ResourceCache = Resources[i]->GetResourceCache();
@@ -441,20 +443,17 @@ void DeviceContextVkImpl::BindDescriptorSetsWithDynamicOffsets(DescriptorSetBind
// (either compute or graphics, according to the pipelineBindPoint). Any bindings that were previously
// applied via these sets are no longer valid (13.2.5)
m_CommandBuffer.BindDescriptorSets(BindPoint, VkLayout, DescrSetIdx, DSCount, &BindInfo.vkSets[DSOffset], static_cast<Uint32>(Offsets.size()), Offsets.data());
- BindInfo.PendingDynamicDescriptors[i] = false;
}
else
{
- VERIFY_EXPR(!BindInfo.PendingDynamicDescriptors[i]);
m_CommandBuffer.BindDescriptorSets(BindPoint, VkLayout, DescrSetIdx, DSCount, &BindInfo.vkSets[DSOffset], 0, nullptr);
}
-
- BindInfo.PendingVkSet[i] = false;
}
+ else
+ break;
}
- VERIFY_EXPR(!BindInfo.PendingVkSet.any());
- VERIFY_EXPR(!BindInfo.PendingDynamicDescriptors.any());
+ VERIFY_EXPR(!(BindInfo.PendingSRB & BindInfo.ActiveSRBMask));
}
void DeviceContextVkImpl::ValidateShaderResources()
@@ -470,10 +469,7 @@ void DeviceContextVkImpl::ValidateShaderResources()
{
auto* LayoutSign = Layout.GetSignature(i);
if (LayoutSign == nullptr)
- {
- LOG_ERROR_MESSAGE("Pipeline resource signature for index (", i, ") is null, this may indicate a bug");
- return;
- }
+ continue;
if (BindInfo.Resources[i] == nullptr)
{
@@ -491,8 +487,7 @@ void DeviceContextVkImpl::ValidateShaderResources()
}
// You must call BindDescriptorSetsWithDynamicOffsets() before validation.
- VERIFY_EXPR(!BindInfo.PendingVkSet[i]);
- VERIFY_EXPR(!BindInfo.PendingDynamicDescriptors[i]);
+ VERIFY_EXPR(!(BindInfo.PendingSRB & BindInfo.ActiveSRBMask));
const auto DSCount = LayoutSign->GetNumDescriptorSets();
const auto DSOffset = i * MAX_DESCR_SET_PER_SIGNATURE;
@@ -562,9 +557,12 @@ void DeviceContextVkImpl::CommitShaderResources(IShaderResourceBinding* pShaderR
const auto DSCount = ResourceCache.GetNumDescriptorSets();
Uint32 DSIndex = 0;
- BindInfo.PendingVkSet[Index] = true;
- BindInfo.PendingDynamicDescriptors[Index] = false;
- BindInfo.DynamicBuffersPresent[Index] = ResourceCache.GetNumDynamicBuffers() > 0;
+ BindInfo.SetPendingSRB(Index);
+
+ if (ResourceCache.GetNumDynamicBuffers() > 0)
+ BindInfo.SetDynamicBuffersPresent(Index);
+ else
+ BindInfo.ResetDynamicBuffersPresent(Index);
if (pSignature->HasStaticDescrSet())
{
@@ -595,9 +593,6 @@ void DeviceContextVkImpl::CommitShaderResources(IShaderResourceBinding* pShaderR
++DSIndex;
}
- if (pSignature->GetDynamicOffsetCount() > 0)
- BindInfo.PendingDynamicDescriptors[Index] = true;
-
VERIFY_EXPR(DSIndex == DSCount);
BindInfo.Resources[Index] = pResBindingVkImpl;
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
index 50f1c5c8..7d1d2c7c 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
@@ -80,15 +80,7 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, IPipelineResourceSi
m_Signatures[Index] = pSignature;
}
- auto* pEmptySign = ValidatedCast<PipelineResourceSignatureVkImpl>(pDeviceVk->GetEmptySignature());
-
- for (Uint32 i = 0; i < m_SignatureCount; ++i)
- {
- if (m_Signatures[i] == nullptr)
- m_Signatures[i] = pEmptySign;
- }
-
- std::array<VkDescriptorSetLayout, MAX_RESOURCE_SIGNATURES* MAX_DESCR_SET_PER_SIGNATURE> DescSetLayouts = {};
+ std::array<VkDescriptorSetLayout, MAX_RESOURCE_SIGNATURES * MAX_DESCR_SET_PER_SIGNATURE> DescSetLayouts;
Uint32 DescSetLayoutCount = 0;
Uint32 DynamicUniformBufferCount = 0;
@@ -97,7 +89,8 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk, IPipelineResourceSi
for (Uint32 i = 0; i < m_SignatureCount; ++i)
{
const auto& pSignature = m_Signatures[i];
- VERIFY_EXPR(pSignature != nullptr);
+ if (pSignature == nullptr)
+ continue;
VERIFY(DescSetLayoutCount <= std::numeric_limits<FirstDescrSetIndexArrayType::value_type>::max(),
"Descriptor set layout count (", DescSetLayoutCount, ") exceeds the maximum representable value");
@@ -156,8 +149,10 @@ size_t PipelineLayoutVk::GetHash() const
HashCombine(hash, m_SignatureCount);
for (Uint32 i = 0; i < m_SignatureCount; ++i)
{
- VERIFY_EXPR(m_Signatures[i] != nullptr);
- HashCombine(hash, m_Signatures[i]->GetHash());
+ if (m_Signatures[i] != nullptr)
+ HashCombine(hash, m_Signatures[i]->GetHash());
+ else
+ HashCombine(hash, 0);
}
return hash;
}
@@ -167,7 +162,8 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso
for (Uint32 i = 0, DSCount = GetSignatureCount(); i < DSCount; ++i)
{
auto* pSignature = GetSignature(i);
- VERIFY_EXPR(pSignature != nullptr);
+ if (pSignature == nullptr)
+ continue;
for (Uint32 r = 0, ResCount = pSignature->GetTotalResourceCount(); r < ResCount; ++r)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index cf6e366a..dc184e1b 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -998,4 +998,49 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const
return false;
}
+void PipelineStateVkImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
+ bool InitStaticResources)
+{
+ *ppShaderResourceBinding = nullptr;
+
+ if (GetResourceSignatureCount() != 1)
+ return;
+
+ return GetResourceSignature(0)->CreateShaderResourceBinding(ppShaderResourceBinding, InitStaticResources);
+}
+
+IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByName(SHADER_TYPE ShaderType,
+ const Char* Name)
+{
+ if (GetResourceSignatureCount() != 1)
+ return nullptr;
+
+ return GetResourceSignature(0)->GetStaticVariableByName(ShaderType, Name);
+}
+
+IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TYPE ShaderType,
+ Uint32 Index)
+{
+ if (GetResourceSignatureCount() != 1)
+ return nullptr;
+
+ return GetResourceSignature(0)->GetStaticVariableByIndex(ShaderType, Index);
+}
+
+Uint32 PipelineStateVkImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const
+{
+ if (GetResourceSignatureCount() != 1)
+ return 0;
+
+ return GetResourceSignature(0)->GetStaticVariableCount(ShaderType);
+}
+
+void PipelineStateVkImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags)
+{
+ if (GetResourceSignatureCount() != 1)
+ return;
+
+ return GetResourceSignature(0)->BindStaticResources(ShaderFlags, pResourceMapping, Flags);
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index edfcb670..dcf812b6 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -276,16 +276,10 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
SamCaps.BorderSamplingModeSupported = True;
SamCaps.AnisotropicFilteringSupported = vkEnabledFeatures.samplerAnisotropy;
SamCaps.LODBiasSupported = True;
-
- PipelineResourceSignatureDesc Desc;
- Desc.Name = "Empty resource signature";
- CreatePipelineResourceSignature(Desc, &m_pEmptySignature, true);
}
RenderDeviceVkImpl::~RenderDeviceVkImpl()
{
- m_pEmptySignature.Release();
-
// Explicitly destroy dynamic heap. This will move resources owned by
// the heap into release queues
m_DynamicMemoryManager.Destroy();