Fix UsedSRsMask/UsedUAsMask when binding arrays to the shader

This commit is contained in:
Wojciech Figat
2022-03-22 12:55:13 +01:00
parent d58584e1fd
commit c10cdc3d90
12 changed files with 250 additions and 265 deletions

View File

@@ -12,7 +12,7 @@ class GPUShaderProgram;
/// <summary> /// <summary>
/// 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). /// 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).
/// </summary> /// </summary>
#define GPU_SHADER_CACHE_VERSION 8 #define GPU_SHADER_CACHE_VERSION 9
/// <summary> /// <summary>
/// Represents collection of shader programs with permutations and custom names. /// Represents collection of shader programs with permutations and custom names.

View File

@@ -8,7 +8,6 @@
#include "GPUDeviceVulkan.h" #include "GPUDeviceVulkan.h"
#include "RenderToolsVulkan.h" #include "RenderToolsVulkan.h"
#include "GPUContextVulkan.h" #include "GPUContextVulkan.h"
#include "GPUAdapterVulkan.h"
#include "CmdBufferVulkan.h" #include "CmdBufferVulkan.h"
#include "Engine/Threading/Threading.h" #include "Engine/Threading/Threading.h"
#include "Engine/Engine/Engine.h" #include "Engine/Engine/Engine.h"
@@ -30,39 +29,48 @@ void DescriptorSetLayoutInfoVulkan::CacheTypesUsageID()
_typesUsageID = id; _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) 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; VkDescriptorSetLayoutBinding binding;
binding.descriptorCount = 1;
binding.stageFlags = stageFlags; binding.stageFlags = stageFlags;
binding.pImmutableSamplers = nullptr; binding.pImmutableSamplers = nullptr;
for (uint32 descriptorIndex = 0; descriptorIndex < descriptorInfo->DescriptorTypesCount; descriptorIndex++) for (uint32 descriptorIndex = 0; descriptorIndex < descriptorInfo->DescriptorTypesCount; descriptorIndex++)
{ {
auto& descriptor = descriptorInfo->DescriptorTypes[descriptorIndex]; auto& descriptor = descriptorInfo->DescriptorTypes[descriptorIndex];
binding.binding = descriptorIndex; binding.binding = descriptorIndex;
binding.descriptorType = descriptor.DescriptorType; 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) DescriptorSetLayoutVulkan::DescriptorSetLayoutVulkan(GPUDeviceVulkan* device)
: _device(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; WriteDescriptors = writeDescriptors;
WritesCount = info.DescriptorTypesCount; WritesCount = info.DescriptorTypesCount;
BindingToDynamicOffset = bindingToDynamicOffset; BindingToDynamicOffset = bindingToDynamicOffset;
uint32 dynamicOffsetIndex = 0; uint32 dynamicOffsetIndex = 0;
for (uint32 i = 0; i < info.DescriptorTypesCount; i++) for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
{ {
const auto& descriptor = info.DescriptorTypes[i];
writeDescriptors->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptors->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptors->dstBinding = i; writeDescriptors->dstBinding = i;
writeDescriptors->descriptorCount = 1; writeDescriptors->descriptorCount = descriptor.Count;
writeDescriptors->descriptorType = info.DescriptorTypes[i].DescriptorType; writeDescriptors->descriptorType = descriptor.DescriptorType;
switch (writeDescriptors->descriptorType) switch (writeDescriptors->descriptorType)
{ {
@@ -394,16 +402,20 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
break; break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
writeDescriptors->pBufferInfo = bufferInfo++; writeDescriptors->pBufferInfo = bufferInfo;
bufferInfo += descriptor.Count;
break; break;
case VK_DESCRIPTOR_TYPE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
writeDescriptors->pImageInfo = imageInfo++; writeDescriptors->pImageInfo = imageInfo;
imageInfo += descriptor.Count;
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
writeDescriptors->pTexelBufferView = texelBufferView;
texelBufferView += descriptor.Count;
break; break;
default: default:
CRASH; CRASH;
@@ -412,7 +424,6 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
writeDescriptors++; writeDescriptors++;
} }
return dynamicOffsetIndex; return dynamicOffsetIndex;
} }

View File

@@ -117,7 +117,6 @@ protected:
uint32 _typesUsageID = ~0; uint32 _typesUsageID = ~0;
void CacheTypesUsageID(); void CacheTypesUsageID();
void AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor);
public: public:
@@ -138,11 +137,6 @@ public:
return _setLayouts; return _setLayouts;
} }
inline const uint32* GetLayoutTypes() const
{
return _layoutTypes;
}
inline uint32 GetTypesUsageID() const inline uint32 GetTypesUsageID() const
{ {
return _typesUsageID; return _typesUsageID;
@@ -160,25 +154,7 @@ public:
_setLayouts = info._setLayouts; _setLayouts = info._setLayouts;
} }
inline bool operator ==(const DescriptorSetLayoutInfoVulkan& other) const 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;
}
friend inline uint32 GetHash(const DescriptorSetLayoutInfoVulkan& key) friend inline uint32 GetHash(const DescriptorSetLayoutInfoVulkan& key)
{ {
@@ -413,6 +389,7 @@ struct DescriptorSetWriteContainerVulkan
{ {
Array<VkDescriptorImageInfo> DescriptorImageInfo; Array<VkDescriptorImageInfo> DescriptorImageInfo;
Array<VkDescriptorBufferInfo> DescriptorBufferInfo; Array<VkDescriptorBufferInfo> DescriptorBufferInfo;
Array<VkBufferView> DescriptorTexelBufferView;
Array<VkWriteDescriptorSet> DescriptorWrites; Array<VkWriteDescriptorSet> DescriptorWrites;
Array<byte> BindingToDynamicOffset; Array<byte> BindingToDynamicOffset;
@@ -420,6 +397,7 @@ struct DescriptorSetWriteContainerVulkan
{ {
DescriptorImageInfo.Resize(0); DescriptorImageInfo.Resize(0);
DescriptorBufferInfo.Resize(0); DescriptorBufferInfo.Resize(0);
DescriptorTexelBufferView.Resize(0);
DescriptorWrites.Resize(0); DescriptorWrites.Resize(0);
BindingToDynamicOffset.Resize(0); BindingToDynamicOffset.Resize(0);
} }
@@ -436,26 +414,24 @@ public:
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(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo); auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
ASSERT(bufferInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer); bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
return edited; 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(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo); auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
ASSERT(bufferInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer); bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
@@ -464,63 +440,61 @@ public:
return edited; return edited;
} }
bool WriteSampler(uint32 descriptorIndex, VkSampler sampler) const bool WriteSampler(uint32 descriptorIndex, VkSampler sampler, uint32 index = 0) const
{ {
ASSERT(descriptorIndex < WritesCount); ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo); auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
ASSERT(imageInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->sampler, sampler); bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->sampler, sampler);
return edited; 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(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo); auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
ASSERT(imageInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView); bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout); edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
return edited; 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(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo); auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
ASSERT(imageInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView); bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout); edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
return edited; return edited;
} }
bool WriteStorageTexelBuffer(uint32 descriptorIndex, const VkBufferView* bufferView) const bool WriteStorageTexelBuffer(uint32 descriptorIndex, VkBufferView bufferView, uint32 index = 0) const
{ {
ASSERT(descriptorIndex < WritesCount); ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
WriteDescriptors[descriptorIndex].pTexelBufferView = bufferView; auto* bufferInfo = const_cast<VkBufferView*>(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
*bufferInfo = bufferView;
return true; 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(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo); auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
ASSERT(bufferInfo);
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer); bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range); edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
return edited; return edited;
} }
bool WriteUniformTexelBuffer(uint32 descriptorIndex, const VkBufferView* view) const bool WriteUniformTexelBuffer(uint32 descriptorIndex, VkBufferView view, uint32 index = 0) const
{ {
ASSERT(descriptorIndex < WritesCount); ASSERT(descriptorIndex < WritesCount);
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
return DescriptorSet::CopyAndReturnNotEqual(WriteDescriptors[descriptorIndex].pTexelBufferView, view); auto* bufferInfo = const_cast<VkBufferView*>(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
return DescriptorSet::CopyAndReturnNotEqual(*bufferInfo, view);
} }
void SetDescriptorSet(VkDescriptorSet descriptorSet) const void SetDescriptorSet(VkDescriptorSet descriptorSet) const

View File

@@ -44,10 +44,10 @@ void GPUBufferViewVulkan::Release()
#endif #endif
} }
void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{ {
ASSERT_LOW_LAYER(View != VK_NULL_HANDLE); ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
bufferView = &View; bufferView = View;
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT); 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); 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); ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
bufferView = &View; bufferView = View;
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT); context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
} }

