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

View File

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

View File

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

View File

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

View File

@@ -116,9 +116,9 @@ const TBuiltInResource DefaultTBuiltInResource =
/* .MinProgramTexelOffset = */ -8, /* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7, /* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8, /* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535, /* .MaxComputeWorkGroupCountX = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupCountY = */ 65535, /* .MaxComputeWorkGroupCountY = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupCountZ = */ 65535, /* .MaxComputeWorkGroupCountZ = */ GPU_MAX_CS_DISPATCH_THREAD_GROUPS,
/* .MaxComputeWorkGroupSizeX = */ 1024, /* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024, /* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64, /* .MaxComputeWorkGroupSizeZ = */ 64,
@@ -212,6 +212,7 @@ struct Descriptor
SpirvShaderResourceBindingType BindingType; SpirvShaderResourceBindingType BindingType;
VkDescriptorType DescriptorType; VkDescriptorType DescriptorType;
SpirvShaderResourceType ResourceType; SpirvShaderResourceType ResourceType;
PixelFormat ResourceFormat;
std::string Name; 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) bool IsUavType(const glslang::TType& type)
{ {
if (type.getQualifier().isReadOnly()) if (type.getQualifier().isReadOnly())
@@ -371,6 +478,7 @@ public:
descriptor.BindingType = resourceBindingType; descriptor.BindingType = resourceBindingType;
descriptor.DescriptorType = descriptorType; descriptor.DescriptorType = descriptorType;
descriptor.ResourceType = resourceType; descriptor.ResourceType = resourceType;
descriptor.ResourceFormat = GetResourceFormat(type.getSampler());
descriptor.Name = name; descriptor.Name = name;
descriptor.Count = type.isSizedArray() ? type.getCumulativeArraySize() : 1; descriptor.Count = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
@@ -694,6 +802,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
d.BindingType = descriptor.BindingType; d.BindingType = descriptor.BindingType;
d.DescriptorType = descriptor.DescriptorType; d.DescriptorType = descriptor.DescriptorType;
d.ResourceType = descriptor.ResourceType; d.ResourceType = descriptor.ResourceType;
d.ResourceFormat = descriptor.ResourceFormat;
d.Count = descriptor.Count; d.Count = descriptor.Count;
switch (descriptor.BindingType) switch (descriptor.BindingType)