Fix incorrect dummy GPU Buffer format when binding missing resource to Vulkan descriptor

This commit is contained in:
Wojtek Figat
2024-12-13 14:56:20 +01:00
parent fc4e6f4972
commit 666efb7675
5 changed files with 139 additions and 20 deletions

View File

@@ -504,7 +504,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
auto handle = handles[slot];
if (!handle)
{
const auto dummy = _device->HelperResources.GetDummyBuffer();
const auto dummy = _device->HelperResources.GetDummyBuffer(descriptor.ResourceFormat);
handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
}
VkBufferView bufferView;
@@ -528,7 +528,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
auto handle = handles[slot];
if (!handle)
{
const auto dummy = _device->HelperResources.GetDummyBuffer();
const auto dummy = _device->HelperResources.GetDummyBuffer(descriptor.ResourceFormat);
handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
}
VkBuffer buffer;
@@ -542,7 +542,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
auto handle = handles[slot];
if (!handle)
{
const auto dummy = _device->HelperResources.GetDummyBuffer();
const auto dummy = _device->HelperResources.GetDummyBuffer(descriptor.ResourceFormat);
handle = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
}
VkBufferView bufferView;
@@ -561,7 +561,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
handle->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
else
{
const auto dummy = _device->HelperResources.GetDummyBuffer();
const auto dummy = _device->HelperResources.GetDummyBuffer(PixelFormat::R32_SInt);
buffer = dummy->GetHandle();
range = dummy->GetSize();
}

View File

@@ -794,7 +794,6 @@ bool BufferedQueryPoolVulkan::HasRoom() const
HelperResourcesVulkan::HelperResourcesVulkan(GPUDeviceVulkan* device)
: _device(device)
, _dummyBuffer(nullptr)
, _dummyVB(nullptr)
{
Platform::MemoryClear(_dummyTextures, sizeof(_dummyTextures));
@@ -921,15 +920,20 @@ GPUTextureVulkan* HelperResourcesVulkan::GetDummyTexture(SpirvShaderResourceType
return texture;
}
GPUBufferVulkan* HelperResourcesVulkan::GetDummyBuffer()
GPUBufferVulkan* HelperResourcesVulkan::GetDummyBuffer(PixelFormat format)
{
if (!_dummyBuffer)
if (_dummyBuffers.IsEmpty())
{
_dummyBuffer = (GPUBufferVulkan*)_device->CreateBuffer(TEXT("DummyBuffer"));
_dummyBuffer->Init(GPUBufferDescription::Buffer(sizeof(int32) * 256, GPUBufferFlags::ShaderResource | GPUBufferFlags::UnorderedAccess, PixelFormat::R32_SInt));
_dummyBuffers.Resize((int32)PixelFormat::MAX);
Platform::MemoryClear((void*)_dummyBuffers.Get(), (int32)PixelFormat::MAX * sizeof(void*));
}
return _dummyBuffer;
auto& dummyBuffer = _dummyBuffers[(int32)format];
if (!dummyBuffer)
{
dummyBuffer = (GPUBufferVulkan*)_device->CreateBuffer(TEXT("DummyBuffer"));
dummyBuffer->Init(GPUBufferDescription::Buffer(PixelFormatExtensions::SizeInBytes(format) * 256, GPUBufferFlags::ShaderResource | GPUBufferFlags::UnorderedAccess, format));
}
return dummyBuffer;
}
GPUBufferVulkan* HelperResourcesVulkan::GetDummyVertexBuffer()
@@ -939,15 +943,16 @@ GPUBufferVulkan* HelperResourcesVulkan::GetDummyVertexBuffer()
_dummyVB = (GPUBufferVulkan*)_device->CreateBuffer(TEXT("DummyVertexBuffer"));
_dummyVB->Init(GPUBufferDescription::Vertex(sizeof(Color32), 1, &Color32::Transparent));
}
return _dummyVB;
}
void HelperResourcesVulkan::Dispose()
{
SAFE_DELETE_GPU_RESOURCES(_dummyTextures);
SAFE_DELETE_GPU_RESOURCE(_dummyBuffer);
SAFE_DELETE_GPU_RESOURCE(_dummyVB);
for (GPUBuffer* buffer : _dummyBuffers)
Delete(buffer);
_dummyBuffers.Clear();
for (int32 i = 0; i < ARRAY_COUNT(_staticSamplers); i++)
{

View File

@@ -308,7 +308,7 @@ class HelperResourcesVulkan
private:
GPUDeviceVulkan* _device;
GPUTextureVulkan* _dummyTextures[6];
GPUBufferVulkan* _dummyBuffer;
Array<GPUBufferVulkan*> _dummyBuffers;
GPUBufferVulkan* _dummyVB;
VkSampler _staticSamplers[GPU_STATIC_SAMPLERS_COUNT];
@@ -318,7 +318,7 @@ public:
public:
VkSampler* GetStaticSamplers();
GPUTextureVulkan* GetDummyTexture(SpirvShaderResourceType type);
GPUBufferVulkan* GetDummyBuffer();
GPUBufferVulkan* GetDummyBuffer(PixelFormat format);
GPUBufferVulkan* GetDummyVertexBuffer();
void Dispose();
};

View File

@@ -4,6 +4,8 @@
#if COMPILE_WITH_VK_SHADER_COMPILER || GRAPHICS_API_VULKAN
#include "Engine/Graphics/PixelFormat.h"
#if GRAPHICS_API_VULKAN
#include "Engine/GraphicsDevice/Vulkan/IncludeVulkanHeaders.h"
#else
@@ -95,6 +97,11 @@ struct SpirvShaderDescriptorInfo
/// </summary>
SpirvShaderResourceType ResourceType;
/// <summary>
/// The resource format.
/// </summary>
PixelFormat ResourceFormat;
/// <summary>
/// The amount of slots used by the descriptor (eg. array of textures size).
/// </summary>
@@ -127,8 +134,6 @@ struct SpirvShaderHeader
/// The shader descriptors usage information.
/// </summary>
SpirvShaderDescriptorInfo DescriptorInfo;
// .. rest is just a actual data array
};
#endif