View File

@@ -48,9 +48,9 @@ public:
} }
// [DescriptorOwnerResourceVulkan] // [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 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;
}; };
/// <summary> /// <summary>

View File

@@ -444,21 +444,23 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
const auto& descriptor = descriptorInfo.DescriptorTypes[i]; const auto& descriptor = descriptorInfo.DescriptorTypes[i];
const int32 descriptorIndex = descriptor.Binding; const int32 descriptorIndex = descriptor.Binding;
DescriptorOwnerResourceVulkan** handles = _handles[(int32)descriptor.BindingType]; DescriptorOwnerResourceVulkan** handles = _handles[(int32)descriptor.BindingType];
for (uint32 index = 0; index < descriptor.Count; index++)
{
const int32 slot = descriptor.Slot + index;
switch (descriptor.DescriptorType) switch (descriptor.DescriptorType)
{ {
case VK_DESCRIPTOR_TYPE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLER:
{ {
// Sampler // Sampler
const VkSampler sampler = _samplerHandles[descriptor.Slot]; const VkSampler sampler = _samplerHandles[slot];
ASSERT(sampler); ASSERT(sampler);
needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler); needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
{ {
// Shader Resource (Texture) // Shader Resource (Texture)
auto handle = (GPUTextureViewVulkan*)handles[descriptor.Slot]; auto handle = (GPUTextureViewVulkan*)handles[slot];
if (!handle) if (!handle)
{ {
const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType); const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
@@ -482,38 +484,39 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
VkImageLayout layout; VkImageLayout layout;
handle->DescriptorAsImage(this, imageView, layout); handle->DescriptorAsImage(this, imageView, layout);
ASSERT(imageView != VK_NULL_HANDLE); ASSERT(imageView != VK_NULL_HANDLE);
needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout); needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
{ {
// Shader Resource (Buffer) // Shader Resource (Buffer)
auto sr = handles[descriptor.Slot]; auto sr = handles[slot];
if (!sr) if (!sr)
{ {
const auto dummy = _device->HelperResources.GetDummyBuffer(); const auto dummy = _device->HelperResources.GetDummyBuffer();
sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
} }
const VkBufferView* bufferView; VkBufferView bufferView;
sr->DescriptorAsUniformTexelBuffer(this, bufferView); sr->DescriptorAsUniformTexelBuffer(this, bufferView);
needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView); ASSERT(bufferView != VK_NULL_HANDLE);
needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
{ {
// Unordered Access (Texture) // Unordered Access (Texture)
auto ua = handles[descriptor.Slot]; auto ua = handles[slot];
ASSERT(ua); ASSERT(ua);
VkImageView imageView; VkImageView imageView;
VkImageLayout layout; VkImageLayout layout;
ua->DescriptorAsStorageImage(this, imageView, layout); ua->DescriptorAsStorageImage(this, imageView, layout);
needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout); needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
{ {
// Unordered Access (Buffer) // Unordered Access (Buffer)
auto ua = handles[descriptor.Slot]; auto ua = handles[slot];
if (!ua) if (!ua)
{ {
const auto dummy = _device->HelperResources.GetDummyBuffer(); const auto dummy = _device->HelperResources.GetDummyBuffer();
@@ -522,33 +525,34 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
VkBuffer buffer; VkBuffer buffer;
VkDeviceSize offset, range; VkDeviceSize offset, range;
ua->DescriptorAsStorageBuffer(this, buffer, offset, range); ua->DescriptorAsStorageBuffer(this, buffer, offset, range);
needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range); needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
{ {
// Unordered Access (Buffer) // Unordered Access (Buffer)
auto ua = handles[descriptor.Slot]; auto ua = handles[slot];
if (!ua) if (!ua)
{ {
const auto dummy = _device->HelperResources.GetDummyBuffer(); const auto dummy = _device->HelperResources.GetDummyBuffer();
ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
} }
const VkBufferView* bufferView; VkBufferView bufferView;
ua->DescriptorAsStorageTexelBuffer(this, bufferView); ua->DescriptorAsStorageTexelBuffer(this, bufferView);
needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView); ASSERT(bufferView != VK_NULL_HANDLE);
needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView, index);
break; break;
} }
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
{ {
// Constant Buffer // Constant Buffer
auto cb = handles[descriptor.Slot]; auto cb = handles[slot];
ASSERT(cb); ASSERT(cb);
VkBuffer buffer; VkBuffer buffer;
VkDeviceSize offset, range; VkDeviceSize offset, range;
uint32 dynamicOffset; uint32 dynamicOffset;
cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset); cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset); needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset, index);
break; break;
} }
default: default:
@@ -558,6 +562,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
} }
} }
} }
}
void GPUContextVulkan::UpdateDescriptorSets(GPUPipelineStateVulkan* pipelineState) void GPUContextVulkan::UpdateDescriptorSets(GPUPipelineStateVulkan* pipelineState)
{ {

View File

@@ -782,7 +782,7 @@ public:
/// </summary> /// </summary>
/// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param> /// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param>
/// <param name="bufferView">The buffer view.</param> /// <param name="bufferView">The buffer view.</param>
virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{ {
CRASH; CRASH;
} }
@@ -804,7 +804,7 @@ public:
/// </summary> /// </summary>
/// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param> /// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param>
/// <param name="bufferView">The buffer view.</param> /// <param name="bufferView">The buffer view.</param>
virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
{ {
CRASH; CRASH;
} }

View File

@@ -51,9 +51,11 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
uint32 dynamicOffsetsCount = 0; uint32 dynamicOffsetsCount = 0;
if (DescriptorInfo.DescriptorTypesCount != 0) if (DescriptorInfo.DescriptorTypesCount != 0)
{ {
// TODO: merge into a single allocation
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount); _pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
_pipelineState->DSWriteContainer.DescriptorImageInfo.AddZeroed(DescriptorInfo.ImageInfosCount); _pipelineState->DSWriteContainer.DescriptorImageInfo.AddZeroed(DescriptorInfo.ImageInfosCount);
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount); _pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
_pipelineState->DSWriteContainer.DescriptorTexelBufferView.AddZeroed(DescriptorInfo.TexelBufferViewsCount);
ASSERT(DescriptorInfo.DescriptorTypesCount < 255); ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
_pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount); _pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount);
@@ -62,9 +64,10 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get(); VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get(); VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.Get(); VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.Get();
VkBufferView* currentTexelBufferView = _pipelineState->DSWriteContainer.DescriptorTexelBufferView.Get();
uint8* currentBindingToDynamicOffsetMap = _pipelineState->DSWriteContainer.BindingToDynamicOffset.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); _pipelineState->DynamicOffsets.AddZeroed(dynamicOffsetsCount);
@@ -337,9 +340,11 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0) if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
continue; continue;
// TODO: merge into a single allocation for a whole PSO
DSWriteContainer.DescriptorWrites.AddZeroed(descriptor->DescriptorTypesCount); DSWriteContainer.DescriptorWrites.AddZeroed(descriptor->DescriptorTypesCount);
DSWriteContainer.DescriptorImageInfo.AddZeroed(descriptor->ImageInfosCount); DSWriteContainer.DescriptorImageInfo.AddZeroed(descriptor->ImageInfosCount);
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount); DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
DSWriteContainer.DescriptorTexelBufferView.AddZeroed(descriptor->TexelBufferViewsCount);
ASSERT(descriptor->DescriptorTypesCount < 255); ASSERT(descriptor->DescriptorTypesCount < 255);
DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount); DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount);
@@ -349,6 +354,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get(); VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get(); VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get(); VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
VkBufferView* currentTexelBufferView = DSWriteContainer.DescriptorTexelBufferView.Get();
byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get(); byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get();
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount]; uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
uint32 dynamicOffsetsCount = 0; uint32 dynamicOffsetsCount = 0;
@@ -360,12 +366,13 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0) if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
continue; 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; dynamicOffsetsCount += numDynamicOffsets;
currentDescriptorWrite += descriptor->DescriptorTypesCount; currentDescriptorWrite += descriptor->DescriptorTypesCount;
currentImageInfo += descriptor->ImageInfosCount; currentImageInfo += descriptor->ImageInfosCount;
currentBufferInfo += descriptor->BufferInfosCount; currentBufferInfo += descriptor->BufferInfosCount;
currentTexelBufferView += descriptor->TexelBufferViewsCount;
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount; currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
} }

