From c10cdc3d90663528ff445bee52ea7ca9210ba243 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Tue, 22 Mar 2022 12:55:13 +0100 Subject: [PATCH] Fix `UsedSRsMask`/`UsedUAsMask` when binding arrays to the shader --- Source/Engine/Graphics/Shaders/GPUShader.h | 2 +- .../Vulkan/DescriptorSetVulkan.cpp | 69 +++--- .../Vulkan/DescriptorSetVulkan.h | 70 ++---- .../GraphicsDevice/Vulkan/GPUBufferVulkan.cpp | 8 +- .../GraphicsDevice/Vulkan/GPUBufferVulkan.h | 4 +- .../Vulkan/GPUContextVulkan.cpp | 213 +++++++++--------- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.h | 4 +- .../Vulkan/GPUPipelineStateVulkan.cpp | 11 +- Source/Engine/GraphicsDevice/Vulkan/Types.h | 6 + .../DirectX/ShaderCompilerD3D.cpp | 6 +- .../DirectX/ShaderCompilerDX.cpp | 40 ++-- .../Vulkan/ShaderCompilerVulkan.cpp | 82 ++++--- 12 files changed, 250 insertions(+), 265 deletions(-) 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; } } }