From cbea62ceb9150d6c57f75d9e1cf8e3bad95b0357 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 28 Apr 2021 15:52:48 +0200 Subject: [PATCH] Fix structured uav/srv buffer usage on Vulkan --- .../GraphicsDevice/Vulkan/GPUBufferVulkan.cpp | 37 ++++++++++--------- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 2 +- .../GraphicsDevice/Vulkan/RenderToolsVulkan.h | 3 ++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp index 1cd90b11b..2acd2712c 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp @@ -17,14 +17,17 @@ void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, Buffer = buffer; Size = size; - VkBufferViewCreateInfo viewInfo; - RenderToolsVulkan::ZeroStruct(viewInfo, VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); - viewInfo.buffer = Buffer; - viewInfo.format = RenderToolsVulkan::ToVulkanFormat(format); - viewInfo.offset = 0; - viewInfo.range = Size; - - VALIDATE_VULKAN_RESULT(vkCreateBufferView(device->Device, &viewInfo, nullptr, &View)); + if (owner->IsShaderResource() && !(owner->GetDescription().Flags & GPUBufferFlags::Structured)) + { + VkBufferViewCreateInfo viewInfo; + RenderToolsVulkan::ZeroStruct(viewInfo, VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); + viewInfo.buffer = Buffer; + viewInfo.format = RenderToolsVulkan::ToVulkanFormat(format); + viewInfo.offset = 0; + viewInfo.range = Size; + ASSERT_LOW_LAYER(viewInfo.format != VK_FORMAT_UNDEFINED); + VALIDATE_VULKAN_RESULT(vkCreateBufferView(device->Device, &viewInfo, nullptr, &View)); + } } void GPUBufferViewVulkan::Release() @@ -32,19 +35,18 @@ void GPUBufferViewVulkan::Release() if (View != VK_NULL_HANDLE) { Device->DeferredDeletionQueue.EnqueueResource(DeferredDeletionQueueVulkan::BufferView, View); - View = VK_NULL_HANDLE; - -#if BUILD_DEBUG - Device = nullptr; - Owner = nullptr; - Buffer = VK_NULL_HANDLE; -#endif } +#if BUILD_DEBUG + Device = nullptr; + Owner = nullptr; + Buffer = VK_NULL_HANDLE; +#endif } void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) { + ASSERT_LOW_LAYER(View != VK_NULL_HANDLE); bufferView = &View; context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT); @@ -52,6 +54,7 @@ void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* conte void GPUBufferViewVulkan::DescriptorAsStorageBuffer(GPUContextVulkan* context, VkBuffer& buffer, VkDeviceSize& offset, VkDeviceSize& range) { + ASSERT_LOW_LAYER(Buffer); buffer = Buffer; offset = 0; range = Size; @@ -88,7 +91,7 @@ bool GPUBufferVulkan::OnInit() bufferInfo.size = _desc.Size; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; - if (useSRV) + if (useSRV && !(_desc.Flags & GPUBufferFlags::Structured)) bufferInfo.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; if (useUAV || _desc.Flags & GPUBufferFlags::RawBuffer) bufferInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; @@ -165,7 +168,7 @@ bool GPUBufferVulkan::OnInit() } } // Check if need to bind buffer to the shaders - else if (useSRV) + else if (useSRV || useUAV) { // Create buffer view _view.Init(_device, this, _buffer, _desc.Size, _desc.Format); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 9126d313b..d61296f49 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -144,8 +144,8 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever case 2: // Fragment shader writes to output location 0 with no matching attachment case 3: // Attachment 2 not written by fragment shader case 5: // SPIR-V module not valid: MemoryBarrier: Vulkan specification requires Memory Semantics to have one of the following bits set: Acquire, Release, AcquireRelease or SequentiallyConsistent -#if PLATFORM_ANDROID case -1666394502: // After query pool creation, each query must be reset before it is used. Queries must also be reset between uses. +#if PLATFORM_ANDROID case 602160055: // Attachment 4 not written by fragment shader; undefined values will be written to attachment. TODO: investigate it for PS_GBuffer shader from Deferred material with USE_LIGHTMAP=1 #endif return VK_FALSE; diff --git a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h index cf9b7e9cf..ec5d882bc 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h @@ -78,6 +78,9 @@ public: case 0: stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; break; + case VK_ACCESS_INDIRECT_COMMAND_READ_BIT: + stageFlags = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; case VK_ACCESS_TRANSFER_WRITE_BIT: stageFlags = VK_PIPELINE_STAGE_TRANSFER_BIT; break;