Fix particles on WebGPU to respect format support flags properly
This commit is contained in:
@@ -8,97 +8,111 @@
|
||||
/// <summary>
|
||||
/// Which resources are supported for a given format and given device.
|
||||
/// </summary>
|
||||
API_ENUM(Attributes="Flags") enum class FormatSupport : int32
|
||||
API_ENUM(Attributes="Flags") enum class FormatSupport : uint64
|
||||
{
|
||||
/// <summary>
|
||||
/// No features supported.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
None = 0x0,
|
||||
|
||||
/// <summary>
|
||||
/// Buffer resources supported.
|
||||
/// </summary>
|
||||
Buffer = 1,
|
||||
Buffer = 0x1,
|
||||
|
||||
/// <summary>
|
||||
/// Vertex buffers supported.
|
||||
/// </summary>
|
||||
VertexBuffer = 0x2,
|
||||
|
||||
/// <summary>
|
||||
/// Vertex buffers supported.
|
||||
/// [Deprecated in 1.12]
|
||||
/// </summary>
|
||||
InputAssemblyVertexBuffer = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Index buffers supported.
|
||||
/// </summary>
|
||||
IndexBuffer = 0x4,
|
||||
|
||||
/// <summary>
|
||||
/// Index buffers supported.
|
||||
/// [Deprecated in 1.12]
|
||||
/// </summary>
|
||||
InputAssemblyIndexBuffer = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Streaming output buffers supported.
|
||||
/// </summary>
|
||||
StreamOutputBuffer = 8,
|
||||
StreamOutputBuffer = 0x8,
|
||||
|
||||
/// <summary>
|
||||
/// 1D texture resources supported.
|
||||
/// </summary>
|
||||
Texture1D = 16,
|
||||
Texture1D = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// 2D texture resources supported.
|
||||
/// </summary>
|
||||
Texture2D = 32,
|
||||
Texture2D = 0x20,
|
||||
|
||||
/// <summary>
|
||||
/// 3D texture resources supported.
|
||||
/// </summary>
|
||||
Texture3D = 64,
|
||||
Texture3D = 0x40,
|
||||
|
||||
/// <summary>
|
||||
/// Cube texture resources supported.
|
||||
/// </summary>
|
||||
TextureCube = 128,
|
||||
TextureCube = 0x80,
|
||||
|
||||
/// <summary>
|
||||
/// The shader Load function for texture objects is supported.
|
||||
/// </summary>
|
||||
ShaderLoad = 256,
|
||||
ShaderLoad = 0x100,
|
||||
|
||||
/// <summary>
|
||||
/// The shader Sample function for texture objects is supported.
|
||||
/// </summary>
|
||||
ShaderSample = 512,
|
||||
ShaderSample = 0x200,
|
||||
|
||||
/// <summary>
|
||||
/// The shader SampleCmp and SampleCmpLevelZero functions for texture objects are supported.
|
||||
/// </summary>
|
||||
ShaderSampleComparison = 1024,
|
||||
ShaderSampleComparison = 0x400,
|
||||
|
||||
/// <summary>
|
||||
/// Unused.
|
||||
/// [Deprecated in 1.12]
|
||||
/// </summary>
|
||||
ShaderSampleMonoText = 2048,
|
||||
|
||||
/// <summary>
|
||||
/// Mipmaps are supported.
|
||||
/// </summary>
|
||||
Mip = 4096,
|
||||
Mip = 0x1000,
|
||||
|
||||
/// <summary>
|
||||
/// Automatic generation of mipmaps is supported.
|
||||
/// [Deprecated in 1.12]
|
||||
/// </summary>
|
||||
MipAutogen = 8192,
|
||||
|
||||
/// <summary>
|
||||
/// Render targets are supported.
|
||||
/// </summary>
|
||||
RenderTarget = 16384,
|
||||
RenderTarget = 0x4000,
|
||||
|
||||
/// <summary>
|
||||
/// Blend operations supported.
|
||||
/// </summary>
|
||||
Blendable = 32768,
|
||||
Blendable = 0x8000,
|
||||
|
||||
/// <summary>
|
||||
/// Depth stencils supported.
|
||||
/// </summary>
|
||||
DepthStencil = 65536,
|
||||
DepthStencil = 0x10000,
|
||||
|
||||
/// <summary>
|
||||
/// CPU locking supported.
|
||||
@@ -108,67 +122,87 @@ API_ENUM(Attributes="Flags") enum class FormatSupport : int32
|
||||
/// <summary>
|
||||
/// Multisample antialiasing (MSAA) resolve operations are supported.
|
||||
/// </summary>
|
||||
MultisampleResolve = 262144,
|
||||
MultisampleResolve = 0x40000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be displayed on screen.
|
||||
/// </summary>
|
||||
Display = 524288,
|
||||
Display = 0x80000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can't be cast to another format.
|
||||
/// </summary>
|
||||
CastWithinBitLayout = 1048576,
|
||||
CastWithinBitLayout = 0x100000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as a multi-sampled render target.
|
||||
/// </summary>
|
||||
MultisampleRenderTarget = 2097152,
|
||||
MultisampleRenderTarget = 0x200000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as a multi-sampled texture and read into a shader with the shader Load function.
|
||||
/// </summary>
|
||||
MultisampleLoad = 4194304,
|
||||
MultisampleLoad = 0x400000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the shader gather function.
|
||||
/// </summary>
|
||||
ShaderGather = 8388608,
|
||||
ShaderGather = 0x800000,
|
||||
|
||||
/// <summary>
|
||||
/// Format supports casting when the resource is a back buffer.
|
||||
/// </summary>
|
||||
BackBufferCast = 16777216,
|
||||
BackBufferCast = 0x1000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used for an unordered access view.
|
||||
/// </summary>
|
||||
TypedUnorderedAccessView = 33554432,
|
||||
TypedUnorderedAccessView = 0x2000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the shader gather with comparison function.
|
||||
/// </summary>
|
||||
ShaderGatherComparison = 67108864,
|
||||
ShaderGatherComparison = 0x4000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the decoder output.
|
||||
/// </summary>
|
||||
DecoderOutput = 134217728,
|
||||
DecoderOutput = 0x8000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the video processor output.
|
||||
/// </summary>
|
||||
VideoProcessorOutput = 268435456,
|
||||
VideoProcessorOutput = 0x10000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the video processor input.
|
||||
/// </summary>
|
||||
VideoProcessorInput = 536870912,
|
||||
VideoProcessorInput = 0x20000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used with the video encoder.
|
||||
/// </summary>
|
||||
VideoEncoder = 1073741824,
|
||||
VideoEncoder = 0x40000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as unorder access resource for read-only operations (shader load).
|
||||
/// </summary>
|
||||
UnorderedAccessReadOnly = 0x80000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as unorder access resource for write-only operations (shader store).
|
||||
/// </summary>
|
||||
UnorderedAccessWriteOnly = 0x100000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as unorder access resource for both read-write operations (shader load and store).
|
||||
/// </summary>
|
||||
UnorderedAccessReadWrite = 0x200000000,
|
||||
|
||||
/// <summary>
|
||||
/// Format can be used as unorder access resource for read/write operations.
|
||||
/// </summary>
|
||||
UnorderedAccess = UnorderedAccessReadOnly | UnorderedAccessWriteOnly | UnorderedAccessReadWrite,
|
||||
};
|
||||
|
||||
DECLARE_ENUM_OPERATORS(FormatSupport);
|
||||
|
||||
@@ -400,6 +400,7 @@ bool GPUTexture::Init(const GPUTextureDescription& desc)
|
||||
LOG(Warning, "Cannot create texture. Depth Stencil texture cannot have mip maps. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
auto formatFeatures = device->GetFormatFeatures(desc.Format);
|
||||
switch (desc.Dimensions)
|
||||
{
|
||||
case TextureDimensions::Texture:
|
||||
@@ -409,6 +410,11 @@ bool GPUTexture::Init(const GPUTextureDescription& desc)
|
||||
LOG(Warning, "Cannot create texture. Texture cannot have per slice views. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (EnumHasNoneFlags(formatFeatures.Support, FormatSupport::Texture2D))
|
||||
{
|
||||
LOG(Warning, "Cannot create texture. Not supported format. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (desc.Width <= 0 || desc.Height <= 0 || desc.ArraySize <= 0
|
||||
|| desc.Width > device->Limits.MaximumTexture2DSize
|
||||
|| desc.Height > device->Limits.MaximumTexture2DSize
|
||||
@@ -449,6 +455,11 @@ bool GPUTexture::Init(const GPUTextureDescription& desc)
|
||||
LOG(Warning, "Cannot create texture. Volume texture cannot have per slice map views if is not a render target. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (EnumHasNoneFlags(formatFeatures.Support, FormatSupport::Texture3D))
|
||||
{
|
||||
LOG(Warning, "Cannot create texture. Not supported format. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (desc.Width <= 0 || desc.Height <= 0 || desc.Depth <= 0
|
||||
|| desc.Width > device->Limits.MaximumTexture3DSize
|
||||
|| desc.Height > device->Limits.MaximumTexture3DSize
|
||||
@@ -469,6 +480,11 @@ bool GPUTexture::Init(const GPUTextureDescription& desc)
|
||||
LOG(Warning, "Cannot create texture. Cube texture cannot have per slice views. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (EnumHasNoneFlags(formatFeatures.Support, FormatSupport::TextureCube))
|
||||
{
|
||||
LOG(Warning, "Cannot create texture. Not supported format. Description: {0}", desc.ToString());
|
||||
return true;
|
||||
}
|
||||
if (desc.Width <= 0 || desc.ArraySize <= 0
|
||||
|| desc.Width > device->Limits.MaximumTextureCubeSize
|
||||
|| desc.Height > device->Limits.MaximumTextureCubeSize
|
||||
|
||||
@@ -658,7 +658,10 @@ bool GPUDeviceDX11::Init()
|
||||
}
|
||||
UINT formatSupport = 0;
|
||||
_device->CheckFormatSupport(dxgiFormat, &formatSupport);
|
||||
FeaturesPerFormat[i] = FormatFeatures((MSAALevel)maxCount, (FormatSupport)formatSupport);
|
||||
FormatSupport support = (FormatSupport)formatSupport;
|
||||
if (EnumHasAllFlags(support, FormatSupport::ShaderLoad))
|
||||
support |= FormatSupport::UnorderedAccess;
|
||||
FeaturesPerFormat[i] = FormatFeatures((MSAALevel)maxCount, support);
|
||||
}
|
||||
|
||||
// Driver extensions support
|
||||
|
||||
@@ -786,7 +786,10 @@ bool GPUDeviceDX12::Init()
|
||||
if (FAILED(_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatInfo, sizeof(formatInfo))))
|
||||
formatInfo.Support1 = D3D12_FORMAT_SUPPORT1_NONE;
|
||||
const MSAALevel maximumMultisampleCount = GetMaximumMultisampleCount(_device, dxgiFormat);
|
||||
FeaturesPerFormat[i] = FormatFeatures(maximumMultisampleCount, (FormatSupport)formatInfo.Support1);
|
||||
FormatSupport support = (FormatSupport)formatInfo.Support1;
|
||||
if (EnumHasAllFlags(support, FormatSupport::ShaderLoad))
|
||||
support |= FormatSupport::UnorderedAccess;
|
||||
FeaturesPerFormat[i] = FormatFeatures(maximumMultisampleCount, support);
|
||||
}
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2 = {};
|
||||
|
||||
@@ -1769,13 +1769,11 @@ bool GPUDeviceVulkan::Init()
|
||||
if (properties.linearTilingFeatures != 0 || properties.optimalTilingFeatures != 0)
|
||||
support |= FormatSupport::Texture1D | FormatSupport::Texture2D | FormatSupport::Texture3D | FormatSupport::TextureCube;
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, FormatSupport::ShaderLoad);
|
||||
//VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, FormatSupport::UnorderedAccess);
|
||||
//VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, FormatSupport::RenderTarget);
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, FormatSupport::Blendable);
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatSupport::DepthStencil);
|
||||
//VK_FORMAT_FEATURE_BLIT_SRC_BIT
|
||||
//VK_FORMAT_FEATURE_BLIT_DST_BIT
|
||||
CHECK_IMAGE_FORMAT(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, FormatSupport::ShaderSample | FormatSupport::ShaderSampleComparison);
|
||||
#undef CHECK_IMAGE_FORMAT
|
||||
|
||||
@@ -1783,8 +1781,7 @@ bool GPUDeviceVulkan::Init()
|
||||
#define CHECK_BUFFER_FORMAT(bit, feature) if ((properties.bufferFeatures & bit) == bit) support |= feature
|
||||
if (properties.bufferFeatures != 0)
|
||||
support |= FormatSupport::Buffer;
|
||||
//VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
|
||||
//VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
|
||||
CHECK_BUFFER_FORMAT(VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, FormatSupport::UnorderedAccess);
|
||||
//VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
|
||||
CHECK_BUFFER_FORMAT(VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, FormatSupport::InputAssemblyVertexBuffer);
|
||||
#undef CHECK_BUFFER_FORMAT
|
||||
|
||||
@@ -89,12 +89,12 @@ bool GPUBufferWebGPU::OnInit()
|
||||
bufferDesc.usage |= WGPUBufferUsage_MapRead | WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc;
|
||||
break;
|
||||
}
|
||||
bufferDesc.size = _desc.Size;
|
||||
bufferDesc.size = (_desc.Size + 3) & ~0x3; // Align up to the multiple of 4 bytes
|
||||
bufferDesc.mappedAtCreation = _desc.InitData != nullptr && (bufferDesc.usage & WGPUBufferUsage_MapWrite);
|
||||
Buffer = wgpuDeviceCreateBuffer(_device->Device, &bufferDesc);
|
||||
if (!Buffer)
|
||||
return true;
|
||||
_memoryUsage = _desc.Size;
|
||||
_memoryUsage = bufferDesc.size;
|
||||
Usage = bufferDesc.usage;
|
||||
|
||||
// Initialize with a data if provided
|
||||
|
||||
@@ -512,6 +512,8 @@ void GPUContextWebGPU::Flush()
|
||||
|
||||
void GPUContextWebGPU::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 size, uint32 offset)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
ASSERT(data);
|
||||
ASSERT(buffer && buffer->GetSize() >= size + offset);
|
||||
auto bufferWebGPU = (GPUBufferWebGPU*)buffer;
|
||||
@@ -526,10 +528,10 @@ void GPUContextWebGPU::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32
|
||||
EndRenderPass();
|
||||
|
||||
// Synchronous upload via shared buffer
|
||||
// TODO: test using map/unmap sequence
|
||||
auto allocation = _device->DataUploader.Allocate(size - offset, WGPUBufferUsage_CopySrc | WGPUBufferUsage_CopyDst);
|
||||
wgpuQueueWriteBuffer(_device->Queue, allocation.Buffer, allocation.Offset, data, size);
|
||||
wgpuCommandEncoderCopyBufferToBuffer(Encoder, allocation.Buffer, allocation.Offset, bufferWebGPU->Buffer, offset, size);
|
||||
auto sizeAligned = (size + 3) & ~0x3; // Number of bytes must be a multiple of 4 for both wgpuQueueWriteBuffer and wgpuCommandEncoderCopyBufferToBuffer
|
||||
auto allocation = _device->DataUploader.Allocate(sizeAligned, WGPUBufferUsage_CopySrc | WGPUBufferUsage_CopyDst);
|
||||
wgpuQueueWriteBuffer(_device->Queue, allocation.Buffer, allocation.Offset, data, sizeAligned);
|
||||
wgpuCommandEncoderCopyBufferToBuffer(Encoder, allocation.Buffer, allocation.Offset, bufferWebGPU->Buffer, offset, sizeAligned);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -547,7 +549,8 @@ void GPUContextWebGPU::CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, ui
|
||||
ASSERT(dstBuffer && srcBuffer);
|
||||
auto srcBufferWebGPU = (GPUBufferWebGPU*)srcBuffer;
|
||||
auto dstBufferWebGPU = (GPUBufferWebGPU*)dstBuffer;
|
||||
wgpuCommandEncoderCopyBufferToBuffer(Encoder, srcBufferWebGPU->Buffer, srcOffset, dstBufferWebGPU->Buffer, dstOffset, size);
|
||||
auto copySize = (size + 3) & ~0x3; // Number of bytes must be a multiple of 4 for wgpuCommandEncoderCopyBufferToBuffer
|
||||
wgpuCommandEncoderCopyBufferToBuffer(Encoder, srcBufferWebGPU->Buffer, srcOffset, dstBufferWebGPU->Buffer, dstOffset, copySize);
|
||||
}
|
||||
|
||||
void GPUContextWebGPU::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int32 mipIndex, const void* data, uint32 rowPitch, uint32 slicePitch)
|
||||
@@ -1003,7 +1006,7 @@ void GPUContextWebGPU::FlushBindGroup()
|
||||
auto defaultTexture = _device->DefaultTexture[(int32)descriptor.ResourceType];
|
||||
if (!defaultTexture)
|
||||
{
|
||||
LOG(Error, "Missing resource {} at slot {} of binding space {}", (int32)descriptor.ResourceType, descriptor.Slot, (int32)descriptor.BindingType);
|
||||
LOG(Error, "Missing default resource {} at slot {} of binding space {}", (int32)descriptor.ResourceType, descriptor.Slot, (int32)descriptor.BindingType);
|
||||
CRASH;
|
||||
}
|
||||
switch (descriptor.ResourceType)
|
||||
@@ -1035,11 +1038,7 @@ void GPUContextWebGPU::FlushBindGroup()
|
||||
if (ptr && ptr->BufferView)
|
||||
entry.buffer = ptr->BufferView->Buffer;
|
||||
if (!entry.buffer)
|
||||
{
|
||||
// Fallback
|
||||
LOG(Error, "Missing resource {} at slot {} of binding space {}", (int32)descriptor.ResourceType, descriptor.Slot, (int32)descriptor.BindingType);
|
||||
CRASH; // TODO: add default buffer as fallback (_device->DefaultBuffer)
|
||||
}
|
||||
entry.buffer = _device->DefaultBuffer; // Fallback
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
@@ -1056,7 +1055,7 @@ void GPUContextWebGPU::FlushBindGroup()
|
||||
_dynamicOffsets.Add(uniform->Allocation.Offset);
|
||||
}
|
||||
else
|
||||
CRASH; // TODO: add dummy buffer as fallback
|
||||
LOG(Fatal, "Missing constant buffer at slot {}", descriptor.Slot);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -209,13 +209,14 @@ bool GPUDeviceWebGPU::Init()
|
||||
FormatSupport::MultisampleRenderTarget |
|
||||
FormatSupport::MultisampleResolve |
|
||||
FormatSupport::MultisampleLoad;
|
||||
auto supportsBasicStorage = FormatSupport::UnorderedAccessReadOnly | FormatSupport::UnorderedAccessWriteOnly;
|
||||
|
||||
#define ADD_FORMAT(pixelFormat, support)
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UInt].Support |= supportsBuffer | supportsTexture | supportsRender;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_SInt].Support |= supportsBuffer | supportsTexture | supportsRender;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_UInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_Float].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8_UNorm].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8_SNorm].Support |= supportsBuffer | supportsTexture;
|
||||
@@ -223,32 +224,32 @@ bool GPUDeviceWebGPU::Init()
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8_SInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_Float].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_Float].Support & ~FormatSupport::ShaderSample;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget | FormatSupport::UnorderedAccess;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget | FormatSupport::UnorderedAccess;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_UInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_SInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_Float].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UNorm_sRGB].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_SNorm].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_SInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_SNorm].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UInt].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_SInt].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::B8G8R8A8_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R10G10B10A2_UInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R10G10B10A2_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R11G11B10_Float].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R9G9B9E5_SharedExp].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_Float].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_Float].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_Float].Support & ~FormatSupport::ShaderSample;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_UInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SInt].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_Float].Support |= supportsBuffer | supportsTexture | supportsRender;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_UInt].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SInt].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_Float].Support |= supportsBuffer | supportsTexture | supportsRender | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_Float].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_Float].Support & ~FormatSupport::ShaderSample;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_UInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_SInt].Support |= supportsBuffer | supportsTexture | FormatSupport::RenderTarget | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::D16_UNorm].Support |= supportsBuffer | supportsTexture | supportsDepth;
|
||||
FeaturesPerFormat[(int32)PixelFormat::D24_UNorm_S8_UInt].Support |= supportsBuffer | supportsTexture | supportsDepth;
|
||||
FeaturesPerFormat[(int32)PixelFormat::D32_Float].Support |= supportsBuffer | supportsTexture | supportsDepth;
|
||||
@@ -269,20 +270,47 @@ bool GPUDeviceWebGPU::Init()
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SInt].Support |= supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_Float].Support |= supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32_Float].Support |= supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32_Float].Support |= supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R10G10B10A2_UInt].Support |= supportsMultisampling;
|
||||
}
|
||||
if (features.Contains(WGPUFeatureName_TextureFormatsTier1))
|
||||
{
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_SNorm].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SNorm].Support |= supportsBuffer | supportsTexture;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_SNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UNorm].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_SNorm].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UInt].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_SInt].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMSAA | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SNorm].Support |= supportsBuffer | supportsTexture | supportsBasicStorage;
|
||||
//FeaturesPerFormat[(int32)PixelFormat::R16_UInt].Support |= supportsBasicStorage; // TODO: fix issues with particle indices buffer that could use it
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SInt].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_Float].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_SNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_UInt].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_SInt].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16_Float].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_UNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SNorm].Support |= supportsBuffer | supportsTexture | supportsRender | supportsMultisampling | supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R10G10B10A2_UNorm].Support |= supportsBasicStorage;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R11G11B10_Float].Support |= supportsBasicStorage;
|
||||
}
|
||||
if (features.Contains(WGPUFeatureName_TextureFormatsTier2))
|
||||
{
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UNorm].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_UInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8_SInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UNorm].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_UInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R8G8B8A8_SInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_UInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_SInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16_Float].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_UInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_SInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R16G16B16A16_Float].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_UInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_SInt].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
FeaturesPerFormat[(int32)PixelFormat::R32G32B32A32_Float].Support |= FormatSupport::UnorderedAccessReadWrite;
|
||||
}
|
||||
if (features.Contains(WGPUFeatureName_Depth32FloatStencil8))
|
||||
{
|
||||
@@ -452,7 +480,7 @@ bool GPUDeviceWebGPU::Init()
|
||||
|
||||
TotalGraphicsMemory = 1024 * 1024 * 1024; // Dummy 1GB
|
||||
|
||||
// Create default samplers
|
||||
// Create default resources
|
||||
auto samplerDesc = GPUSamplerDescription::New();
|
||||
#define INIT_SAMPLER(slot, filter, addressMode, compare) \
|
||||
DefaultSamplers[slot] = New<GPUSamplerWebGPU>(this); \
|
||||
@@ -467,6 +495,15 @@ bool GPUDeviceWebGPU::Init()
|
||||
INIT_SAMPLER(4, GPUSamplerFilter::Point, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
|
||||
INIT_SAMPLER(5, GPUSamplerFilter::Trilinear, GPUSamplerAddressMode::Clamp, GPUSamplerCompareFunction::Less);
|
||||
#undef INIT_SAMPLER
|
||||
{
|
||||
WGPUBufferDescriptor bufferDesc = WGPU_BUFFER_DESCRIPTOR_INIT;
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
bufferDesc.label = WEBGPU_STR("DefaultBuffer");
|
||||
#endif
|
||||
bufferDesc.usage = WGPUBufferUsage_Storage;
|
||||
bufferDesc.size = 64;
|
||||
DefaultBuffer = wgpuDeviceCreateBuffer(Device, &bufferDesc);
|
||||
}
|
||||
|
||||
// Setup commands processing
|
||||
DataUploader._device = Device;
|
||||
@@ -578,6 +615,11 @@ void GPUDeviceWebGPU::Dispose()
|
||||
SAFE_DELETE_GPU_RESOURCES(DefaultSamplers);
|
||||
SAFE_DELETE(_mainContext);
|
||||
SAFE_DELETE(Adapter);
|
||||
if (DefaultBuffer)
|
||||
{
|
||||
wgpuBufferRelease(DefaultBuffer);
|
||||
DefaultBuffer = nullptr;
|
||||
}
|
||||
if (Queue)
|
||||
{
|
||||
wgpuQueueRelease(Queue);
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
WGPUQueue Queue = nullptr;
|
||||
GPUSamplerWebGPU* DefaultSamplers[6] = {};
|
||||
GPUTextureWebGPU* DefaultTexture[10] = {};
|
||||
WGPUBuffer DefaultBuffer = nullptr;
|
||||
GPUDataUploaderWebGPU DataUploader;
|
||||
uint32 MinUniformBufferOffsetAlignment = 1;
|
||||
|
||||
|
||||
@@ -167,7 +167,11 @@ bool ParticleBuffer::AllocateSortBuffer()
|
||||
const int32 sortedIndicesCount = Capacity * Emitter->Graph.SortModules.Count();
|
||||
uint32 indexSize = sizeof(uint32);
|
||||
PixelFormat indexFormat = PixelFormat::R32_UInt;
|
||||
if (Capacity <= MAX_uint16)
|
||||
auto r16Support = GPUDevice::Instance->GetFormatFeatures(PixelFormat::R16_UInt).Support;
|
||||
auto indexFormatRequirements = FormatSupport::Buffer | FormatSupport::UnorderedAccessReadOnly;
|
||||
if (Mode == ParticlesSimulationMode::GPU)
|
||||
indexFormatRequirements |= FormatSupport::UnorderedAccess;
|
||||
if (Capacity <= MAX_uint16 && EnumHasAllFlags(r16Support, indexFormatRequirements))
|
||||
{
|
||||
// 16-bit indices
|
||||
indexSize = sizeof(uint16);
|
||||
|
||||
Reference in New Issue
Block a user