Skip to content

wgsl: Sketch design for arrays of buffer-bindings #2105

@dneto0

Description

@dneto0

We need a sensible design for supporting arrays-of-buffers

Arrays-of-bindings (for buffers) are an important newer feature of APIs, supporting a bindless style.

These can't be included in WebGPU 1.0, but the language design for that future feature may influence the 1.0 language.
So this is tagged for "1.0" for now.

This discussion builds on the two solutions so far for #1534:

What Vulkan has

  • Vulkan supports a single-dimensional array of buffers.
    * Vulkan’s main feature bit: descriptorIndexing, and fine grain features in VkPhysicalDeviceDescriptorIndexingFeatures
  • Each element of the array corresponds to a descriptor binding point. The 0th element maps to the given descriptorSet and binding attribute, and binding numbers increase by 1 for each successive array element.
    • Indexing into these is limited, by default, with opt-in extra features:
      • Indexing by a SPIR-V constant expression
      • Indexing by a dynamically computed but still uniform value
      • Indexing by a dynamically computed value, not necessarily uniform.
  • An extra feature is to allow a runtime-sized array of these descriptors. see the runtimeDescriptorArray subfeature in VkPhysicalDeviceDescriptorIndexingFeatures
  • Note: The design below does not contemplate these gradations of functionality.

Design sketch: arrays of buffers for WGSL

Key idea, while avoiding a block attribute: mark the container to say its elements are buffer-roots.

This covers both sized-arrays of buffers and dynamically-sized arrays of buffers.

Observations/questions about arrays of buffers

  • Layout does not make sense, since it’s not contiguous storage.
    • Perhaps stride does not apply: no [[stride(N)]] attribute, or stride parameterization of the array type?
  • Are the array types constructible?
    • What if the same type is used for array-of-buffer and internally?
    • Perhaps allow them to be “constructible”, but limit what operations can be done on them, based on buffer-array variable concept, as below.
  • Maybe it’s not really about the type, but about its use for a buffer-array variable.
    • Principle: Allow reuse of a structure type for other things.
    • This is allowed in options 0 and 4a.

Syntax and inference

Below are several options for how buffer-arrays are spelled out in WGSL source.

struct B {
  a: i32;
  data: array<f32>;
};

[[group(0),binding(0)]]
var<storage> single: B;

/* 
   Option 0: Don't have syntax. Implicit all the way down.
   Idea: 
   - Infer the fact that these are buffer-array variables from the fact that
     they are variables in the uniform or storage storage class, and are
     arrays around a struct.
   - Least fuss for users. Not much more work for tooling.
*/

[[group(1),binding(0)]] var<storage> sized: array<B,10>;  
[[group(2),binding(0)]] var<storage> dynsized: dynamic_array<B>;



/* 
   Option 4b: Different syntax keyword for introducing the type.
          4b: Different words.
              But is it dynamic_buffer_array (more logical)
              or buffer_dynamic_array (looks more composed, i.e. "just add dynamic_ before array"
*/

[[group(1),binding(0)]] var<storage> sized: buffer_array<B,10>;
[[group(2),binding(0)]] var<storage> dynsized: dynamic_buffer_array<B>;



/* 

   Option 5: Alternate syntax for struct to indicate it's only usable for a binding.
   Some spec overhead, but also clearly delineates what can and cannot be done.

 */

block ssbo_interface {
  x : dynamic_array<f32>;
};

[[group(0), binding(0)]] var<storage>  sized : array<ssbo_interface, 8>;
[[group(0), binding(1)]] var<storage>  dynsized : dynamic_array<ssbo_interface>;

Metadata

Metadata

Assignees

No one assigned

    Labels

    wgslWebGPU Shading Language Issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions