diff --git a/Source/Engine/Graphics/Shaders/GPUShader.h b/Source/Engine/Graphics/Shaders/GPUShader.h
index 35f239e26..28ef2ee62 100644
--- a/Source/Engine/Graphics/Shaders/GPUShader.h
+++ b/Source/Engine/Graphics/Shaders/GPUShader.h
@@ -12,7 +12,7 @@ class GPUShaderProgram;
///
/// The runtime version of the shaders cache supported by the all graphics back-ends. The same for all the shader cache formats (easier to sync and validate).
///
-#define GPU_SHADER_CACHE_VERSION 8
+#define GPU_SHADER_CACHE_VERSION 9
///
/// Represents collection of shader programs with permutations and custom names.
diff --git a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.cpp
index 37ef2722e..171e60b8b 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.cpp
@@ -8,7 +8,6 @@
#include "GPUDeviceVulkan.h"
#include "RenderToolsVulkan.h"
#include "GPUContextVulkan.h"
-#include "GPUAdapterVulkan.h"
#include "CmdBufferVulkan.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Engine/Engine.h"
@@ -30,39 +29,48 @@ void DescriptorSetLayoutInfoVulkan::CacheTypesUsageID()
_typesUsageID = id;
}
-void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor)
-{
- _layoutTypes[descriptor.descriptorType]++;
-
- if (descriptorSetIndex >= _setLayouts.Count())
- {
- _setLayouts.Resize(descriptorSetIndex + 1);
- }
-
- SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
- descSetLayout.LayoutBindings.Add(descriptor);
-
- _hash = Crc::MemCrc32(&descriptor, sizeof(descriptor), _hash);
-}
-
void DescriptorSetLayoutInfoVulkan::AddBindingsForStage(VkShaderStageFlagBits stageFlags, DescriptorSet::Stage descSet, const SpirvShaderDescriptorInfo* descriptorInfo)
{
- const int32 descriptorSetIndex = (int32)descSet;
+ const int32 descriptorSetIndex = descSet;
+ if (descriptorSetIndex >= _setLayouts.Count())
+ _setLayouts.Resize(descriptorSetIndex + 1);
+ SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
VkDescriptorSetLayoutBinding binding;
- binding.descriptorCount = 1;
binding.stageFlags = stageFlags;
binding.pImmutableSamplers = nullptr;
-
for (uint32 descriptorIndex = 0; descriptorIndex < descriptorInfo->DescriptorTypesCount; descriptorIndex++)
{
auto& descriptor = descriptorInfo->DescriptorTypes[descriptorIndex];
binding.binding = descriptorIndex;
binding.descriptorType = descriptor.DescriptorType;
- AddDescriptor(descriptorSetIndex, binding);
+ binding.descriptorCount = descriptor.Count;
+
+ _layoutTypes[binding.descriptorType]++;
+ descSetLayout.LayoutBindings.Add(binding);
+ _hash = Crc::MemCrc32(&binding, sizeof(binding), _hash);
}
}
+bool DescriptorSetLayoutInfoVulkan::operator==(const DescriptorSetLayoutInfoVulkan& other) const
+{
+ if (other._setLayouts.Count() != _setLayouts.Count())
+ return false;
+ if (other._typesUsageID != _typesUsageID)
+ return false;
+
+ for (int32 index = 0; index < other._setLayouts.Count(); index++)
+ {
+ const int32 bindingsCount = _setLayouts[index].LayoutBindings.Count();
+ if (other._setLayouts[index].LayoutBindings.Count() != bindingsCount)
+ return false;
+ if (bindingsCount != 0 && Platform::MemoryCompare(other._setLayouts[index].LayoutBindings.Get(), _setLayouts[index].LayoutBindings.Get(), bindingsCount * sizeof(VkDescriptorSetLayoutBinding)))
+ return false;
+ }
+
+ return true;
+}
+
DescriptorSetLayoutVulkan::DescriptorSetLayoutVulkan(GPUDeviceVulkan* device)
: _device(device)
{
@@ -370,20 +378,20 @@ PipelineLayoutVulkan::~PipelineLayoutVulkan()
}
}
-uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffset)
+uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, VkBufferView* texelBufferView, uint8* bindingToDynamicOffset)
{
- ASSERT(info.DescriptorTypesCount <= 64);
+ ASSERT(info.DescriptorTypesCount <= SpirvShaderDescriptorInfo::MaxDescriptors);
WriteDescriptors = writeDescriptors;
WritesCount = info.DescriptorTypesCount;
BindingToDynamicOffset = bindingToDynamicOffset;
-
uint32 dynamicOffsetIndex = 0;
for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
{
+ const auto& descriptor = info.DescriptorTypes[i];
writeDescriptors->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptors->dstBinding = i;
- writeDescriptors->descriptorCount = 1;
- writeDescriptors->descriptorType = info.DescriptorTypes[i].DescriptorType;
+ writeDescriptors->descriptorCount = descriptor.Count;
+ writeDescriptors->descriptorType = descriptor.DescriptorType;
switch (writeDescriptors->descriptorType)
{
@@ -394,25 +402,28 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- writeDescriptors->pBufferInfo = bufferInfo++;
+ writeDescriptors->pBufferInfo = bufferInfo;
+ bufferInfo += descriptor.Count;
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
- writeDescriptors->pImageInfo = imageInfo++;
+ writeDescriptors->pImageInfo = imageInfo;
+ imageInfo += descriptor.Count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ writeDescriptors->pTexelBufferView = texelBufferView;
+ texelBufferView += descriptor.Count;
break;
default:
- CRASH;
+ CRASH;
break;
}
writeDescriptors++;
}
-
return dynamicOffsetIndex;
}
diff --git a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h
index da95ac48b..695da1be9 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h
+++ b/Source/Engine/GraphicsDevice/Vulkan/DescriptorSetVulkan.h
@@ -117,7 +117,6 @@ protected:
uint32 _typesUsageID = ~0;
void CacheTypesUsageID();
- void AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor);
public:
@@ -138,11 +137,6 @@ public:
return _setLayouts;
}
- inline const uint32* GetLayoutTypes() const
- {
- return _layoutTypes;
- }
-
inline uint32 GetTypesUsageID() const
{
return _typesUsageID;
@@ -160,25 +154,7 @@ public:
_setLayouts = info._setLayouts;
}
- inline bool operator ==(const DescriptorSetLayoutInfoVulkan& other) const
- {
- if (other._setLayouts.Count() != _setLayouts.Count())
- return false;
- if (other._typesUsageID != _typesUsageID)
- return false;
-
- for (int32 index = 0; index < other._setLayouts.Count(); index++)
- {
- const int32 bindingsCount = _setLayouts[index].LayoutBindings.Count();
- if (other._setLayouts[index].LayoutBindings.Count() != bindingsCount)
- return false;
-
- if (bindingsCount != 0 && Platform::MemoryCompare(other._setLayouts[index].LayoutBindings.Get(), _setLayouts[index].LayoutBindings.Get(), bindingsCount * sizeof(VkDescriptorSetLayoutBinding)))
- return false;
- }
-
- return true;
- }
+ bool operator==(const DescriptorSetLayoutInfoVulkan& other) const;
friend inline uint32 GetHash(const DescriptorSetLayoutInfoVulkan& key)
{
@@ -413,6 +389,7 @@ struct DescriptorSetWriteContainerVulkan
{
Array DescriptorImageInfo;
Array DescriptorBufferInfo;
+ Array DescriptorTexelBufferView;
Array DescriptorWrites;
Array BindingToDynamicOffset;
@@ -420,6 +397,7 @@ struct DescriptorSetWriteContainerVulkan
{
DescriptorImageInfo.Resize(0);
DescriptorBufferInfo.Resize(0);
+ DescriptorTexelBufferView.Resize(0);
DescriptorWrites.Resize(0);
BindingToDynamicOffset.Resize(0);
}
@@ -436,26 +414,24 @@ public:
public:
- uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, byte* bindingToDynamicOffset);
+ uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, VkBufferView* texelBufferView, byte* bindingToDynamicOffset);
- bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
+ bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
- VkDescriptorBufferInfo* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo);
- ASSERT(bufferInfo);
+ auto* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
return edited;
}
- bool WriteDynamicUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 dynamicOffset) const
+ bool WriteDynamicUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 dynamicOffset, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
- VkDescriptorBufferInfo* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo);
- ASSERT(bufferInfo);
+ auto* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
@@ -464,63 +440,61 @@ public:
return edited;
}
- bool WriteSampler(uint32 descriptorIndex, VkSampler sampler) const
+ bool WriteSampler(uint32 descriptorIndex, VkSampler sampler, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
- VkDescriptorImageInfo* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo);
- ASSERT(imageInfo);
+ auto* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->sampler, sampler);
return edited;
}
- bool WriteImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout) const
+ bool WriteImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
- VkDescriptorImageInfo* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo);
- ASSERT(imageInfo);
+ auto* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
return edited;
}
- bool WriteStorageImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout) const
+ bool WriteStorageImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
- VkDescriptorImageInfo* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo);
- ASSERT(imageInfo);
+ auto* imageInfo = const_cast(WriteDescriptors[descriptorIndex].pImageInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
return edited;
}
- bool WriteStorageTexelBuffer(uint32 descriptorIndex, const VkBufferView* bufferView) const
+ bool WriteStorageTexelBuffer(uint32 descriptorIndex, VkBufferView bufferView, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
- WriteDescriptors[descriptorIndex].pTexelBufferView = bufferView;
+ auto* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
+ *bufferInfo = bufferView;
return true;
}
- bool WriteStorageBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
+ bool WriteStorageBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
- VkDescriptorBufferInfo* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo);
- ASSERT(bufferInfo);
+ auto* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pBufferInfo + index);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
return edited;
}
- bool WriteUniformTexelBuffer(uint32 descriptorIndex, const VkBufferView* view) const
+ bool WriteUniformTexelBuffer(uint32 descriptorIndex, VkBufferView view, uint32 index = 0) const
{
ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
- return DescriptorSet::CopyAndReturnNotEqual(WriteDescriptors[descriptorIndex].pTexelBufferView, view);
+ auto* bufferInfo = const_cast(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
+ return DescriptorSet::CopyAndReturnNotEqual(*bufferInfo, view);
}
void SetDescriptorSet(VkDescriptorSet descriptorSet) const
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp
index 8cdf5969d..389d19d3f 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp
@@ -44,10 +44,10 @@ void GPUBufferViewVulkan::Release()
#endif
}
-void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
+void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{
ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
- bufferView = &View;
+ bufferView = View;
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
}
@@ -60,10 +60,10 @@ void GPUBufferViewVulkan::DescriptorAsStorageBuffer(GPUContextVulkan* context, V
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
}
-void GPUBufferViewVulkan::DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
+void GPUBufferViewVulkan::DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{
ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
- bufferView = &View;
+ bufferView = View;
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
}
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h
index a495cf46c..9b78c266f 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h
@@ -48,9 +48,9 @@ public:
}
// [DescriptorOwnerResourceVulkan]
- void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) override;
+ void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
void DescriptorAsStorageBuffer(GPUContextVulkan* context, VkBuffer& buffer, VkDeviceSize& offset, VkDeviceSize& range) override;
- void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) override;
+ void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
};
///
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
index f392a256a..e82cc6e24 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp
@@ -444,117 +444,122 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
const auto& descriptor = descriptorInfo.DescriptorTypes[i];
const int32 descriptorIndex = descriptor.Binding;
DescriptorOwnerResourceVulkan** handles = _handles[(int32)descriptor.BindingType];
-
- switch (descriptor.DescriptorType)
+ for (uint32 index = 0; index < descriptor.Count; index++)
{
- case VK_DESCRIPTOR_TYPE_SAMPLER:
- {
- // Sampler
- const VkSampler sampler = _samplerHandles[descriptor.Slot];
- ASSERT(sampler);
- needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler);
- break;
- }
- case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
- {
- // Shader Resource (Texture)
- auto handle = (GPUTextureViewVulkan*)handles[descriptor.Slot];
- if (!handle)
+ const int32 slot = descriptor.Slot + index;
+ switch (descriptor.DescriptorType)
{
- const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
- switch (descriptor.ResourceType)
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ {
+ // Sampler
+ const VkSampler sampler = _samplerHandles[slot];
+ ASSERT(sampler);
+ needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler, index);
+ break;
+ }
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ {
+ // Shader Resource (Texture)
+ auto handle = (GPUTextureViewVulkan*)handles[slot];
+ if (!handle)
{
- case SpirvShaderResourceType::Texture1D:
- case SpirvShaderResourceType::Texture2D:
- handle = static_cast(dummy->View(0));
- break;
- case SpirvShaderResourceType::Texture3D:
- handle = static_cast(dummy->ViewVolume());
- break;
- case SpirvShaderResourceType::TextureCube:
- case SpirvShaderResourceType::Texture1DArray:
- case SpirvShaderResourceType::Texture2DArray:
- handle = static_cast(dummy->ViewArray());
- break;
+ const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
+ switch (descriptor.ResourceType)
+ {
+ case SpirvShaderResourceType::Texture1D:
+ case SpirvShaderResourceType::Texture2D:
+ handle = static_cast(dummy->View(0));
+ break;
+ case SpirvShaderResourceType::Texture3D:
+ handle = static_cast(dummy->ViewVolume());
+ break;
+ case SpirvShaderResourceType::TextureCube:
+ case SpirvShaderResourceType::Texture1DArray:
+ case SpirvShaderResourceType::Texture2DArray:
+ handle = static_cast(dummy->ViewArray());
+ break;
+ }
}
+ VkImageView imageView;
+ VkImageLayout layout;
+ handle->DescriptorAsImage(this, imageView, layout);
+ ASSERT(imageView != VK_NULL_HANDLE);
+ needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout, index);
+ break;
}
- VkImageView imageView;
- VkImageLayout layout;
- handle->DescriptorAsImage(this, imageView, layout);
- ASSERT(imageView != VK_NULL_HANDLE);
- needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout);
- break;
- }
- case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- {
- // Shader Resource (Buffer)
- auto sr = handles[descriptor.Slot];
- if (!sr)
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
{
- const auto dummy = _device->HelperResources.GetDummyBuffer();
- sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ // Shader Resource (Buffer)
+ auto sr = handles[slot];
+ if (!sr)
+ {
+ const auto dummy = _device->HelperResources.GetDummyBuffer();
+ sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ }
+ VkBufferView bufferView;
+ sr->DescriptorAsUniformTexelBuffer(this, bufferView);
+ ASSERT(bufferView != VK_NULL_HANDLE);
+ needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView, index);
+ break;
}
- const VkBufferView* bufferView;
- sr->DescriptorAsUniformTexelBuffer(this, bufferView);
- needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView);
- break;
- }
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
- {
- // Unordered Access (Texture)
- auto ua = handles[descriptor.Slot];
- ASSERT(ua);
- VkImageView imageView;
- VkImageLayout layout;
- ua->DescriptorAsStorageImage(this, imageView, layout);
- needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout);
- break;
- }
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- {
- // Unordered Access (Buffer)
- auto ua = handles[descriptor.Slot];
- if (!ua)
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
{
- const auto dummy = _device->HelperResources.GetDummyBuffer();
- ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ // Unordered Access (Texture)
+ auto ua = handles[slot];
+ ASSERT(ua);
+ VkImageView imageView;
+ VkImageLayout layout;
+ ua->DescriptorAsStorageImage(this, imageView, layout);
+ needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout, index);
+ break;
}
- VkBuffer buffer;
- VkDeviceSize offset, range;
- ua->DescriptorAsStorageBuffer(this, buffer, offset, range);
- needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range);
- break;
- }
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- {
- // Unordered Access (Buffer)
- auto ua = handles[descriptor.Slot];
- if (!ua)
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
{
- const auto dummy = _device->HelperResources.GetDummyBuffer();
- ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ // Unordered Access (Buffer)
+ auto ua = handles[slot];
+ if (!ua)
+ {
+ const auto dummy = _device->HelperResources.GetDummyBuffer();
+ ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ }
+ VkBuffer buffer;
+ VkDeviceSize offset, range;
+ ua->DescriptorAsStorageBuffer(this, buffer, offset, range);
+ needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range, index);
+ break;
+ }
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ {
+ // Unordered Access (Buffer)
+ auto ua = handles[slot];
+ if (!ua)
+ {
+ const auto dummy = _device->HelperResources.GetDummyBuffer();
+ ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
+ }
+ VkBufferView bufferView;
+ ua->DescriptorAsStorageTexelBuffer(this, bufferView);
+ ASSERT(bufferView != VK_NULL_HANDLE);
+ needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView, index);
+ break;
+ }
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ {
+ // Constant Buffer
+ auto cb = handles[slot];
+ ASSERT(cb);
+ VkBuffer buffer;
+ VkDeviceSize offset, range;
+ uint32 dynamicOffset;
+ cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
+ needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset, index);
+ break;
+ }
+ default:
+ // Unknown or invalid descriptor type
+ CRASH;
+ break;
}
- const VkBufferView* bufferView;
- ua->DescriptorAsStorageTexelBuffer(this, bufferView);
- needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView);
- break;
- }
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- {
- // Constant Buffer
- auto cb = handles[descriptor.Slot];
- ASSERT(cb);
- VkBuffer buffer;
- VkDeviceSize offset, range;
- uint32 dynamicOffset;
- cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
- needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset);
- break;
- }
- default:
- // Unknown or invalid descriptor type
- CRASH;
- break;
}
}
}
@@ -1494,7 +1499,7 @@ void GPUContextVulkan::CopyResource(GPUResource* dstResource, GPUResource* srcRe
ASSERT(bufferCopy.size == dstBufferVulkan->GetSize());
vkCmdCopyBuffer(cmdBuffer->GetHandle(), srcBufferVulkan->GetHandle(), dstBufferVulkan->GetHandle(), 1, &bufferCopy);
}
- // Texture -> Texture
+ // Texture -> Texture
else if (srcType == GPUResource::ObjectType::Texture && dstType == GPUResource::ObjectType::Texture)
{
if (dstTextureVulkan->IsStaging())
@@ -1505,7 +1510,7 @@ void GPUContextVulkan::CopyResource(GPUResource* dstResource, GPUResource* srcRe
ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer);
CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer);
}
- // Texture -> Staging Texture
+ // Texture -> Staging Texture
else
{
// Transition resources
@@ -1635,7 +1640,7 @@ void GPUContextVulkan::CopySubresource(GPUResource* dstResource, uint32 dstSubre
ASSERT(bufferCopy.size == dstBufferVulkan->GetSize());
vkCmdCopyBuffer(cmdBuffer->GetHandle(), srcBufferVulkan->GetHandle(), dstBufferVulkan->GetHandle(), 1, &bufferCopy);
}
- // Texture -> Texture
+ // Texture -> Texture
else if (srcType == GPUResource::ObjectType::Texture && dstType == GPUResource::ObjectType::Texture)
{
const int32 dstMipMaps = dstTextureVulkan->MipLevels();
@@ -1653,7 +1658,7 @@ void GPUContextVulkan::CopySubresource(GPUResource* dstResource, uint32 dstSubre
ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer);
CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer);
}
- // Texture -> Staging Texture
+ // Texture -> Staging Texture
else
{
// Transition resources
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h
index 20f6d324f..f7fc6a221 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h
@@ -782,7 +782,7 @@ public:
///
/// The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.
/// The buffer view.
- virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
+ virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{
CRASH;
}
@@ -804,7 +804,7 @@ public:
///
/// The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.
/// The buffer view.
- virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
+ virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{
CRASH;
}
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
index d7dc050b7..0cccccf38 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp
@@ -51,9 +51,11 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
uint32 dynamicOffsetsCount = 0;
if (DescriptorInfo.DescriptorTypesCount != 0)
{
+ // TODO: merge into a single allocation
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
_pipelineState->DSWriteContainer.DescriptorImageInfo.AddZeroed(DescriptorInfo.ImageInfosCount);
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
+ _pipelineState->DSWriteContainer.DescriptorTexelBufferView.AddZeroed(DescriptorInfo.TexelBufferViewsCount);
ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
_pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount);
@@ -62,9 +64,10 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.Get();
+ VkBufferView* currentTexelBufferView = _pipelineState->DSWriteContainer.DescriptorTexelBufferView.Get();
uint8* currentBindingToDynamicOffsetMap = _pipelineState->DSWriteContainer.BindingToDynamicOffset.Get();
- dynamicOffsetsCount = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
+ dynamicOffsetsCount = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentTexelBufferView, currentBindingToDynamicOffsetMap);
}
_pipelineState->DynamicOffsets.AddZeroed(dynamicOffsetsCount);
@@ -337,9 +340,11 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
continue;
+ // TODO: merge into a single allocation for a whole PSO
DSWriteContainer.DescriptorWrites.AddZeroed(descriptor->DescriptorTypesCount);
DSWriteContainer.DescriptorImageInfo.AddZeroed(descriptor->ImageInfosCount);
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
+ DSWriteContainer.DescriptorTexelBufferView.AddZeroed(descriptor->TexelBufferViewsCount);
ASSERT(descriptor->DescriptorTypesCount < 255);
DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount);
@@ -349,6 +354,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
+ VkBufferView* currentTexelBufferView = DSWriteContainer.DescriptorTexelBufferView.Get();
byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get();
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
uint32 dynamicOffsetsCount = 0;
@@ -360,12 +366,13 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
continue;
- const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
+ const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentTexelBufferView, currentBindingToDynamicOffsetMap);
dynamicOffsetsCount += numDynamicOffsets;
currentDescriptorWrite += descriptor->DescriptorTypesCount;
currentImageInfo += descriptor->ImageInfosCount;
currentBufferInfo += descriptor->BufferInfosCount;
+ currentTexelBufferView += descriptor->TexelBufferViewsCount;
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
}
diff --git a/Source/Engine/GraphicsDevice/Vulkan/Types.h b/Source/Engine/GraphicsDevice/Vulkan/Types.h
index a97a777d2..f7ebe3f93 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/Types.h
+++ b/Source/Engine/GraphicsDevice/Vulkan/Types.h
@@ -94,10 +94,16 @@ struct SpirvShaderDescriptorInfo
/// The resource type.
///
SpirvShaderResourceType ResourceType;
+
+ ///
+ /// The amount of slots used by the descriptor (eg. array of textures size).
+ ///
+ uint32 Count;
};
uint16 ImageInfosCount;
uint16 BufferInfosCount;
+ uint32 TexelBufferViewsCount;
uint32 DescriptorTypesCount;
Descriptor DescriptorTypes[MaxDescriptors];
};
diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp
index 101ffff5a..b599b7090 100644
--- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp
+++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp
@@ -151,7 +151,8 @@ namespace
case D3D_SIT_TEXTURE:
case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS:
- bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
+ for (UINT shift = 0; shift < resDesc.BindCount; shift++)
+ bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
break;
// Unordered Access
@@ -161,7 +162,8 @@ namespace
case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
- bindings.UsedUAsMask |= 1 << resDesc.BindPoint;
+ for (UINT shift = 0; shift < resDesc.BindCount; shift++)
+ bindings.UsedUAsMask |= 1 << (resDesc.BindPoint + shift);
break;
}
}
diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp
index 17ffc61c4..966e20b75 100644
--- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp
+++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp
@@ -381,13 +381,19 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
// Shader Resource
case D3D_SIT_TEXTURE:
- bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
- header.SrDimensions[resDesc.BindPoint] = resDesc.Dimension;
+ for (UINT shift = 0; shift < resDesc.BindCount; shift++)
+ {
+ bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
+ header.SrDimensions[resDesc.BindPoint + shift] = resDesc.Dimension;
+ }
break;
case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS:
- bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
- header.SrDimensions[resDesc.BindPoint] = D3D_SRV_DIMENSION_BUFFER;
+ for (UINT shift = 0; shift < resDesc.BindCount; shift++)
+ {
+ bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
+ header.SrDimensions[resDesc.BindPoint + shift] = D3D_SRV_DIMENSION_BUFFER;
+ }
break;
// Unordered Access
@@ -397,30 +403,10 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
- bindings.UsedUAsMask |= 1 << resDesc.BindPoint;
- switch (resDesc.Dimension)
+ for (UINT shift = 0; shift < resDesc.BindCount; shift++)
{
- case D3D_SRV_DIMENSION_BUFFER:
- header.UaDimensions[resDesc.BindPoint] = 1; // D3D12_UAV_DIMENSION_BUFFER;
- break;
- case D3D_SRV_DIMENSION_TEXTURE1D:
- header.UaDimensions[resDesc.BindPoint] = 2; // D3D12_UAV_DIMENSION_TEXTURE1D;
- break;
- case D3D_SRV_DIMENSION_TEXTURE1DARRAY:
- header.UaDimensions[resDesc.BindPoint] = 3; // D3D12_UAV_DIMENSION_TEXTURE1DARRAY;
- break;
- case D3D_SRV_DIMENSION_TEXTURE2D:
- header.UaDimensions[resDesc.BindPoint] = 4; // D3D12_UAV_DIMENSION_TEXTURE2D;
- break;
- case D3D_SRV_DIMENSION_TEXTURE2DARRAY:
- header.UaDimensions[resDesc.BindPoint] = 5; // D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
- break;
- case D3D_SRV_DIMENSION_TEXTURE3D:
- header.UaDimensions[resDesc.BindPoint] = 8; // D3D12_UAV_DIMENSION_TEXTURE3D;
- break;
- default:
- LOG(Error, "Unknown UAV resource {2} of type {0} at slot {1}", resDesc.Dimension, resDesc.BindPoint, String(resDesc.Name));
- return true;
+ bindings.UsedUAsMask |= 1 << (resDesc.BindPoint + shift);
+ header.SrDimensions[resDesc.BindPoint + shift] = (byte)resDesc.Dimension; // D3D_SRV_DIMENSION matches D3D12_UAV_DIMENSION
}
break;
}
diff --git a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp
index 3de291d23..edf4a0887 100644
--- a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp
+++ b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp
@@ -33,7 +33,6 @@ namespace
class Includer : public glslang::TShader::Includer
{
private:
-
ShaderCompilationContext* _context;
IncludeResult* include(const char* headerName, const char* includerName, int depth) const
@@ -46,14 +45,12 @@ private:
}
public:
-
Includer(ShaderCompilationContext* context)
{
_context = context;
}
public:
-
// [glslang::TShader::Include]
IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override
{
@@ -210,6 +207,7 @@ struct Descriptor
int32 Slot;
int32 Binding;
int32 Size;
+ int32 Count;
SpirvShaderResourceBindingType BindingType;
VkDescriptorType DescriptorType;
SpirvShaderResourceType ResourceType;
@@ -229,7 +227,7 @@ SpirvShaderResourceType GetTextureType(const glslang::TSampler& sampler)
case glslang::EsdCube:
return SpirvShaderResourceType::TextureCube;
default:
- CRASH;
+ CRASH;
return SpirvShaderResourceType::Unknown;
}
}
@@ -244,23 +242,13 @@ bool IsUavType(const glslang::TType& type)
class DescriptorsCollector
{
public:
-
- int32 Images;
- int32 Buffers;
- int32 DescriptorsCount;
+ int32 Images = 0;
+ int32 Buffers = 0;
+ int32 TexelBuffers = 0;
+ int32 DescriptorsCount = 0;
Descriptor Descriptors[SpirvShaderDescriptorInfo::MaxDescriptors];
public:
-
- DescriptorsCollector()
- {
- Images = 0;
- Buffers = 0;
- DescriptorsCount = 0;
- }
-
-public:
-
Descriptor* Add(glslang::TVarEntryInfo& ent)
{
const glslang::TType& type = ent.symbol->getType();
@@ -374,28 +362,6 @@ public:
}
}
- // Get the output info about shader uniforms usage
- switch (descriptorType)
- {
- case VK_DESCRIPTOR_TYPE_SAMPLER:
- case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
- Images++;
- break;
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- Buffers++;
- break;
- default:
- LOG(Warning, "Invalid descriptor type {0} for symbol {1}.", (int32)descriptorType, String(name));
- return nullptr;
- }
-
const auto index = DescriptorsCount++;
auto& descriptor = Descriptors[index];
descriptor.Binding = index;
@@ -405,6 +371,32 @@ public:
descriptor.DescriptorType = descriptorType;
descriptor.ResourceType = resourceType;
descriptor.Name = name;
+ descriptor.Count = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
+
+ // Get the output info about shader uniforms usage
+ switch (descriptorType)
+ {
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ Images += descriptor.Count;
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ Buffers += descriptor.Count;
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ TexelBuffers += descriptor.Count;
+ break;
+ default:
+ LOG(Warning, "Invalid descriptor type {0} for symbol {1}.", (int32)descriptorType, String(name));
+ return nullptr;
+ }
+
return &descriptor;
}
};
@@ -412,12 +404,10 @@ public:
class MyIoMapResolver : public glslang::TDefaultIoResolverBase
{
private:
-
int32 _set;
DescriptorsCollector* _collector;
public:
-
MyIoMapResolver(int32 set, DescriptorsCollector* collector, const glslang::TIntermediate& intermediate)
: TDefaultIoResolverBase(intermediate)
, _set(set)
@@ -426,7 +416,6 @@ public:
}
public:
-
// [glslang::TDefaultIoResolverBase]
bool validateBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override
{
@@ -455,7 +444,9 @@ public:
// Add resource
const auto descriptor = _collector->Add(ent);
if (descriptor)
- return ent.newBinding = reserveSlot(_set, descriptor->Binding);
+ {
+ return ent.newBinding = reserveSlot(_set, descriptor->Binding, descriptor->Count);
+ }
return ent.newBinding;
}
@@ -686,6 +677,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Process all descriptors
header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images;
header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers;
+ header.DescriptorInfo.TexelBufferViewsCount = descriptorsCollector.TexelBuffers;
for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++)
{
auto& descriptor = descriptorsCollector.Descriptors[i];
@@ -697,6 +689,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
d.BindingType = descriptor.BindingType;
d.DescriptorType = descriptor.DescriptorType;
d.ResourceType = descriptor.ResourceType;
+ d.Count = descriptor.Count;
switch (descriptor.BindingType)
{
@@ -732,6 +725,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Mark as used and cache some data
cc.IsUsed = true;
cc.Size = descriptor.Size;
+ break;
}
}
}