View File

@@ -116,9 +116,9 @@ const TBuiltInResource DefaultTBuiltInResource =
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupCountX = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupCountY = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupCountZ = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
@@ -212,6 +212,7 @@ struct Descriptor
SpirvShaderResourceBindingType BindingType;
VkDescriptorType DescriptorType;
SpirvShaderResourceType ResourceType;
PixelFormat ResourceFormat;
std::string Name;
};
@@ -233,6 +234,112 @@ SpirvShaderResourceType GetTextureType(const glslang::TSampler& sampler)
}
}
PixelFormat GetResourceFormat(const glslang::TSampler& sampler)
{
switch (sampler.type)
{
case glslang::EbtVoid:
return PixelFormat::Unknown;
case glslang::EbtFloat:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R32_Float;
case 2:
return PixelFormat::R32G32_Float;
case 3:
return PixelFormat::R32G32B32_Float;
case 4:
return PixelFormat::R32G32B32A32_Float;
}
break;
case glslang::EbtFloat16:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R16_Float;
case 2:
return PixelFormat::R16G16_Float;
case 4:
return PixelFormat::R16G16B16A16_Float;
}
break;
case glslang::EbtUint:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R32_UInt;
case 2:
return PixelFormat::R32G32_UInt;
case 3:
return PixelFormat::R32G32B32_UInt;
case 4:
return PixelFormat::R32G32B32A32_UInt;
}
break;
case glslang::EbtInt:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R32_SInt;
case 2:
return PixelFormat::R32G32_SInt;
case 3:
return PixelFormat::R32G32B32_SInt;
case 4:
return PixelFormat::R32G32B32A32_SInt;
}
break;
case glslang::EbtUint8:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R8_UInt;
case 2:
return PixelFormat::R8G8_UInt;
case 4:
return PixelFormat::R8G8B8A8_UInt;
}
break;
case glslang::EbtInt8:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R8_SInt;
case 2:
return PixelFormat::R8G8_SInt;
case 4:
return PixelFormat::R8G8B8A8_SInt;
}
break;
case glslang::EbtUint16:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R16_UInt;
case 2:
return PixelFormat::R16G16_UInt;
case 4:
return PixelFormat::R16G16B16A16_UInt;
}
break;
case glslang::EbtInt16:
switch (sampler.vectorSize)
{
case 1:
return PixelFormat::R16_SInt;
case 2:
return PixelFormat::R16G16_SInt;
case 4:
return PixelFormat::R16G16B16A16_SInt;
}
break;
default:
break;
}
return PixelFormat::Unknown;
}
bool IsUavType(const glslang::TType& type)
{
if (type.getQualifier().isReadOnly())
@@ -371,6 +478,7 @@ public:
descriptor.BindingType = resourceBindingType;
descriptor.DescriptorType = descriptorType;
descriptor.ResourceType = resourceType;
descriptor.ResourceFormat = GetResourceFormat(type.getSampler());
descriptor.Name = name;
descriptor.Count = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
@@ -694,6 +802,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
d.BindingType = descriptor.BindingType;
d.DescriptorType = descriptor.DescriptorType;
d.ResourceType = descriptor.ResourceType;
d.ResourceFormat = descriptor.ResourceFormat;
d.Count = descriptor.Count;
switch (descriptor.BindingType)