summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-05-06 22:04:05 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-05-06 22:04:05 +0000
commit9978d8d7422de1dc3532f872c8b937f0be25d7cc (patch)
treeaffa0c4aa98b6b635f56f00a58ef942d0281aab5 /Graphics/GraphicsEngineVulkan
parentImproved SPIRV shader resource loading (diff)
downloadDiligentCore-9978d8d7422de1dc3532f872c8b937f0be25d7cc.tar.gz
DiligentCore-9978d8d7422de1dc3532f872c8b937f0be25d7cc.zip
First working implementation of pipeline layout initialization in Vulkan
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineLayout.h18
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h7
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp56
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp59
4 files changed, 66 insertions, 74 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
index 625e1f3d..b382f0f3 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
@@ -57,7 +57,11 @@ public:
void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs);
#endif
- void AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType, SHADER_TYPE ShaderType, VkDescriptorType DescriptorType, Uint32 DescriptorCount, Uint32 &DescriptorSet, Uint32 &OffsetFromSetStart);
+ void AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs,
+ SHADER_TYPE ShaderType,
+ Uint32 &DescriptorSet,
+ Uint32 &Binding,
+ std::vector<uint32_t> &SPIRV);
#if 0
// This method should be thread-safe as it does not modify any object state
@@ -138,24 +142,22 @@ private:
void Finalize(const VulkanUtilities::VulkanLogicalDevice &LogicalDevice);
void Release(RenderDeviceVkImpl *pRenderDeviceVk);
- DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType){return m_DescriptorSetLayouts[VarType];}
- const DescriptorSetLayout& GetDescriptorSet(SHADER_VARIABLE_TYPE VarType)const { return m_DescriptorSetLayouts[VarType]; }
+ 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]; }
bool operator == (const DescriptorSetLayoutManager& rhs)const;
bool operator != (const DescriptorSetLayoutManager& rhs)const {return !(*this == rhs);}
size_t GetHash()const;
VkPipelineLayout GetVkPipelineLayout()const{return m_VkPipelineLayout;}
- void AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType,
+ void AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs,
SHADER_TYPE ShaderType,
- VkDescriptorType DescriptorType,
- Uint32 DescriptorCount,
Uint32 &DescriptorSet,
- Uint32 &OffsetFromSetStart);
+ Uint32 &Binding);
private:
IMemoryAllocator &m_MemAllocator;
VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout;
- std::array<DescriptorSetLayout, 3> m_DescriptorSetLayouts;
+ std::array<DescriptorSetLayout, 2> m_DescriptorSetLayouts;
std::vector<VkDescriptorSetLayoutBinding, STDAllocatorRawMem<VkDescriptorSetLayoutBinding>> m_LayoutBindings;
uint8_t m_ActiveSets = 0;
};
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
index a118cc6c..07332660 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
@@ -144,13 +144,6 @@ public:
inline Uint32 GetSize()const{return m_NumResources; }
-#ifdef _DEBUG
- void SetDebugAttribs(Uint32 MaxOffset)
- {
- VERIFY_EXPR(m_NumResources == MaxOffset);
- }
-#endif
-
const Uint32 m_NumResources = 0;
private:
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
index c7a80ace..eb54d855 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
@@ -54,6 +54,29 @@ static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE Shader
}
}
+class ResourceTypeToVkDescriptorType
+{
+public:
+ ResourceTypeToVkDescriptorType()
+ {
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageImage] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::SampledImage] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::AtomicCounter] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateImage] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+ m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateSampler] = VK_DESCRIPTOR_TYPE_SAMPLER;
+ }
+
+ VkDescriptorType operator[](SPIRVShaderResourceAttribs::ResourceType ResType)const
+ {
+ return m_Map[static_cast<int>(ResType)];
+ }
+
+private:
+ std::array<VkDescriptorType, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes> m_Map = {};
+};
+
PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayoutManager(IMemoryAllocator &MemAllocator):
m_MemAllocator(MemAllocator),
m_LayoutBindings(STD_ALLOCATOR_RAW_MEM(VkDescriptorSetLayoutBinding, MemAllocator, "Allocator for Layout Bindings"))
@@ -98,9 +121,9 @@ size_t PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::GetMemor
// msb = n
// MemSize = 2^(n+1)
- MemSize = Uint32{1U << PlatformMisc::GetMSB(NumBindings-1)};
+ MemSize = Uint32{2U << PlatformMisc::GetMSB(NumBindings-1)};
}
- VERIFY_EXPR(NumBindings <= MemSize);
+ VERIFY_EXPR( ((NumBindings & (NumBindings-1)) == 0) && NumBindings == MemSize || NumBindings < MemSize);
#ifdef _DEBUG
static constexpr size_t MinMemSize = 1;
@@ -108,7 +131,7 @@ size_t PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::GetMemor
static constexpr size_t MinMemSize = 16;
#endif
MemSize = std::max(MemSize, MinMemSize);
- return MemSize;
+ return MemSize * sizeof(VkDescriptorSetLayoutBinding);
}
void PipelineLayout::DescriptorSetLayoutManager::DescriptorSetLayout::ReserveMemory(Uint32 NumBindings, IMemoryAllocator &MemAllocator)
@@ -271,14 +294,12 @@ size_t PipelineLayout::DescriptorSetLayoutManager::GetHash()const
return Hash;
}
-void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType,
+void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs,
SHADER_TYPE ShaderType,
- VkDescriptorType DescriptorType,
- Uint32 DescriptorCount,
Uint32 &DescriptorSet,
- Uint32 &OffsetFromSetStart)
+ Uint32 &Binding)
{
- auto& DescrSet = GetDescriptorSet(VarType);
+ auto& DescrSet = GetDescriptorSet(ResAttribs.VarType);
if (DescrSet.SetIndex < 0)
{
DescrSet.SetIndex = m_ActiveSets++;
@@ -287,9 +308,10 @@ void PipelineLayout::DescriptorSetLayoutManager::AllocateResourceSlot(SHADER_VAR
VkDescriptorSetLayoutBinding VkBinding = {};
VkBinding.binding = DescrSet.TotalDescriptors;
- OffsetFromSetStart = DescrSet.TotalDescriptors;
- VkBinding.descriptorType = DescriptorType;
- VkBinding.descriptorCount = DescriptorCount;
+ Binding = DescrSet.TotalDescriptors;
+ static const ResourceTypeToVkDescriptorType ResTypeToVkDescrType;
+ VkBinding.descriptorType = ResTypeToVkDescrType[ResAttribs.Type];
+ VkBinding.descriptorCount = ResAttribs.ArraySize;
VkBinding.stageFlags = ShaderTypeToVkShaderStageFlagBit(ShaderType);
VkBinding.pImmutableSamplers = nullptr;
DescrSet.AddBinding(VkBinding, m_MemAllocator);
@@ -417,15 +439,15 @@ void PipelineLayout::InitStaticSampler(SHADER_TYPE ShaderType, const String &Tex
#endif
-void PipelineLayout::AllocateResourceSlot(SHADER_VARIABLE_TYPE VarType,
+void PipelineLayout::AllocateResourceSlot(const SPIRVShaderResourceAttribs &ResAttribs,
SHADER_TYPE ShaderType,
- VkDescriptorType DescriptorType,
- Uint32 DescriptorCount,
Uint32 &DescriptorSet, // Output parameter
- Uint32 &OffsetFromSetStart // Output parameter
- )
+ Uint32 &Binding, // Output parameter
+ std::vector<uint32_t> &SPIRV)
{
- m_LayoutMgr.AllocateResourceSlot(VarType, ShaderType, DescriptorType, DescriptorCount, DescriptorSet, OffsetFromSetStart);
+ m_LayoutMgr.AllocateResourceSlot(ResAttribs, ShaderType, DescriptorSet, Binding);
+ SPIRV[ResAttribs.BindingDecorationOffset] = Binding;
+ SPIRV[ResAttribs.DescriptorSetDecorationOffset] = DescriptorSet;
#if 0
auto ShaderInd = GetShaderTypeIndex(ShaderType);
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
index 7787ef38..fe5a6fa7 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp
@@ -54,29 +54,6 @@ ShaderResourceLayoutVk::~ShaderResourceLayoutVk()
Resources[r].~VkResource();
}
-class ResourceTypeToVkDescriptorType
-{
-public:
- ResourceTypeToVkDescriptorType()
- {
- m_Map[SPIRVShaderResourceAttribs::ResourceType::UniformBuffer] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageBuffer] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::StorageImage] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::SampledImage] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::AtomicCounter] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateImage] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
- m_Map[SPIRVShaderResourceAttribs::ResourceType::SeparateSampler] = VK_DESCRIPTOR_TYPE_SAMPLER;
- }
-
- VkDescriptorType operator[](SPIRVShaderResourceAttribs::ResourceType ResType)const
- {
- return m_Map[static_cast<int>(ResType)];
- }
-
-private:
- std::array<VkDescriptorType, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes> m_Map = {};
-};
-
void ShaderResourceLayoutVk::AllocateMemory(IMemoryAllocator &Allocator)
{
VERIFY( &m_ResourceBuffer.get_deleter().m_Allocator == &Allocator, "Inconsistent memory allocators" );
@@ -176,7 +153,7 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi
m_pResourceCache = pResourceCache;
m_pLogicalDevice = LogicalDevice.GetSharedPtr();
- VERIFY_EXPR( (pResourceCache != nullptr) ^ (pPipelineLayout != nullptr) );
+ VERIFY_EXPR( (pResourceCache != nullptr) ^ (pPipelineLayout != nullptr && pSPIRV != nullptr) );
Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
@@ -214,7 +191,7 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi
VERIFY_EXPR(IsAllowedType(SepImg.VarType, AllowedTypeBits));
++m_NumResources[SepImg.VarType];
},
- [&](const SPIRVShaderResourceAttribs &SepSmpl, Uint32)
+ [&](const SPIRVShaderResourceAttribs &SepSmpl, Uint32)
{
VERIFY_EXPR(IsAllowedType(SepSmpl.VarType, AllowedTypeBits));
++m_NumResources[SepSmpl.VarType];
@@ -225,17 +202,16 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi
AllocateMemory(LayoutDataAllocator);
std::array<Uint32, SHADER_VARIABLE_TYPE_NUM_TYPES> CurrResInd = {};
- std::array<Uint32, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC + 1> StaticResCacheSetSizes = {};
+ std::array<Uint32, SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes > StaticResCacheSetSizes = {};
auto AddResource = [&](const SPIRVShaderResourceAttribs &Attribs)
{
Uint32 Binding = 0;
Uint32 DescriptorSet = 0;
- static const ResourceTypeToVkDescriptorType ResTypeToVkDescType;
- VkDescriptorType DescriptorType = ResTypeToVkDescType[Attribs.Type];
if (pPipelineLayout)
{
- pPipelineLayout->AllocateResourceSlot(Attribs.VarType, m_pResources->GetShaderType(), DescriptorType, Attribs.ArraySize, DescriptorSet, Binding);
+ VERIFY_EXPR(pSPIRV != nullptr);
+ pPipelineLayout->AllocateResourceSlot(Attribs, m_pResources->GetShaderType(), DescriptorSet, Binding, *pSPIRV);
VERIFY(DescriptorSet <= std::numeric_limits<decltype(VkResource::DescriptorSet)>::max(), "Descriptor set (", DescriptorSet, ") excceeds representable max value");
VERIFY(Binding <= std::numeric_limits<decltype(VkResource::Binding)>::max(), "Binding (", Binding, ") excceeds representable max value");
}
@@ -243,19 +219,16 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi
{
// If pipeline layout is not provided - use artifial layout to store
// static shader resources:
- // Separate samplers at index VK_DESCRIPTOR_TYPE_SAMPLER (0)
- // SampledImages at index VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER (1)
- // Separate images at index VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE (2)
- // Storage images at index VK_DESCRIPTOR_TYPE_STORAGE_IMAGE (3)
- // Index VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER (4) is unused
- // Index VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER (5) is unused
- // Uniform buffers at index VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER (6)
- // Storage buffers at index VK_DESCRIPTOR_TYPE_STORAGE_BUFFER (7)
- // Index VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC (8) is unused
- // Index VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC (9) is unused
+ // Uniform buffers at index SPIRVShaderResourceAttribs::ResourceType::UniformBuffer (0)
+ // Storage buffers at index SPIRVShaderResourceAttribs::ResourceType::StorageBuffer (1)
+ // Storage images at index SPIRVShaderResourceAttribs::ResourceType::StorageImage (2)
+ // Sampled images at index SPIRVShaderResourceAttribs::ResourceType::SampledImage (3)
+ // Atomic counters at index SPIRVShaderResourceAttribs::ResourceType::AtomicCounter (4)
+ // Separate images at index SPIRVShaderResourceAttribs::ResourceType::SeparateImage (5)
+ // Separate samplers at index SPIRVShaderResourceAttribs::ResourceType::SeparateSampler(6)
VERIFY_EXPR(m_pResourceCache != nullptr);
- DescriptorSet = DescriptorType;
+ DescriptorSet = Attribs.Type;
Binding = StaticResCacheSetSizes[DescriptorSet];
StaticResCacheSetSizes[DescriptorSet] += Attribs.ArraySize;
}
@@ -318,9 +291,11 @@ void ShaderResourceLayoutVk::Initialize(const VulkanUtilities::VulkanLogicalDevi
VERIFY_EXPR(pPipelineLayout == nullptr && pSPIRV == nullptr);
m_pResourceCache->Initialize(GetRawAllocator(), static_cast<Uint32>(StaticResCacheSetSizes.size()), StaticResCacheSetSizes.data());
#ifdef _DEBUG
- for(VkDescriptorType DescriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; DescriptorType <= VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; DescriptorType = static_cast<VkDescriptorType>(DescriptorType+1))
+ for(SPIRVShaderResourceAttribs::ResourceType ResType = SPIRVShaderResourceAttribs::ResourceType::UniformBuffer;
+ ResType < SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes;
+ ResType = static_cast<SPIRVShaderResourceAttribs::ResourceType>(ResType +1))
{
- m_pResourceCache->GetDescriptorSet(DescriptorType).SetDebugAttribs(StaticResCacheSetSizes[DescriptorType]);
+ VERIFY_EXPR(m_pResourceCache->GetDescriptorSet(ResType).GetSize() == StaticResCacheSetSizes[ResType]);
}
#endif
}