Fix issues with Vulkan backend when using DDGI
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<DescriptorPoolVulkan*> DescriptorPoolArray;
|
||||
Dictionary<uint32, DescriptorPoolArray> _descriptorPools;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user