-
Notifications
You must be signed in to change notification settings - Fork 329
Description
This is a follow-up from the call, related to #773, #910, and also directly relevant to #922 (comment)
Proposal
Recently, we agreed on [[stride 16]] array<i32, 5>
, which is a decoration of the array type, similar to SPIR-V. The problem with this approach appears when we try to answer the question "is the array stride a part of the type?":
- if it's a part of the type, then how would the assignment work between arrays of the different strides?
- if it's not a part of the type, then why do we annotate the type?
We know that stride makes no sense for any arrays placed in the registers. It only matters when accessing a host-shareable structure. Once it's loaded into registers, the decoration is no longer relevant. Therefore, this is a proposal to put it on the fields instead:
type UniformBuffer = struct {
[[offset 0, stride 16]]
foo: array<i32, 5>,
};
Benefits
- No need to introduce type-local decorations, which
stride
currently is the only example of, I think. The proposedstride
is in line with theoffset
that we already have. - Clarity in the assignment rules of arrays, with no special wording for how stride is handled
- Clarity in where the stride matters, and where it doesn't
- Less things for users to specify: only once for a field, instead of every time the type is used
Concerns
How do we work with pointers into host-sharable fields?
It's not clear to me what we should be able to do with pointers, and what we shouldn't, yet. If I understand correctly, WebGPU doesn't have the equivalent of VK_KHR_variable_pointers
and the corresponding variablePointersStorageBuffer
feature. This means, we as WGSL implementors, have full knowledge of what each pointer is pointing to. Therefore, we can figure out, transparent to the shader writer, how to advance a pointer to the next position (by adding the stride), based on that knowledge.
How do we deal with nested arrays?
Given that it's not a common case, we could just say that you have to put the nested array into a separate structure:
// also a host-shareable struct
type Nested = struct {
[[offset 0, stride 16]]
sub_array: array<i32, 5>,
};
type UniformBuffer = struct {
[[offset 0, stride 80]]
foo: array<Nested, 3>,
};