View File

@@ -94,10 +94,16 @@ struct SpirvShaderDescriptorInfo
/// The resource type. /// The resource type.
/// </summary> /// </summary>
SpirvShaderResourceType ResourceType; SpirvShaderResourceType ResourceType;
/// <summary>
/// The amount of slots used by the descriptor (eg. array of textures size).
/// </summary>
uint32 Count;
}; };
uint16 ImageInfosCount; uint16 ImageInfosCount;
uint16 BufferInfosCount; uint16 BufferInfosCount;
uint32 TexelBufferViewsCount;
uint32 DescriptorTypesCount; uint32 DescriptorTypesCount;
Descriptor DescriptorTypes[MaxDescriptors]; Descriptor DescriptorTypes[MaxDescriptors];
}; };

View File

@@ -151,7 +151,8 @@ namespace
case D3D_SIT_TEXTURE: case D3D_SIT_TEXTURE:
case D3D_SIT_STRUCTURED: case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS: case D3D_SIT_BYTEADDRESS:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint; for (UINT shift = 0; shift < resDesc.BindCount; shift++)
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
break; break;
// Unordered Access // Unordered Access
@@ -161,7 +162,8 @@ namespace
case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: 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; break;
} }
} }

View File

@@ -381,13 +381,19 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
// Shader Resource // Shader Resource
case D3D_SIT_TEXTURE: case D3D_SIT_TEXTURE:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint; for (UINT shift = 0; shift < resDesc.BindCount; shift++)
header.SrDimensions[resDesc.BindPoint] = resDesc.Dimension; {
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
header.SrDimensions[resDesc.BindPoint + shift] = resDesc.Dimension;
}
break; break;
case D3D_SIT_STRUCTURED: case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS: case D3D_SIT_BYTEADDRESS:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint; for (UINT shift = 0; shift < resDesc.BindCount; shift++)
header.SrDimensions[resDesc.BindPoint] = D3D_SRV_DIMENSION_BUFFER; {
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
header.SrDimensions[resDesc.BindPoint + shift] = D3D_SRV_DIMENSION_BUFFER;
}
break; break;
// Unordered Access // Unordered Access
@@ -397,30 +403,10 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
bindings.UsedUAsMask |= 1 << resDesc.BindPoint; for (UINT shift = 0; shift < resDesc.BindCount; shift++)
switch (resDesc.Dimension)
{ {
case D3D_SRV_DIMENSION_BUFFER: bindings.UsedUAsMask |= 1 << (resDesc.BindPoint + shift);
header.UaDimensions[resDesc.BindPoint] = 1; // D3D12_UAV_DIMENSION_BUFFER; header.SrDimensions[resDesc.BindPoint + shift] = (byte)resDesc.Dimension; // D3D_SRV_DIMENSION matches D3D12_UAV_DIMENSION
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;
} }
break; break;
} }

View File

@@ -33,7 +33,6 @@ namespace
class Includer : public glslang::TShader::Includer class Includer : public glslang::TShader::Includer
{ {
private: private:
ShaderCompilationContext* _context; ShaderCompilationContext* _context;
IncludeResult* include(const char* headerName, const char* includerName, int depth) const IncludeResult* include(const char* headerName, const char* includerName, int depth) const
@@ -46,14 +45,12 @@ private:
} }
public: public:
Includer(ShaderCompilationContext* context) Includer(ShaderCompilationContext* context)
{ {
_context = context; _context = context;
} }
public: public:
// [glslang::TShader::Include] // [glslang::TShader::Include]
IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override
{ {
@@ -210,6 +207,7 @@ struct Descriptor
int32 Slot; int32 Slot;
int32 Binding; int32 Binding;
int32 Size; int32 Size;
int32 Count;
SpirvShaderResourceBindingType BindingType; SpirvShaderResourceBindingType BindingType;
VkDescriptorType DescriptorType; VkDescriptorType DescriptorType;
SpirvShaderResourceType ResourceType; SpirvShaderResourceType ResourceType;
@@ -244,23 +242,13 @@ bool IsUavType(const glslang::TType& type)
class DescriptorsCollector class DescriptorsCollector
{ {
public: public:
int32 Images = 0;
int32 Images; int32 Buffers = 0;
int32 Buffers; int32 TexelBuffers = 0;
int32 DescriptorsCount; int32 DescriptorsCount = 0;
Descriptor Descriptors[SpirvShaderDescriptorInfo::MaxDescriptors]; Descriptor Descriptors[SpirvShaderDescriptorInfo::MaxDescriptors];
public: public:
DescriptorsCollector()
{
Images = 0;
Buffers = 0;
DescriptorsCount = 0;
}
public:
Descriptor* Add(glslang::TVarEntryInfo& ent) Descriptor* Add(glslang::TVarEntryInfo& ent)
{ {
const glslang::TType& type = ent.symbol->getType(); 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++; const auto index = DescriptorsCount++;
auto& descriptor = Descriptors[index]; auto& descriptor = Descriptors[index];
descriptor.Binding = index; descriptor.Binding = index;
@@ -405,6 +371,32 @@ public:
descriptor.DescriptorType = descriptorType; descriptor.DescriptorType = descriptorType;
descriptor.ResourceType = resourceType; descriptor.ResourceType = resourceType;
descriptor.Name = name; 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; return &descriptor;
} }
}; };
@@ -412,12 +404,10 @@ public:
class MyIoMapResolver : public glslang::TDefaultIoResolverBase class MyIoMapResolver : public glslang::TDefaultIoResolverBase
{ {
private: private:
int32 _set; int32 _set;
DescriptorsCollector* _collector; DescriptorsCollector* _collector;
public: public:
MyIoMapResolver(int32 set, DescriptorsCollector* collector, const glslang::TIntermediate& intermediate) MyIoMapResolver(int32 set, DescriptorsCollector* collector, const glslang::TIntermediate& intermediate)
: TDefaultIoResolverBase(intermediate) : TDefaultIoResolverBase(intermediate)
, _set(set) , _set(set)
@@ -426,7 +416,6 @@ public:
} }
public: public:
// [glslang::TDefaultIoResolverBase] // [glslang::TDefaultIoResolverBase]
bool validateBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override bool validateBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override
{ {
@@ -455,7 +444,9 @@ public:
// Add resource // Add resource
const auto descriptor = _collector->Add(ent); const auto descriptor = _collector->Add(ent);
if (descriptor) if (descriptor)
return ent.newBinding = reserveSlot(_set, descriptor->Binding); {
return ent.newBinding = reserveSlot(_set, descriptor->Binding, descriptor->Count);
}
return ent.newBinding; return ent.newBinding;
} }
@@ -686,6 +677,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Process all descriptors // Process all descriptors
header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images; header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images;
header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers; header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers;
header.DescriptorInfo.TexelBufferViewsCount = descriptorsCollector.TexelBuffers;
for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++) for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++)
{ {
auto& descriptor = descriptorsCollector.Descriptors[i]; auto& descriptor = descriptorsCollector.Descriptors[i];
@@ -697,6 +689,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
d.BindingType = descriptor.BindingType; d.BindingType = descriptor.BindingType;
d.DescriptorType = descriptor.DescriptorType; d.DescriptorType = descriptor.DescriptorType;
d.ResourceType = descriptor.ResourceType; d.ResourceType = descriptor.ResourceType;
d.Count = descriptor.Count;
switch (descriptor.BindingType) switch (descriptor.BindingType)
{ {
@@ -732,6 +725,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Mark as used and cache some data // Mark as used and cache some data
cc.IsUsed = true; cc.IsUsed = true;
cc.Size = descriptor.Size; cc.Size = descriptor.Size;
break;
} }
} }
} }