diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index a8b34f781..106ffadf8 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -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(); } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 694730ab3..319dd653f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -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++) { diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h index 7fa84152a..e5e9c7de8 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h @@ -308,7 +308,7 @@ class HelperResourcesVulkan private: GPUDeviceVulkan* _device; GPUTextureVulkan* _dummyTextures[6]; - GPUBufferVulkan* _dummyBuffer; + Array _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(); }; diff --git a/Source/Engine/GraphicsDevice/Vulkan/Types.h b/Source/Engine/GraphicsDevice/Vulkan/Types.h index 2daf72619..31acb0832 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/Types.h +++ b/Source/Engine/GraphicsDevice/Vulkan/Types.h @@ -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 /// SpirvShaderResourceType ResourceType; + /// + /// The resource format. + /// + PixelFormat ResourceFormat; + /// /// The amount of slots used by the descriptor (eg. array of textures size). /// @@ -127,8 +134,6 @@ struct SpirvShaderHeader /// The shader descriptors usage information. /// SpirvShaderDescriptorInfo DescriptorInfo; - - // .. rest is just a actual data array }; #endif diff --git a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp index c14e15ee2..5f509ef1e 100644 --- a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp +++ b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp @@ -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)