summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2021-01-26 07:13:23 +0000
committerazhirnov <zh1dron@gmail.com>2021-01-26 07:13:23 +0000
commitf8491bc2e3bd00dff8d86ad7f3da266005e01483 (patch)
tree5235768a948e41fc2c9516433148f5fa30372daa /Graphics
parentremoved empty signature, added test for partially compatible pipeline layouts (diff)
downloadDiligentCore-f8491bc2e3bd00dff8d86ad7f3da266005e01483.tar.gz
DiligentCore-f8491bc2e3bd00dff8d86ad7f3da266005e01483.zip
added immutable samplers to descriptor set layout, fixed PRS tests
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp25
-rw-r--r--Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp1
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp33
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp17
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp42
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp11
6 files changed, 109 insertions, 20 deletions
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
index bded504e..af4a04ea 100644
--- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
+++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
@@ -550,16 +550,19 @@ const Char* GetShaderVariableTypeLiteralName(SHADER_RESOURCE_VARIABLE_TYPE VarTy
const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType, bool bGetFullName)
{
+ static_assert(SHADER_RESOURCE_TYPE_LAST == SHADER_RESOURCE_TYPE_ACCEL_STRUCT, "Please update the switch below to handle the new shader resource type");
switch (ResourceType)
{
// clang-format off
- case SHADER_RESOURCE_TYPE_UNKNOWN: return bGetFullName ? "SHADER_RESOURCE_TYPE_UNKNOWN" : "unknown";
- case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return bGetFullName ? "SHADER_RESOURCE_TYPE_CONSTANT_BUFFER" : "constant buffer";
- case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_SRV" : "texture SRV";
- case SHADER_RESOURCE_TYPE_BUFFER_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_SRV" : "buffer SRV";
- case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_UAV" : "texture UAV";
- case SHADER_RESOURCE_TYPE_BUFFER_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_UAV" : "buffer UAV";
- case SHADER_RESOURCE_TYPE_SAMPLER: return bGetFullName ? "SHADER_RESOURCE_TYPE_SAMPLER" : "sampler";
+ case SHADER_RESOURCE_TYPE_UNKNOWN: return bGetFullName ? "SHADER_RESOURCE_TYPE_UNKNOWN" : "unknown";
+ case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return bGetFullName ? "SHADER_RESOURCE_TYPE_CONSTANT_BUFFER" : "constant buffer";
+ case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_SRV" : "texture SRV";
+ case SHADER_RESOURCE_TYPE_BUFFER_SRV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_SRV" : "buffer SRV";
+ case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_TEXTURE_UAV" : "texture UAV";
+ case SHADER_RESOURCE_TYPE_BUFFER_UAV: return bGetFullName ? "SHADER_RESOURCE_TYPE_BUFFER_UAV" : "buffer UAV";
+ case SHADER_RESOURCE_TYPE_SAMPLER: return bGetFullName ? "SHADER_RESOURCE_TYPE_SAMPLER" : "sampler";
+ case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return bGetFullName ? "SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT" : "input attachment";
+ case SHADER_RESOURCE_TYPE_ACCEL_STRUCT: return bGetFullName ? "SHADER_RESOURCE_TYPE_ACCEL_STRUCT" : "acceleration structure";
// clang-format on
default:
UNEXPECTED("Unexepcted resource type (", Uint32{ResourceType}, ")");
@@ -569,6 +572,7 @@ const Char* GetShaderResourceTypeLiteralName(SHADER_RESOURCE_TYPE ResourceType,
const Char* GetFilterTypeLiteralName(FILTER_TYPE FilterType, bool bGetFullName)
{
+ static_assert(FILTER_TYPE_NUM_FILTERS == 13, "Please update the switch below to handle the new filter type");
switch (FilterType)
{
// clang-format off
@@ -594,6 +598,7 @@ const Char* GetFilterTypeLiteralName(FILTER_TYPE FilterType, bool bGetFullName)
const Char* GetTextureAddressModeLiteralName(TEXTURE_ADDRESS_MODE AddressMode, bool bGetFullName)
{
+ static_assert(TEXTURE_ADDRESS_NUM_MODES == 6, "Please update the switch below to handle the new texture address mode");
switch (AddressMode)
{
// clang-format off
@@ -612,6 +617,7 @@ const Char* GetTextureAddressModeLiteralName(TEXTURE_ADDRESS_MODE AddressMode, b
const Char* GetComparisonFunctionLiteralName(COMPARISON_FUNCTION ComparisonFunc, bool bGetFullName)
{
+ static_assert(COMPARISON_FUNC_NUM_FUNCTIONS == 9, "Please update the switch below to handle the new comparison function");
switch (ComparisonFunc)
{
// clang-format off
@@ -636,6 +642,7 @@ const Char* GetStencilOpLiteralName(STENCIL_OP StencilOp)
#define STENCIL_OP_TO_STR(Op) \
case Op: return #Op
+ static_assert(STENCIL_OP_NUM_OPS == 9, "Please update the switch below to handle the new stencil op");
switch (StencilOp)
{
STENCIL_OP_TO_STR(STENCIL_OP_UNDEFINED);
@@ -660,6 +667,7 @@ const Char* GetBlendFactorLiteralName(BLEND_FACTOR BlendFactor)
#define BLEND_FACTOR_TO_STR(Factor) \
case Factor: return #Factor
+ static_assert(BLEND_FACTOR_NUM_FACTORS == 18, "Please update the switch below to handle the new blend factor");
switch (BlendFactor)
{
BLEND_FACTOR_TO_STR(BLEND_FACTOR_UNDEFINED);
@@ -693,6 +701,7 @@ const Char* GetBlendOperationLiteralName(BLEND_OPERATION BlendOp)
#define BLEND_OP_TO_STR(BlendOp) \
case BlendOp: return #BlendOp
+ static_assert(BLEND_OPERATION_NUM_OPERATIONS == 6, "Please update the switch below to handle the new blend op");
switch (BlendOp)
{
BLEND_OP_TO_STR(BLEND_OPERATION_UNDEFINED);
@@ -714,6 +723,7 @@ const Char* GetFillModeLiteralName(FILL_MODE FillMode)
#define FILL_MODE_TO_STR(Mode) \
case Mode: return #Mode
+ static_assert(FILL_MODE_NUM_MODES == 3, "Please update the switch below to handle the new filter mode");
switch (FillMode)
{
FILL_MODE_TO_STR(FILL_MODE_UNDEFINED);
@@ -732,6 +742,7 @@ const Char* GetCullModeLiteralName(CULL_MODE CullMode)
#define CULL_MODE_TO_STR(Mode) \
case Mode: return #Mode
+ static_assert(CULL_MODE_NUM_MODES == 4, "Please update the switch below to handle the new cull mode");
switch (CullMode)
{
CULL_MODE_TO_STR(CULL_MODE_UNDEFINED);
diff --git a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp
index 6578e0d1..0913f5d7 100644
--- a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp
+++ b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp
@@ -93,6 +93,7 @@ public:
bool IsUsingSeparateSamplers() const { return !IsUsingCombinedSamplers(); }
Uint32 GetTotalResourceCount() const { return this->m_Desc.NumResources; }
+ Uint32 GetImmutableSamplerCount() const { return this->m_Desc.NumImmutableSamplers; }
std::pair<Uint32, Uint32> GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE VarType) const
{
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
index 4bdb1865..3dfb7a4b 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp
@@ -83,6 +83,7 @@ public:
Uint32 GetDynamicStorageBufferCount() const { return m_DynamicStorageBufferCount; }
Uint32 GetNumDescriptorSets() const;
+ SHADER_TYPE GetActiveShaderStages() const { return m_ShaderStages; }
Uint32 GetNumShaderStages() const { return m_NumShaderStages; }
SHADER_TYPE GetShaderStageType(Uint32 StageIndex) const;
@@ -92,16 +93,15 @@ public:
SRB = 1 // in SRB
};
- // sizeof(ResourceAttribs) == 12, x64
+ // sizeof(ResourceAttribs) == 16, x64
struct ResourceAttribs
{
private:
static constexpr Uint32 _DescrTypeBits = 4;
static constexpr Uint32 _DescrSetBits = 1;
static constexpr Uint32 _BindingIndexBits = 16;
- static constexpr Uint32 _SamplerIndBits = 10;
+ static constexpr Uint32 _SamplerIndBits = 16;
static constexpr Uint32 _SamplerAssignedBits = 1;
- static_assert((_DescrTypeBits + _DescrSetBits + _BindingIndexBits + _SamplerIndBits + _SamplerAssignedBits) % 8 == 0, "Fields are not properly packed");
static_assert((1u << _DescrTypeBits) >= static_cast<Uint32>(DescriptorType::Count), "Not enough bits to store DescriptorType values");
static_assert((1u << _DescrSetBits) >= MAX_DESCR_SET_PER_SIGNATURE, "Not enough bits to store descriptor set index");
@@ -164,6 +164,28 @@ public:
return m_Desc.Resources[ResIndex];
}
+ struct ImmutableSamplerAttribs
+ {
+ RefCntAutoPtr<ISampler> Ptr;
+ Uint32 DescrSet : 16;
+ Uint32 BindingIndex : 16;
+
+ ImmutableSamplerAttribs() :
+ DescrSet{~0u}, BindingIndex{~0u} {}
+ };
+
+ const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const
+ {
+ VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers);
+ return m_ImmutableSamplers[SampIndex];
+ }
+
+ const ImmutableSamplerDesc& GetImmutableSamplerDesc(Uint32 SampIndex) const
+ {
+ VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers);
+ return m_Desc.ImmutableSamplers[SampIndex];
+ }
+
VkDescriptorSetLayout GetStaticVkDescriptorSetLayout() const { return m_VkDescSetLayouts[0]; }
VkDescriptorSetLayout GetDynamicVkDescriptorSetLayout() const { return m_VkDescSetLayouts[1]; }
@@ -275,10 +297,7 @@ private:
ShaderResourceCacheVk* m_pResourceCache = nullptr;
ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages]
-
- using ImmutableSamplerPtrType = RefCntAutoPtr<ISampler>;
-
- ImmutableSamplerPtrType* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
+ ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
SRBMemoryAllocator m_SRBMemAllocator;
};
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
index 7d1d2c7c..969fe16e 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp
@@ -33,6 +33,7 @@
#include "PipelineLayoutVk.hpp"
#include "RenderDeviceVkImpl.hpp"
#include "VulkanTypeConversions.hpp"
+#include "StringTools.hpp"
namespace Diligent
{
@@ -175,6 +176,22 @@ bool PipelineLayoutVk::GetResourceInfo(const char* Name, SHADER_TYPE Stage, Reso
Info.Type = ResDesc.ResourceType;
Info.BindingIndex = Attr.BindingIndex;
Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet;
+ Info.Signature = pSignature;
+ return true;
+ }
+ }
+
+ 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) && StreqSuff(Name, Desc.SamplerOrTextureName, pSignature->GetCombinedSamplerSuffix()))
+ {
+ Info.Type = SHADER_RESOURCE_TYPE_SAMPLER;
+ Info.BindingIndex = Attr.BindingIndex;
+ Info.DescrSetIndex = m_FirstDescrSetIndex[i] + Attr.DescrSet;
+ Info.Signature = pSignature;
return true;
}
}
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
index d3426240..b51d74b6 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp
@@ -283,7 +283,7 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount
// Reserve at least 1 element because m_pResourceAttribs must hold a pointer to memory
MemPool.AddSpace<ResourceAttribs>(std::max(1u, Desc.NumResources));
- MemPool.AddSpace<ImmutableSamplerPtrType>(Desc.NumImmutableSamplers);
+ MemPool.AddSpace<ImmutableSamplerAttribs>(Desc.NumImmutableSamplers);
ReserveSpaceForDescription(MemPool, Desc);
@@ -335,7 +335,7 @@ PipelineResourceSignatureVkImpl::PipelineResourceSignatureVkImpl(IReferenceCount
MemPool.Reserve();
m_pResourceAttribs = MemPool.Allocate<ResourceAttribs>(std::max(1u, m_Desc.NumResources));
- m_ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerPtrType>(m_Desc.NumImmutableSamplers);
+ m_ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerAttribs>(m_Desc.NumImmutableSamplers);
// The memory is now owned by PipelineResourceSignatureVkImpl and will be freed by Destruct().
auto* Ptr = MemPool.ReleaseOwnership();
@@ -457,10 +457,10 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache
{
auto& ImmutableSampler = m_ImmutableSamplers[SrcImmutableSamplerInd];
const auto& ImmutableSamplerDesc = m_Desc.ImmutableSamplers[SrcImmutableSamplerInd].Desc;
- if (!ImmutableSampler)
- GetDevice()->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler);
+ if (!ImmutableSampler.Ptr)
+ GetDevice()->CreateSampler(ImmutableSamplerDesc, &ImmutableSampler.Ptr);
- pVkImmutableSamplers = TempAllocator.ConstructArray<VkSampler>(ResDesc.ArraySize, ImmutableSampler.RawPtr<SamplerVkImpl>()->GetVkSampler());
+ pVkImmutableSamplers = TempAllocator.ConstructArray<VkSampler>(ResDesc.ArraySize, ImmutableSampler.Ptr.RawPtr<SamplerVkImpl>()->GetVkSampler());
}
}
@@ -512,6 +512,36 @@ void PipelineResourceSignatureVkImpl::CreateLayout(const CacheOffsetsType& Cache
VERIFY_EXPR(BindingIndices[CACHE_GROUP_DYN_SB_DYN_VAR] == BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR]);
VERIFY_EXPR(BindingIndices[CACHE_GROUP_OTHER_DYN_VAR] == BindingCount[CACHE_GROUP_DYN_UB_DYN_VAR] + BindingCount[CACHE_GROUP_DYN_SB_DYN_VAR] + BindingCount[CACHE_GROUP_OTHER_DYN_VAR]);
+ // Add immutable samplers that is not exist in m_Desc.Resources
+ // If static/mutable descriptor set layout is empty, then add samplers to dynamic layout.
+ for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
+ {
+ auto& ImmutableSampler = m_ImmutableSamplers[i];
+ const auto& SamplerDesc = m_Desc.ImmutableSamplers[i];
+ const Uint32 SetIdx = (DSMapping[0] < MAX_DESCR_SET_PER_SIGNATURE ? 0 : 1);
+ auto& BindingIndex = BindingIndices[SetIdx * 3 + 2];
+
+ if (ImmutableSampler.Ptr)
+ continue;
+
+ GetDevice()->CreateSampler(SamplerDesc.Desc, &ImmutableSampler.Ptr);
+
+ ImmutableSampler.DescrSet = DSMapping[SetIdx];
+ ImmutableSampler.BindingIndex = BindingIndex;
+
+ VERIFY_EXPR(ImmutableSampler.BindingIndex == BindingIndex);
+ ++BindingIndex;
+
+ vkSetLayoutBindings[SetIdx].emplace_back();
+ auto& vkSetLayoutBinding = vkSetLayoutBindings[SetIdx].back();
+
+ vkSetLayoutBinding.binding = ImmutableSampler.BindingIndex;
+ vkSetLayoutBinding.descriptorCount = 1;
+ vkSetLayoutBinding.stageFlags = ShaderTypesToVkShaderStageFlags(SamplerDesc.ShaderStages);
+ vkSetLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+ vkSetLayoutBinding.pImmutableSamplers = TempAllocator.Construct<VkSampler>(ImmutableSampler.Ptr.RawPtr<SamplerVkImpl>()->GetVkSampler());
+ }
+
if (m_Desc.SRBAllocationGranularity > 1)
{
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {};
@@ -647,7 +677,7 @@ void PipelineResourceSignatureVkImpl::Destruct()
for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
{
- m_ImmutableSamplers[i].~ImmutableSamplerPtrType();
+ m_ImmutableSamplers[i].~ImmutableSamplerAttribs();
}
m_ImmutableSamplers = nullptr;
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index dc184e1b..41585909 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -857,6 +857,17 @@ void PipelineStateVkImpl::InitPipelineLayout(const PipelineStateCreateInfo& Crea
"' that is not present in any pipeline resource signature that is used to create pipeline state '",
m_Desc.Name, "'.");
}
+
+ SHADER_RESOURCE_TYPE Type;
+ PIPELINE_RESOURCE_FLAGS Flags;
+ GetShaderResourceTypeAndFlags(Res.Type, Type, Flags);
+ if (Type != Info.Type)
+ {
+ LOG_ERROR_AND_THROW("Shader '", pShader->GetDesc().Name, "' contains resource with name '", Res.Name,
+ "' and type '", GetShaderResourceTypeLiteralName(Type), "' that is not compatible with type '",
+ GetShaderResourceTypeLiteralName(Info.Type), "' in pipeline resource signature '", Info.Signature->GetDesc().Name, "'.");
+ }
+
SPIRV[Res.BindingDecorationOffset] = Info.BindingIndex;
SPIRV[Res.DescriptorSetDecorationOffset] = Info.DescrSetIndex;
});