summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-01-28 21:22:04 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-01-28 21:22:04 +0000
commitd4f3ca9fc42dfd8ba8a220a8c4355bde48359c00 (patch)
tree4aea65cac0529c4f332330b9b87b3c5e71452733 /Graphics/GraphicsEngineVulkan
parentDevice context Vk: added CommittedResourcesValidated to avoid calling DvpVali... (diff)
downloadDiligentCore-d4f3ca9fc42dfd8ba8a220a8c4355bde48359c00.tar.gz
DiligentCore-d4f3ca9fc42dfd8ba8a220a8c4355bde48359c00.zip
Vk backend: added validation of parameters that can't be validated when resources are bound
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp7
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp16
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp216
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp47
8 files changed, 257 insertions, 54 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
index 87cf1da0..131a9006 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp
@@ -69,10 +69,12 @@ public:
struct ResourceInfo
{
- IPipelineResourceSignature* Signature = nullptr;
- SHADER_RESOURCE_TYPE Type = SHADER_RESOURCE_TYPE_UNKNOWN;
- Uint32 DescrSetIndex = 0;
- Uint32 BindingIndex = 0;
+ 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 = 0;
+ Uint32 DescrSetIndex = 0;
+ Uint32 BindingIndex = 0;
};
bool GetResourceInfo(const char* Name, SHADER_TYPE Stage, ResourceInfo& Info) const;
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
index 2fdb2ba8..8e8829f2 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
@@ -42,6 +42,7 @@ namespace Diligent
class RenderDeviceVkImpl;
class ShaderResourceCacheVk;
class ShaderVariableManagerVk;
+struct SPIRVShaderResourceAttribs;
enum class DescriptorType : Uint8
{
@@ -53,9 +54,9 @@ enum class DescriptorType : Uint8
StorageTexelBuffer,
StorageTexelBuffer_ReadOnly,
UniformBuffer,
+ UniformBufferDynamic,
StorageBuffer,
StorageBuffer_ReadOnly,
- UniformBufferDynamic,
StorageBufferDynamic,
StorageBufferDynamic_ReadOnly,
InputAttachment,
@@ -274,6 +275,10 @@ public:
return GetHash() != Other.GetHash();
}
+#ifdef DILIGENT_DEVELOPMENT
+ bool DvpValidateCommittedResource(const SPIRVShaderResourceAttribs& SPIRVAttribs, Uint32 ResIndex, ShaderResourceCacheVk& ResourceCache) const;
+#endif
+
private:
// Resource cache group identifier
enum CACHE_GROUP : size_t
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
index 438b09e9..d65c85ac 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
@@ -31,6 +31,7 @@
/// Declaration of Diligent::PipelineStateVkImpl class
#include <array>
+#include <memory>
#include "RenderDeviceVk.h"
#include "PipelineStateVk.h"
@@ -50,6 +51,7 @@ namespace Diligent
class FixedBlockMemoryAllocator;
class ShaderVariableManagerVk;
class ShaderVkImpl;
+class ShaderResourceBindingVkImpl;
/// Pipeline state object implementation in Vulkan backend.
class PipelineStateVkImpl final : public PipelineStateBase<IPipelineStateVk, RenderDeviceVkImpl>
@@ -108,6 +110,13 @@ public:
};
using TShaderStages = std::vector<ShaderStageInfo>;
+#ifdef DILIGENT_DEVELOPMENT
+ // 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;
+#endif
+
private:
template <typename PSOCreateInfoType>
TShaderStages InitInternalObjects(const PSOCreateInfoType& CreateInfo,
@@ -126,6 +135,13 @@ private:
VulkanUtilities::PipelineWrapper m_Pipeline;
PipelineLayoutVk m_PipelineLayout;
+
+#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;
+#endif
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp
index e3bb52f6..804a1c84 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp
@@ -68,14 +68,13 @@ public:
return m_SPIRV;
}
- const SPIRVShaderResources& GetShaderResources() const { return *m_pShaderResources; }
+ const std::shared_ptr<const SPIRVShaderResources>& GetShaderResources() const { return m_pShaderResources; }
const char* GetEntryPoint() const { return m_EntryPoint.c_str(); }
private:
void MapHLSLVertexShaderInputs();
- // AZ TODO: remove shared pointer
std::shared_ptr<const SPIRVShaderResources> m_pShaderResources;
std::string m_EntryPoint;
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 4aba7d94..f03e6e07 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -473,6 +473,8 @@ void DeviceContextVkImpl::DvpValidateCommittedShaderResources()
}
}
+ m_pPipelineState->DvpVerifySRBResources(BindInfo.Resources);
+
m_State.CommittedResourcesValidated = true;
}
#endif
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
index 3c0d642c..c10bffcd 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
@@ -171,9 +171,9 @@ size_t PipelineLayoutVk::GetHash() const
bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, ResourceInfo& Info) const
{
- for (Uint32 i = 0, DSCount = GetSignatureCount(); i < DSCount; ++i)
+ for (Uint32 sign = 0, SignCount = GetSignatureCount(); sign < SignCount; ++sign)
{
- auto* pSignature = GetSignature(i);
+ auto* const pSignature = GetSignature(sign);
if (pSignature == nullptr)
continue;
@@ -185,8 +185,9 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso
if ((ResDesc.ShaderStages & Stage) && strcmp(ResDesc.Name, Name) == 0)
{
Info.Type = ResDesc.ResourceType;
+ Info.ResIndex = r;
Info.BindingIndex = Attr.BindingIndex;
- Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet;
+ Info.DescrSetIndex = m_FirstDescrSetIndex[sign] + Attr.DescrSet;
Info.Signature = pSignature;
return true;
}
@@ -200,8 +201,9 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso
if (Attr.Ptr && (Desc.ShaderStages & Stage) && StreqSuff(Name, Desc.SamplerOrTextureName, pSignature->GetCombinedSamplerSuffix()))
{
Info.Type = SHADER_RESOURCE_TYPE_SAMPLER;
+ Info.ResIndex = ~0U;
Info.BindingIndex = Attr.BindingIndex;
- Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet;
+ Info.DescrSetIndex = m_FirstDescrSetIndex[sign] + Attr.DescrSet;
Info.Signature = pSignature;
return true;
}
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
index 28a11445..408a784a 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
@@ -35,6 +35,7 @@
#include "TopLevelASVkImpl.hpp"
#include "BasicMath.hpp"
#include "DynamicLinearAllocator.hpp"
+#include "SPIRVShaderResources.hpp"
namespace Diligent
{
@@ -1131,20 +1132,12 @@ void PipelineResourceSignatureVkImpl::CommitDynamicResources(const ShaderResourc
String PipelineResourceSignatureVkImpl::GetPrintName(const PipelineResourceDesc& ResDesc, Uint32 ArrayInd)
{
- VERIFY_EXPR(ArrayInd < ResDesc.ArraySize);
-
- if (ResDesc.ArraySize > 1)
- {
- std::stringstream ss;
- ss << ResDesc.Name << '[' << ArrayInd << ']';
- return ss.str();
- }
- else
- return ResDesc.Name;
+ return GetShaderResourcePrintName(ResDesc, ArrayInd);
}
namespace
{
+
struct BindResourceHelper
{
ShaderResourceCacheVk::Resource& DstRes;
@@ -1316,15 +1309,6 @@ void BindResourceHelper::CacheUniformBuffer(IDeviceObject* pBuffer,
RefCntAutoPtr<BufferVkImpl> pBufferVk{pBuffer, IID_BufferVk};
#ifdef DILIGENT_DEVELOPMENT
VerifyConstantBufferBinding(*this, ResDesc.VarType, ArrayIndex, pBuffer, pBufferVk.RawPtr(), DstRes.pObject.RawPtr());
-
- // AZ TODO
- /*if (pBufferVk->GetDesc().uiSizeInBytes < BufferStaticSize)
- {
- // It is OK if robustBufferAccess feature is enabled, otherwise access outside of buffer range may lead to crash or undefined behavior.
- LOG_WARNING_MESSAGE("Error binding uniform buffer '", pBufferVk->GetDesc().Name, "' to shader variable '",
- GetDesc().Name, "': buffer size in the shader (",
- BufferStaticSize, ") is incompatible with the actual buffer size (", pBufferVk->GetDesc().uiSizeInBytes, ").");
- }*/
#endif
auto UpdateDynamicBuffersCounter = [&DynamicBuffersCounter](const BufferVkImpl* pOldBuffer, const BufferVkImpl* pNewBuffer) {
@@ -1377,25 +1361,6 @@ void BindResourceHelper::CacheStorageBuffer(IDeviceObject* pBufferView,
LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
ResDesc.Name, "': structured buffer view is expected.");
}
-
- // AZ TODO
- /*if (BufferStride == 0 && ViewDesc.ByteWidth < BufferStaticSize)
- {
- // It is OK if robustBufferAccess feature is enabled, otherwise access outside of buffer range may lead to crash or undefined behavior.
- LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
- Name, "': buffer size in the shader (",
- BufferStaticSize, ") is incompatible with the actual buffer view size (", ViewDesc.ByteWidth, ").");
- }
-
- if (BufferStride > 0 && (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0))
- {
- // For buffers with dynamic arrays we know only static part size and array element stride.
- // Element stride in the shader may be differ than in the code. Here we check that the buffer size is exactly the same as the array with N elements.
- LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
- Name, "': static buffer size in the shader (",
- BufferStaticSize, ") and array element stride (", BufferStride, ") are incompatible with the actual buffer view size (", ViewDesc.ByteWidth, "),",
- " this may be the result of the array element size mismatch.");
- }*/
}
}
#endif
@@ -1671,12 +1636,16 @@ String BindResourceHelper::GetPrintName(Uint32 ArrayInd) const
RESOURCE_DIMENSION BindResourceHelper::GetResourceDimension() const
{
- return RESOURCE_DIM_UNDEFINED; // AZ TODO
+ // Required resource dimension is not known to the root signature as
+ // shader resources are only known to PSO.
+ return RESOURCE_DIM_UNDEFINED;
}
bool BindResourceHelper::IsMultisample() const
{
- return false; // AZ TODO
+ // Required multisample state is not known to the root signature as
+ // shader resources are only known to PSO.
+ return false;
}
} // namespace
@@ -1707,4 +1676,171 @@ void PipelineResourceSignatureVkImpl::BindResource(IDeviceObject* pObj,
Helper.BindResource(pObj);
}
+template <typename TextureViewImplType>
+bool ValidateTextureDimension(const PipelineResourceDesc& ResDesc,
+ Uint32 ArrayInd,
+ const TextureViewImplType* pTexView,
+ RESOURCE_DIMENSION ExpectedResourceDim,
+ bool IsMultisample)
+{
+ VERIFY_EXPR(ExpectedResourceDim != RESOURCE_DIM_UNDEFINED);
+
+ bool BindingsOK = true;
+
+ const auto ResourceDim = pTexView->GetDesc().TextureDim;
+ if (ResourceDim != ExpectedResourceDim)
+ {
+ LOG_ERROR_MESSAGE("The resource dimension of texture view '", pTexView->GetDesc().Name,
+ "' bound to variable '", GetShaderResourcePrintName(ResDesc, ArrayInd), "' is ", GetResourceDimString(ResourceDim),
+ ", but resource dimension expected by the shader is ", GetResourceDimString(ExpectedResourceDim), ".");
+ }
+
+ if (ResourceDim == RESOURCE_DIM_TEX_2D || ResourceDim == RESOURCE_DIM_TEX_2D_ARRAY)
+ {
+ auto SampleCount = pTexView->GetTexture()->GetDesc().SampleCount;
+ if (IsMultisample && SampleCount == 1)
+ {
+ LOG_ERROR_MESSAGE("Texture view '", pTexView->GetDesc().Name, "' bound to variable '",
+ GetShaderResourcePrintName(ResDesc, ArrayInd), "' is invalid: multisample texture is expected.");
+ BindingsOK = false;
+ }
+ else if (!IsMultisample && SampleCount > 1)
+ {
+ LOG_ERROR_MESSAGE("Texture view '", pTexView->GetDesc().Name, "' bound to variable '",
+ GetShaderResourcePrintName(ResDesc, ArrayInd), "' is invalid: single-sample texture is expected.");
+ BindingsOK = false;
+ }
+ }
+
+ return BindingsOK;
+}
+
+#ifdef DILIGENT_DEVELOPMENT
+bool PipelineResourceSignatureVkImpl::DvpValidateCommittedResource(const SPIRVShaderResourceAttribs& SPIRVAttribs,
+ Uint32 ResIndex,
+ ShaderResourceCacheVk& ResourceCache) const
+{
+ VERIFY_EXPR(ResIndex < m_Desc.NumResources);
+ const auto& ResInfo = m_Desc.Resources[ResIndex];
+ const auto& ResAttribs = m_pResourceAttribs[ResIndex];
+ VERIFY(strcmp(ResInfo.Name, SPIRVAttribs.Name) == 0, "Inconsistent resource names");
+
+ bool BindingsOK = true;
+
+ const auto& DescrSetResources = ResourceCache.GetDescriptorSet(ResAttribs.DescrSet);
+ const auto CacheType = ResourceCache.GetContentType();
+ const auto CacheOffset = ResAttribs.CacheOffset(CacheType);
+
+ switch (ResAttribs.GetDescriptorType())
+ {
+ case DescriptorType::UniformBuffer:
+ case DescriptorType::UniformBufferDynamic:
+ {
+ VERIFY_EXPR(ResInfo.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
+ for (Uint32 i = 0; i < ResAttribs.ArraySize; ++i)
+ {
+ const auto& Res = DescrSetResources.GetResource(CacheOffset + i);
+
+ // When can use raw cast here because the dynamic type is verified when the resource
+ // is bound. It will be null if the type is incorrect.
+ if (const auto* pBufferVk = Res.pObject.RawPtr<BufferVkImpl>())
+ {
+ if (pBufferVk->GetDesc().uiSizeInBytes < SPIRVAttribs.BufferStaticSize)
+ {
+ // It is OK if robustBufferAccess feature is enabled, otherwise access outside of buffer range may lead to crash or undefined behavior.
+ LOG_WARNING_MESSAGE("The size of uniform buffer '",
+ pBufferVk->GetDesc().Name, "' bound to shader variable '",
+ GetPrintName(ResInfo, i), "' is ", pBufferVk->GetDesc().uiSizeInBytes,
+ " bytes, but the shader expects at least ", SPIRVAttribs.BufferStaticSize,
+ " bytes.");
+ }
+ }
+ else
+ {
+ // Missing resource error is logged by BindResourceHelper::CacheUniformBuffer
+ }
+ }
+ }
+ break;
+
+ case DescriptorType::StorageBuffer:
+ case DescriptorType::StorageBuffer_ReadOnly:
+ case DescriptorType::StorageBufferDynamic:
+ case DescriptorType::StorageBufferDynamic_ReadOnly:
+ {
+ VERIFY_EXPR(ResInfo.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV || ResInfo.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
+ for (Uint32 i = 0; i < ResAttribs.ArraySize; ++i)
+ {
+ const auto& Res = DescrSetResources.GetResource(CacheOffset + i);
+
+ // When can use raw cast here because the dynamic type is verified when the resource
+ // is bound. It will be null if the type is incorrect.
+ if (auto* pBufferViewVk = Res.pObject.RawPtr<BufferViewVkImpl>())
+ {
+ const auto* pBufferVk = ValidatedCast<BufferVkImpl>(pBufferViewVk->GetBuffer());
+ const auto& ViewDesc = pBufferViewVk->GetDesc();
+ const auto& BuffDesc = pBufferVk->GetDesc();
+
+ if (BuffDesc.ElementByteStride == 0)
+ {
+ if (ViewDesc.ByteWidth < SPIRVAttribs.BufferStaticSize)
+ {
+ // It is OK if robustBufferAccess feature is enabled, otherwise access outside of buffer range may lead to crash or undefined behavior.
+ LOG_WARNING_MESSAGE("The size of buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' bound to shader variable '",
+ GetPrintName(ResInfo, i), "' is ", ViewDesc.ByteWidth, " bytes, but the shader expects at least ",
+ SPIRVAttribs.BufferStaticSize, " bytes.");
+ }
+ }
+ else
+ {
+ if (ViewDesc.ByteWidth < SPIRVAttribs.BufferStaticSize || (ViewDesc.ByteWidth - SPIRVAttribs.BufferStaticSize) % BuffDesc.ElementByteStride != 0)
+ {
+ // For buffers with dynamic arrays we know only static part size and array element stride.
+ // Element stride in the shader may be differ than in the code. Here we check that the buffer size is exactly the same as the array with N elements.
+ LOG_WARNING_MESSAGE("The size (", ViewDesc.ByteWidth, ") and stride (", BuffDesc.ElementByteStride, ") of buffer view '",
+ ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' bound to shader variable '",
+ GetPrintName(ResInfo, i), "' are incompatible with what the shader expects. This may be the result of the array element size mismatch.");
+ }
+ }
+ }
+ else
+ {
+ // Missing resource error is logged by BindResourceHelper::CacheStorageBuffer
+ }
+ }
+ }
+ break;
+
+ case DescriptorType::StorageImage:
+ case DescriptorType::SeparateImage:
+ case DescriptorType::CombinedImageSampler:
+ {
+ VERIFY_EXPR(ResInfo.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResInfo.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
+ for (Uint32 i = 0; i < ResAttribs.ArraySize; ++i)
+ {
+ const auto& Res = DescrSetResources.GetResource(CacheOffset + i);
+ // When can use raw cast here because the dynamic type is verified when the resource
+ // is bound. It will be null if the type is incorrect.
+ if (const auto* pTexViewVk = Res.pObject.RawPtr<TextureViewVkImpl>())
+ {
+ if (!ValidateTextureDimension(ResInfo, i, pTexViewVk, SPIRVAttribs.GetResourceDimension(), SPIRVAttribs.IsMultisample()))
+ BindingsOK = false;
+ }
+ else
+ {
+ // Missing resource error is logged by BindResourceHelper::CacheImage
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ // Nothing to do
+ }
+
+ return BindingsOK;
+}
+#endif
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index ce53ed59..ac260c8d 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -36,6 +36,7 @@
#include "ShaderResourceBindingVkImpl.hpp"
#include "EngineMemory.h"
#include "StringTools.hpp"
+#include "ShaderResourceBindingVkImpl.hpp"
#if !DILIGENT_NO_HLSL
@@ -750,8 +751,8 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
UniqueNames.clear();
for (auto* pShader : Stage.Shaders)
{
- const auto DefaultVarType = LayoutDesc.DefaultVariableType;
- auto& ShaderResources = pShader->GetShaderResources();
+ const auto DefaultVarType = LayoutDesc.DefaultVariableType;
+ const auto& ShaderResources = *pShader->GetShaderResources();
ShaderResources.ProcessResources(
[&](const SPIRVShaderResourceAttribs& Res, Uint32) //
@@ -849,7 +850,12 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
auto* pShader = Shaders[i];
auto& SPIRV = SPIRVs[i];
- pShader->GetShaderResources().ProcessResources(
+ const auto& pShaderResources = pShader->GetShaderResources();
+#ifdef DILIGENT_DEVELOPMENT
+ m_ShaderResources.emplace_back(pShaderResources);
+#endif
+
+ pShaderResources->ProcessResources(
[&](const SPIRVShaderResourceAttribs& Res, Uint32) //
{
PipelineLayoutVk::ResourceInfo Info;
@@ -872,6 +878,10 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
SPIRV[Res.BindingDecorationOffset] = Info.BindingIndex;
SPIRV[Res.DescriptorSetDecorationOffset] = Info.DescrSetIndex;
+
+#ifdef DILIGENT_DEVELOPMENT
+ m_ResInfo.emplace_back(Info);
+#endif
});
}
}
@@ -1016,4 +1026,35 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const
return false;
}
+#ifdef DILIGENT_DEVELOPMENT
+void PipelineStateVkImpl::DvpVerifySRBResources(SRBArray& SRBs) const
+{
+ auto res_info = m_ResInfo.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
+ {
+ VERIFY_EXPR(res_info->Signature != nullptr);
+ const auto& SignDesc = res_info->Signature->GetDesc();
+ const auto SignBindIndex = SignDesc.BindingIndex;
+ if (auto* pSRB = SRBs[SignBindIndex])
+ {
+ res_info->Signature->DvpValidateCommittedResource(ResAttribs, res_info->ResIndex, pSRB->GetResourceCache());
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("No SRB is bound to binding index ", SignBindIndex, " for signature '", SignDesc.Name, '\'');
+ }
+ }
+ ++res_info;
+ } //
+ );
+ }
+ VERIFY_EXPR(res_info == m_ResInfo.end());
+}
+#endif
+
} // namespace Diligent