Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pipeline-sized arrays in storage bindings #4892

Open
Runi-c opened this issue Sep 20, 2024 · 1 comment
Open

Support pipeline-sized arrays in storage bindings #4892

Runi-c opened this issue Sep 20, 2024 · 1 comment
Labels
wgsl WebGPU Shading Language Issues
Milestone

Comments

@Runi-c
Copy link

Runi-c commented Sep 20, 2024

I'm working on a hefty compute shader project in WGSL and running into a pair of issues that feel very constricting.

  1. The only way to have runtime or pipeline-sized array bindings is to use one storage buffer per array. This is because we can only have one runtime-sized array in a storage buffer (which makes sense), and pipeline-sized arrays (e.g. arrays sized by a pipeline constant) can only be used in the workgroup address space and therefore can't be bound.
  2. WebGPU implementations and/or graphics libraries have a relatively small maximum limit for maxStorageBuffersPerShaderStage (Chromium uses 10, wgpu uses 16, not sure why they're different)

What I would prefer to be able to do when I have multiple tightly related arrays with sizes only known at pipeline creation time is to put them all in a single read-only buffer binding like this:

override foo_count: u32;
override bar_count: u32;
override baz_count: u32;
struct SimulationData {
    stuff: array<Foo, foo_count>,
    other_stuff: array<Bar, bar_count>,
    more: array<Baz, baz_count>,
}
@group(0) @binding(0)
var<storage, read> data: SimulationData;

But because of the constraints on runtime- and pipeline-sized arrays, the only option I have is to allocate 3 runtime-sized storage buffers to what I would prefer to fill 1 buffer with:

@group(0) @binding(0)
var<storage, read> stuff: array<Foo>;
@group(0) @binding(1)
var<storage, read> other_stuff: array<Bar>;
@group(0) @binding(2)
var<storage, read> more: array<Baz>;

For a workload with many small arrays of CPU-derived data, this will run into the storage buffers limit very quickly unless we do something more drastic like a shader preprocessor hack, or setting an arbitrary max array size, or in the worst case, packing everything into one flat array and marshalling out the struct data manually in the shader kernel.

@Runi-c Runi-c added the wgsl WebGPU Shading Language Issues label Sep 20, 2024
@dneto0
Copy link
Contributor

dneto0 commented Oct 29, 2024

Thanks for the suggestion. Currently the places where an array can be sized by an override expression limited to what's common between Metal and Vulkan. (Direct3D doesn't support it, so we cover it up by delaying shader compilation until pipeline creation time.)

Putting this in M2 for consideration.

@dneto0 dneto0 added this to the Milestone 2 milestone Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wgsl WebGPU Shading Language Issues
Projects
None yet
Development

No branches or pull requests

2 participants