Add Compute shaders support to WebGPU
This commit is contained in:
@@ -8,6 +8,42 @@
|
||||
#include "Engine/GraphicsDevice/Vulkan/Types.h"
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
/// <summary>
|
||||
/// Bundle of the current bound state to the Web GPU context (used to properly handle different texture layouts or samplers when building bind group layout).
|
||||
/// </summary>
|
||||
struct GPUContextBindingsWebGPU
|
||||
{
|
||||
GPUResourceView** ShaderResources; // [GPU_MAX_SR_BINDED]
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Batch of bind group descriptions for the layout. Used as a key for caching created bind groups.
|
||||
/// </summary>
|
||||
struct GPUBindGroupKeyWebGPU
|
||||
{
|
||||
uint32 Hash;
|
||||
WGPUBindGroupLayout Layout;
|
||||
mutable uint64 LastFrameUsed;
|
||||
WGPUBindGroupEntry Entries[64];
|
||||
uint8 EntriesCount;
|
||||
uint8 Versions[64]; // Versions of descriptors used to differentiate when texture residency gets changed
|
||||
|
||||
bool operator==(const GPUBindGroupKeyWebGPU& other) const;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Reusable utility for caching bind group objects. Handles reusing bind groups for the same key and releasing them when they are not used for a long time (based on the frame number).
|
||||
/// </summary>
|
||||
struct GPUBindGroupCacheWebGPU
|
||||
{
|
||||
private:
|
||||
uint64 _lastFrameBindGroupsGC = 0;
|
||||
Dictionary<GPUBindGroupKeyWebGPU, WGPUBindGroup> _bindGroups; // TODO: try using LRU cache
|
||||
|
||||
public:
|
||||
WGPUBindGroup Get(WGPUDevice device, GPUBindGroupKeyWebGPU& key, const StringAnsiView& debugName, uint64 gcFrames = 50);
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Shaders base class for Web GPU backend.
|
||||
/// </summary>
|
||||
@@ -69,4 +105,39 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Compute Shader for Web GPU backend.
|
||||
/// </summary>
|
||||
class GPUShaderProgramCSWebGPU : public GPUShaderProgramWebGPU<GPUShaderProgramCS>
|
||||
{
|
||||
private:
|
||||
WGPUComputePipeline _pipeline = nullptr;
|
||||
WGPUBindGroupLayout _bindGroupLayout = nullptr;
|
||||
GPUBindGroupCacheWebGPU _bindGroupCache;
|
||||
|
||||
public:
|
||||
GPUShaderProgramCSWebGPU(const GPUShaderProgramInitializer& initializer, const SpirvShaderDescriptorInfo& descriptorInfo, WGPUShaderModule shaderModule)
|
||||
: GPUShaderProgramWebGPU(initializer, descriptorInfo, shaderModule)
|
||||
{
|
||||
}
|
||||
|
||||
~GPUShaderProgramCSWebGPU()
|
||||
{
|
||||
if (_bindGroupLayout)
|
||||
wgpuBindGroupLayoutRelease(_bindGroupLayout);
|
||||
if (_pipeline)
|
||||
wgpuComputePipelineRelease(_pipeline);
|
||||
}
|
||||
|
||||
public:
|
||||
// Gets the pipeline.
|
||||
WGPUComputePipeline GetPipeline(WGPUDevice device, const GPUContextBindingsWebGPU& bindings, WGPUBindGroupLayout& resultBindGroupLayout);
|
||||
|
||||
// Gets the bind group for the given key (unhashed). Bind groups are cached and reused for the same key.
|
||||
FORCE_INLINE WGPUBindGroup GetBindGroup(WGPUDevice device, GPUBindGroupKeyWebGPU& key)
|
||||
{
|
||||
return _bindGroupCache.Get(device, key, _name, 60 * 60);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user