From 07c6c5a84110caf9caab65d979bb1355d989209c Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Fri, 1 Jul 2022 14:09:28 +0200 Subject: [PATCH] Fix issues with Vulkan backend when using DDGI --- .../GraphicsDevice/Vulkan/GPUBufferVulkan.cpp | 10 ++-- .../GraphicsDevice/Vulkan/GPUBufferVulkan.h | 2 +- .../Vulkan/GPUContextVulkan.cpp | 52 ++++++++----------- .../GraphicsDevice/Vulkan/GPUContextVulkan.h | 3 ++ .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 1 + 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp index 0dda4488f..6ebfb239a 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp @@ -8,7 +8,7 @@ #include "Engine/Threading/Threading.h" #include "Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h" -void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, VkBuffer buffer, VkDeviceSize size, PixelFormat format) +void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, PixelFormat format) { ASSERT(View == VK_NULL_HANDLE); @@ -17,7 +17,7 @@ void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, Buffer = buffer; Size = size; - if (owner->IsShaderResource() && !(owner->GetDescription().Flags & GPUBufferFlags::Structured)) + if ((owner->IsShaderResource() && !(owner->GetDescription().Flags & GPUBufferFlags::Structured)) || (usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { VkBufferViewCreateInfo viewInfo; RenderToolsVulkan::ZeroStruct(viewInfo, VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); @@ -104,6 +104,8 @@ bool GPUBufferVulkan::OnInit() bufferInfo.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; if (_desc.Flags & GPUBufferFlags::Argument) bufferInfo.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + if (_desc.Flags & GPUBufferFlags::Argument && useUAV) + bufferInfo.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; // For some reason, glslang marks indirect uav buffers (UpdateProbesInitArgs, IndirectArgsBuffer) as Storage Texel Buffers if (_desc.Flags & GPUBufferFlags::VertexBuffer) bufferInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; if (_desc.Flags & GPUBufferFlags::IndexBuffer) @@ -172,11 +174,11 @@ bool GPUBufferVulkan::OnInit() return true; } } - // Check if need to bind buffer to the shaders + // Check if need to bind buffer to the shaders else if (useSRV || useUAV) { // Create buffer view - _view.Init(_device, this, _buffer, _desc.Size, _desc.Format); + _view.Init(_device, this, _buffer, _desc.Size, bufferInfo.usage, _desc.Format); } return false; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h index 9b78c266f..3d31ef695 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.h @@ -35,7 +35,7 @@ public: public: - void Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, VkBuffer buffer, VkDeviceSize size, PixelFormat format); + void Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, PixelFormat format); void Release(); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index d543cefb1..97c172d44 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -135,6 +135,13 @@ GPUContextVulkan::GPUContextVulkan(GPUDeviceVulkan* device, QueueVulkan* queue) _handles[(int32)SpirvShaderResourceBindingType::SAMPLER] = nullptr; _handles[(int32)SpirvShaderResourceBindingType::SRV] = _srHandles; _handles[(int32)SpirvShaderResourceBindingType::UAV] = _uaHandles; +#if ENABLE_ASSERTION + _handlesSizes[(int32)SpirvShaderResourceBindingType::INVALID] = 0; + _handlesSizes[(int32)SpirvShaderResourceBindingType::CB] = GPU_MAX_CB_BINDED; + _handlesSizes[(int32)SpirvShaderResourceBindingType::SAMPLER] = GPU_MAX_SAMPLER_BINDED; + _handlesSizes[(int32)SpirvShaderResourceBindingType::SRV] = GPU_MAX_SR_BINDED; + _handlesSizes[(int32)SpirvShaderResourceBindingType::UAV] = GPU_MAX_UA_BINDED; +#endif } GPUContextVulkan::~GPUContextVulkan() @@ -447,12 +454,11 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des for (uint32 index = 0; index < descriptor.Count; index++) { const int32 slot = descriptor.Slot + index; + ASSERT(slot < _handlesSizes[(int32)descriptor.BindingType]); switch (descriptor.DescriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: { - // Sampler - ASSERT_LOW_LAYER(slot < GPU_MAX_SAMPLER_BINDED); const VkSampler sampler = _samplerHandles[slot]; ASSERT(sampler); needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler, index); @@ -460,8 +466,6 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des } case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { - // Shader Resource (Texture) - ASSERT_LOW_LAYER(slot < GPU_MAX_SR_BINDED); auto handle = (GPUTextureViewVulkan*)handles[slot]; if (!handle) { @@ -491,68 +495,58 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des } case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { - // Shader Resource (Buffer) - ASSERT_LOW_LAYER(slot < GPU_MAX_SR_BINDED); - auto sr = handles[slot]; - if (!sr) + auto handle = handles[slot]; + if (!handle) { const auto dummy = _device->HelperResources.GetDummyBuffer(); - sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); + handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); } VkBufferView bufferView; - sr->DescriptorAsUniformTexelBuffer(this, bufferView); + handle->DescriptorAsUniformTexelBuffer(this, bufferView); ASSERT(bufferView != VK_NULL_HANDLE); needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView, index); break; } case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { - // Unordered Access (Texture) - ASSERT_LOW_LAYER(slot < GPU_MAX_UA_BINDED); - auto ua = handles[slot]; - ASSERT(ua); + auto handle = handles[slot]; + ASSERT(handle); VkImageView imageView; VkImageLayout layout; - ua->DescriptorAsStorageImage(this, imageView, layout); + handle->DescriptorAsStorageImage(this, imageView, layout); needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout, index); break; } case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { - // Unordered Access (Buffer) - ASSERT_LOW_LAYER(slot < GPU_MAX_UA_BINDED); - auto ua = handles[slot]; - if (!ua) + auto handle = handles[slot]; + if (!handle) { const auto dummy = _device->HelperResources.GetDummyBuffer(); - ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); + handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); } VkBuffer buffer; VkDeviceSize offset, range; - ua->DescriptorAsStorageBuffer(this, buffer, offset, range); + handle->DescriptorAsStorageBuffer(this, buffer, offset, range); needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range, index); break; } case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { - // Unordered Access (Buffer) - ASSERT_LOW_LAYER(slot < GPU_MAX_UA_BINDED); - auto ua = handles[slot]; - if (!ua) + auto handle = handles[slot]; + if (!handle) { const auto dummy = _device->HelperResources.GetDummyBuffer(); - ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); + handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr(); } VkBufferView bufferView; - ua->DescriptorAsStorageTexelBuffer(this, bufferView); + handle->DescriptorAsStorageTexelBuffer(this, bufferView); ASSERT(bufferView != VK_NULL_HANDLE); needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView, index); break; } case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: { - // Constant Buffer - ASSERT_LOW_LAYER(slot < GPU_MAX_CB_BINDED); auto cb = handles[slot]; ASSERT(cb); VkBuffer buffer; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h index 78b4883f0..f22c713e5 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h @@ -107,6 +107,9 @@ private: DescriptorOwnerResourceVulkan* _uaHandles[GPU_MAX_UA_BINDED]; VkSampler _samplerHandles[GPU_MAX_SAMPLER_BINDED]; DescriptorOwnerResourceVulkan** _handles[(int32)SpirvShaderResourceBindingType::MAX]; +#if ENABLE_ASSERTION + uint32 _handlesSizes[(int32)SpirvShaderResourceBindingType::MAX]; +#endif typedef Array DescriptorPoolArray; Dictionary _descriptorPools; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index fc8e1f4bc..2ce5e1592 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -142,6 +142,7 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever case 7060244: // Image Operand Offset can only be used with OpImage*Gather operations case -1539028524: // SortedIndices is null so Vulkan backend sets it to default R32_SFLOAT format which is not good for UINT format of the buffer case -1810835948: // SortedIndices is null so Vulkan backend sets it to default R32_SFLOAT format which is not good for UINT format of the buffer + case -1621360350: // VkFramebufferCreateInfo attachment #0 has a layer count (1) smaller than the corresponding framebuffer layer count (64). The Vulkan spec states: If flags does not include VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments that is used as an input, color, resolve, or depth/stencil attachment by renderPass must have been created with a VkImageViewCreateInfo::subresourceRange.layerCount greater than or equal to layers return VK_FALSE; } break;