diff --git a/spec/index.bs b/spec/index.bs
index 857b139214..8081fd61f9 100644
--- a/spec/index.bs
+++ b/spec/index.bs
@@ -159,6 +159,7 @@ spec: WGSL; urlPrefix: https://gpuweb.github.io/gpuweb/wgsl/#
text: subgroup size; url: subgroup-size
type: abstract-op
text: SizeOf; url: sizeof
+ text: AccessibleSlots; url: accessible-slots
spec: Internationalization Glossary; urlPrefix: https://www.w3.org/TR/i18n-glossary/#
type: dfn
text: localizable text; url: dfn-localizable-text
@@ -1625,6 +1626,13 @@ A supported limits object has a value for every limit defined by
counting any empty slots below the highest index.
Validated in {{GPUDevice/createRenderPipeline()}} and [$valid to draw|in draw calls$].
+
@@ -1859,6 +1867,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureArrayLayers;
readonly attribute unsigned long maxBindGroups;
readonly attribute unsigned long maxBindGroupsPlusVertexBuffers;
+ readonly attribute unsigned long maxImmediateSize;
readonly attribute unsigned long maxBindingsPerBindGroup;
readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout;
readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout;
@@ -2596,6 +2605,7 @@ Any {{GPUAdapter}} returned by {{GPU/requestAdapter()}} must provide the followi
- {{supported limits/maxComputeWorkgroupSizeZ}} must be ≤ {{supported limits/maxComputeInvocationsPerWorkgroup}}.
- {{supported limits/maxComputeInvocationsPerWorkgroup}} must be ≤ {{supported limits/maxComputeWorkgroupSizeX}}
× {{supported limits/maxComputeWorkgroupSizeY}} × {{supported limits/maxComputeWorkgroupSizeZ}}.
+- {{supported limits/maxImmediateSize}} must be a multiple of 4 bytes.
### Adapter Selection ### {#adapter-selection}
@@ -6950,6 +6960,11 @@ GPUPipelineLayout includes GPUObjectBase;
: \[[bindGroupLayouts]], of type [=list=]<{{GPUBindGroupLayout}}>, readonly
::
The {{GPUBindGroupLayout}} objects provided at creation in {{GPUPipelineLayoutDescriptor/bindGroupLayouts|GPUPipelineLayoutDescriptor.bindGroupLayouts}}.
+
+ : \[[immediateSize]], of type {{GPUSize32}}, readonly
+ ::
+ The size in bytes of the immediate data range, provided at creation in {{GPUPipelineLayoutDescriptor/immediateSize|GPUPipelineLayoutDescriptor.immediateSize}}
+ (or by the [$default pipeline layout$]).
Note: using the same {{GPUPipelineLayout}} for many {{GPURenderPipeline}} or {{GPUComputePipeline}} pipelines guarantees that the user agent doesn't need to rebind any resources internally when there is a switch between these pipelines.
@@ -6979,6 +6994,7 @@ A {{GPUPipelineLayout}} is created via {{GPUDevice/createPipelineLayout()|GPUDev
dictionary GPUPipelineLayoutDescriptor
: GPUObjectDescriptorBase {
required sequence bindGroupLayouts;
+ GPUSize32 immediateSize = 0;
};
@@ -6991,6 +7007,10 @@ pipeline, and have the following members:
A list of optional {{GPUBindGroupLayout}}s the pipeline will use. Each element corresponds
to a [=@group=] attribute in the {{GPUShaderModule}}, with the `N`th element corresponding
with `@group(N)`.
+
+ : immediateSize
+ ::
+ The size, in bytes, of the immediate data range used by the pipeline.
@@ -7040,16 +7060,21 @@ pipeline, and have the following members:
- The [=list/size=] of |descriptor|.{{GPUPipelineLayoutDescriptor/bindGroupLayouts}}
must be ≤ |limits|.{{supported limits/maxBindGroups}}.
- |allEntries| must not [=exceeds the binding slot limits|exceed the binding slot limits=] of |limits|.
+ - |descriptor|.{{GPUPipelineLayoutDescriptor/immediateSize}} must be ≤
+ |limits|.{{supported limits/maxImmediateSize}}.
+ - |descriptor|.{{GPUPipelineLayoutDescriptor/immediateSize}} must be a multiple of 4.
1. Set the |pl|.{{GPUPipelineLayout/[[bindGroupLayouts]]}} to |bindGroupLayouts|.
+ 1. Set the |pl|.{{GPUPipelineLayout/[[immediateSize]]}} to |descriptor|.{{GPUPipelineLayoutDescriptor/immediateSize}}.
Note: two {{GPUPipelineLayout}} objects are considered equivalent for any usage
if their internal {{GPUPipelineLayout/[[bindGroupLayouts]]}} sequences contain
-{{GPUBindGroupLayout}} objects that are [=group-equivalent=].
+{{GPUBindGroupLayout}} objects that are [=group-equivalent=] and their
+{{GPUPipelineLayout/[[immediateSize]]}} values are equal.
## Example ## {#bindgroup-examples}
@@ -7692,6 +7717,7 @@ To create a default pipeline layout for {{GPUPipelineBase
run the following [=device timeline=] steps:
1. Let |groupCount| be 0.
+ 1. Let |immediateSize| be 0.
1. Let |groupDescs| be a sequence of |device|.{{device/[[limits]]}}.{{supported limits/maxBindGroups}}
new {{GPUBindGroupLayoutDescriptor}} objects.
1. For each |groupDesc| in |groupDescs|:
@@ -7824,6 +7850,11 @@ run the following [=device timeline=] steps:
1. Append |entry| to |groupDescs|[|group|].
+ 1. If there is an immediate data variable that is [=statically used=] by |entryPoint|
+ ([=assert=] there is at most one):
+ 1. Let |T| be the [=store type=] of the immediate data variable.
+ 1. Set |immediateSize| to max(|immediateSize|, [=roundUp=](4, [$SizeOf$](|T|))).
+
1. Let |groupLayouts| be a new [=list=].
1. For each |i| from 0 to |groupCount| - 1, inclusive:
1. Let |groupDesc| be |groupDescs|[|i|].
@@ -7833,6 +7864,7 @@ run the following [=device timeline=] steps:
1. Let |desc| be a new {{GPUPipelineLayoutDescriptor}}.
1. Set |desc|.{{GPUPipelineLayoutDescriptor/bindGroupLayouts}} to |groupLayouts|.
+ 1. Set |desc|.{{GPUPipelineLayoutDescriptor/immediateSize}} to |immediateSize|.
1. Return |device|.{{GPUDevice/createPipelineLayout()}}(|desc|).
@@ -8014,6 +8046,11 @@ typedef double GPUPipelineConstantValue; // May represent WGSL's bool, f32, i32,
- If the pipeline-overridable constant identified by |key|
[=pipeline-overridable constant default value|does not have a default value=],
|descriptor|.{{GPUProgrammableStage/constants}} |must| [=map/contain=] |key|.
+ 1. If there is an immediate data variable that is [=statically used=] by |entryPoint|
+ ([=assert=] there is at most one):
+ - Let |T| be the [=store type=] of the immediate data variable.
+ - Let |requiredSize| be [$SizeOf$](|T|).
+ - |layout|.{{GPUPipelineLayout/[[immediateSize]]}} must be ≥ |requiredSize|.
1. [=pipeline-creation error|Pipeline-creation=] [=program errors=] |must| not
result from the rules of the [[WGSL]] specification.
1.
@@ -11263,6 +11300,9 @@ interface mixin GPUBindingCommandsMixin {
[AllowShared] Uint32Array dynamicOffsetsData,
GPUSize64 dynamicOffsetsDataStart,
GPUSize32 dynamicOffsetsDataLength);
+
+ undefined setImmediates(GPUSize32 rangeOffset, AllowSharedBufferSource data,
+ optional GPUSize64 dataOffset = 0, optional GPUSize64 dataSize);
};
@@ -11277,9 +11317,21 @@ It must only be included by interfaces which also include those mixins.
::
The current {{GPUBindGroup}} for each index.
- : \[[dynamic_offsets]], of type [=ordered map=]<{{GPUIndex32}}, [=list=]<{{GPUBufferDynamicOffset}}>>, initally empty
+ : \[[dynamic_offsets]], of type [=ordered map=]<{{GPUIndex32}}, [=list=]<{{GPUBufferDynamicOffset}}>>, initially empty
::
The current dynamic offsets for each {{GPUBindingCommandsMixin/[[bind_groups]]}} entry.
+
+ : \[[immediate_data]], of type [=byte sequence=]
+ ::
+ The current immediate data bytes.
+ Initially a [=byte sequence=] of length equal to the device's {{supported limits/maxImmediateSize}}, with all bytes set to zero.
+ Values are set by {{GPUBindingCommandsMixin/setImmediates()}}.
+
+ : \[[immediate_slots_set]], of type [=list=]<{{boolean}}>
+ ::
+ Tracks which 32-bit word slots of immediate data have been set.
+ Initially a [=list=] of length equal to the device's {{supported limits/maxImmediateSize}} divided by 4, with all entries set to `false`.
+ Each entry corresponds to a 4-byte slot.
## Bind Groups ## {#programmable-passes-bind-groups}
@@ -11484,7 +11536,6 @@ It must only be included by interfaces which also include those mixins.
-
To Iterate over each dynamic binding offset in a given {{GPUBindGroup}} |bindGroup|
with a given list of |steps| to be executed for each dynamic offset, run the following [=device timeline=] steps:
@@ -11573,6 +11624,32 @@ It must only be included by interfaces which also include those mixins.
Otherwise return `true`.
+
+ Validate immediate data(encoder, pipeline)
+
+ **Arguments:**
+
+ : {{GPUBindingCommandsMixin}} |encoder|
+ :: Encoder whose immediate data is being validated.
+ : {{GPUPipelineBase}} |pipeline|
+ :: Pipeline to validate |encoder|'s immediate data is compatible with.
+
+ [=Device timeline=] steps:
+
+ 1. If any of the following conditions are unsatisfied, return `false`:
+
+
+ - |pipeline| must not be `null`.
+ - For each immediate data variable that is [=statically used=] by any entry point in |pipeline|:
+ - Let |T| be the [=store type=] of the immediate data variable.
+ - Let |accessibleSlots| be [$AccessibleSlots$](|T|) as defined in [[WGSL]].
+ - For each |slotIndex| in |accessibleSlots|:
+ - |encoder|.{{GPUBindingCommandsMixin/[[immediate_slots_set]]}}[|slotIndex|] must be `true`.
+
+
+ Otherwise return `true`.
+
+
Encoder bind groups alias a writable resource(|encoder|, |pipeline|)
if any writable buffer binding range overlaps with any other binding range of the same buffer,
@@ -11630,6 +11707,71 @@ It must only be included by interfaces which also include those mixins.
Implementations are strongly encouraged to optimize this algorithm.
+## Immediate Data ## {#programmable-passes-immediate-data}
+
+
+ : setImmediates(rangeOffset, data, dataOffset, dataSize)
+ ::
+ Sets immediate data for subsequent render or compute commands.
+
+
+
+ **Called on:** {{GPUBindingCommandsMixin}} |this|.
+
+ **Arguments:**
+
+
+ |rangeOffset|: Offset in bytes into the immediate data range to begin writing at.
+ |data|: Data to write into the immediate data range.
+ |dataOffset|: Offset into |data| to begin writing from. Given in elements if
+ |data| is a {{TypedArray}} and bytes otherwise.
+ |dataSize|: Size of content to write from |data|. Given in elements if
+ |data| is a {{TypedArray}} and bytes otherwise.
+
+
+ **Returns:** {{undefined}}
+
+ [=Content timeline=] steps:
+
+ 1. If |data| is an {{ArrayBuffer}} or {{DataView}}, let the element type be "byte".
+ Otherwise, |data| is a TypedArray; let the element type be the type of the TypedArray.
+ 1. Let |dataElementCount| be the size of |data|, in elements.
+ 1. If |dataSize| is missing,
+ let |contentsSize| be |dataElementCount| − |dataOffset|.
+ Otherwise, let |contentsSize| be |dataSize|.
+ 1. If any of the following conditions are unsatisfied,
+ throw an {{OperationError}} and return.
+
+
+ - |contentsSize| ≥ 0.
+ - |dataOffset| + |contentsSize| ≤ |dataElementCount|.
+ - |contentsSize|, converted to bytes, is a multiple of 4.
+
+ 1. Let |dataContents| be [=get a copy of the buffer source|a copy of the bytes held by the buffer source=] |data|.
+ 1. Let |contents| be the |contentsSize| elements of |dataContents| starting at
+ an offset of |dataOffset| elements.
+ 1. Let |contentsBytes| be |contentsSize| converted to bytes.
+ 1. Issue the subsequent steps on the [=Device timeline=] of |this|.{{GPUObjectBase/[[device]]}}.
+
+
+ [=Device timeline=] steps:
+
+ 1. [$Validate the encoder state$] of |this|. If it returns false, return.
+ 1. If any of the following conditions are unsatisfied, [$invalidate$] |this| and return.
+
+
+ - |rangeOffset| is a multiple of 4.
+ - |rangeOffset| + |contentsBytes| ≤ |this|.{{GPUObjectBase/[[device]]}}.{{device/[[limits]]}}.{{supported limits/maxImmediateSize}}.
+
+ 1. For each byte |b| at index |i| in |contents|:
+ 1. Let |byteIndex| be |rangeOffset| + |i|.
+ 1. Let |slotIndex| be floor(|byteIndex| ÷ 4).
+ 1. Set |this|.{{GPUBindingCommandsMixin/[[immediate_data]]}}[|byteIndex|] to |b|.
+ 1. Set |this|.{{GPUBindingCommandsMixin/[[immediate_slots_set]]}}[|slotIndex|] to true.
+
+
+
+
# Debug Markers # {#debug-markers}
GPUDebugCommandsMixin provides methods to apply debug labels to groups
@@ -11918,10 +12060,12 @@ dictionary GPUComputePassDescriptor
- |usageScope| must satisfy [=usage scope validation=].
- [$Validate encoder bind groups$](|this|, |this|.{{GPUComputePassEncoder/[[pipeline]]}})
is `true`.
+ - [$Validate immediate data$](|this|, |this|.{{GPUComputePassEncoder/[[pipeline]]}})
+ is `true`.
- all of |workgroupCountX|, |workgroupCountY| and |workgroupCountZ| are ≤
|this|.device.limits.{{supported limits/maxComputeWorkgroupsPerDimension}}.
- let |workgroupSize| be the computed workgroup size for
- |bindingState|.{{GPUComputePassEncoder/[[pipeline]]}}.
+ |bindingState|.{{GPUComputePassEncoder/[[pipeline]]}}.
- the entry point uses the [=builtin/workgroup_index=]
built-in value and |workgroupCountX| × |workgroupCountY|
× |workgroupCountZ|
@@ -11997,6 +12141,8 @@ dictionary GPUComputePassDescriptor
- |usageScope| must satisfy [=usage scope validation=].
- [$Validate encoder bind groups$](|this|, |this|.{{GPUComputePassEncoder/[[pipeline]]}})
is `true`.
+ - [$Validate immediate data$](|this|, |this|.{{GPUComputePassEncoder/[[pipeline]]}})
+ is `true`.
- |indirectBuffer| is [$valid to use with$] |this|.
- |indirectBuffer|.{{GPUBuffer/usage}} contains {{GPUBufferUsage/INDIRECT}}.
- |indirectOffset| + sizeof([=indirect dispatch parameters=]) ≤
@@ -13413,6 +13559,8 @@ It must only be included by interfaces which also include those mixins.
- [$Validate encoder bind groups$](|encoder|, |encoder|.{{GPURenderCommandsMixin/[[pipeline]]}})
must be `true`.
+ - [$Validate immediate data$](|encoder|, |encoder|.{{GPURenderCommandsMixin/[[pipeline]]}})
+ must be `true`.
- Let |pipelineDescriptor| be |encoder|.{{GPURenderCommandsMixin/[[pipeline]]}}.{{GPURenderPipeline/[[descriptor]]}}.
- For each {{GPUIndex32}} |slot| `0` to
|pipelineDescriptor|.{{GPURenderPipelineDescriptor/vertex}}.{{GPUVertexState/buffers}}.[=list/size=]:
@@ -13731,8 +13879,8 @@ attachments used by this encoder.
this render pass.
When a {{GPURenderBundle}} is executed, it does not inherit the render pass's pipeline, bind
- groups, or vertex and index buffers. After a {{GPURenderBundle}} has executed, the render
- pass's pipeline, bind group, and vertex/index buffer state is cleared
+ groups, immediate data, or vertex and index buffers. After a {{GPURenderBundle}} has executed, the render
+ pass's pipeline, bind group, immediate data, and vertex/index buffer state is cleared
(to the initial, empty values).
Note: The state is cleared, not restored to the previous state.
@@ -13797,6 +13945,7 @@ attachments used by this encoder.
the following [=device timeline=] steps:
1. [=map/Clear=] |encoder|.{{GPUBindingCommandsMixin/[[bind_groups]]}}.
+ 1. Set each entry of |encoder|.{{GPUBindingCommandsMixin/[[immediate_slots_set]]}} to `false`.
1. Set |encoder|.{{GPURenderCommandsMixin/[[pipeline]]}} to `null`.
1. Set |encoder|.{{GPURenderCommandsMixin/[[index_buffer]]}} to `null`.
1. [=map/Clear=] |encoder|.{{GPURenderCommandsMixin/[[vertex_buffers]]}}.
diff --git a/wgsl/index.bs b/wgsl/index.bs
index 61201dd777..74e97765f6 100644
--- a/wgsl/index.bs
+++ b/wgsl/index.bs
@@ -260,6 +260,7 @@ spec: WebGPU; urlPrefix: https://gpuweb.github.io/gpuweb/#
text: front-facing; url: front-facing
text: shader-output mask; url: shader-output-mask
text: framebuffer; url: framebuffer
+ text: immediateSize; url: dom-gpupipelinelayoutdescriptor-immediatesize
text: normalized device coordinates; url: ndc
text: clip space coordinates; url: clip-space-coordinates
text: clip position; url: clip-position
@@ -268,6 +269,7 @@ spec: WebGPU; urlPrefix: https://gpuweb.github.io/gpuweb/#
text: rasterizationpoint-depth; url: rasterizationpoint-depth
text: rasterizationpoint-perspectivedivisor; url: rasterizationpoint-perspectivedivisor
text: fragmentdestination-position; url: fragmentdestination-position
+ text: setImmediates; url: dom-gpubindingcommandsmixin-setimmediates
text: subgroups-feature; url: subgroups
text: subgroupMinSize; url: dom-gpuadapterinfo-subgroupminsize
text: subgroupMaxSize; url: dom-gpuadapterinfo-subgroupmaxsize
@@ -275,6 +277,7 @@ spec: WebGPU; urlPrefix: https://gpuweb.github.io/gpuweb/#
text: texture view swizzle; url: dom-gputextureviewdescriptor-swizzle
for: supported limits
text: maxComputeWorkgroupStorageSize; url: dom-supported-limits-maxcomputeworkgroupstoragesize
+ text: maxImmediateSize; url: dom-supported-limits-maximmediatesize
type: attribute
for: GPU
text: wgslLanguageFeatures; url: gpuwgsllanguagefeatures
@@ -942,6 +945,11 @@ shader that goes beyond the specified limits.
This maps the WebGPU [=supported limits/maxComputeWorkgroupStorageSize=] limit
into a standalone WGSL limit.
[=supported limits/maxComputeWorkgroupStorageSize|16384=]
+ | | Maximum [=byte-size=] of an [=immediate data=] [=variable=].
+
+ This maps the WebGPU [=supported limits/maxImmediateSize=] limit
+ into a standalone WGSL limit.
+ | [=supported limits/maxImmediateSize|64=]
| | Maximum number of elements in [[#value-constructor-builtin-function|value constructor]] expression of [=array=] type | 2047
@@ -1499,6 +1507,7 @@ The [=language extension=] names are:
* `'texture_and_sampler_let'`
* `'texture_formats_tier1'`
* `'linear_indexing'`
+* `'immediate_data'`
### Interpolation Type Names ### {#interpolation-type-names}
@@ -1998,6 +2007,11 @@ Extension names are not [=identifiers=]: they do not [=resolves|resolve=] to [=d
|
Supports the [=built-in values/global_invocation_index=] and
[=built-in values/workgroup_index=] [=built-in values=].
+ | | immediate_data
+ |
+ Enables the [=address spaces/immediate=] address space, allowing variables
+ to be declared with `var` and bound to small amounts of frequently
+ updated data passed directly from the command encoder via the WebGPU API.
@@ -4910,6 +4924,14 @@ effective-value-type.
|
| Yes. [=uniform buffer=]
+ | | [=variable|var=]<[=address spaces/immediate=]>
+ | Immutable
+ | [=module scope|Module=]
+ | [=type/concrete|Concrete=] [=constructible=] [=host-shareable=], excluding arrays and structures containing array members
+ | Disallowed
+ |
+ | Yes. [=immediate data=]
+
| | [=variable|var=]6
| Immutable7
| [=module scope|Module=]
@@ -5194,6 +5216,22 @@ Its [=store type=] must be a [=host-shareable=] type and must satisfy the
The variable may be declared with a [=access/read=] or [=access/read_write=]
access mode; the default is read.
+A variable in the [=address spaces/immediate=] address space is an immediate data variable.
+Its [=store type=] [=shader-creation error|must=] be a [=host-shareable=] [=constructible=] type,
+excluding arrays and structures that contain array members.
+Each [=entry point=] [=shader-creation error|must=] [=statically access=] at most one immediate data variable.
+The value of an immediate variable is set via [=setImmediates=] commands recorded by the WebGPU API command encoder,
+and remains constant during shader execution.
+The variable size is limited by the pipeline layout's [=immediateSize=] configuration.
+
+
+The [=AccessibleSlots=] exclude padding bytes between structure members and at the end of structures.
+Only the accessible slots need to be initialized via the WebGPU API
+before the immediate data variable is accessed in a shader.
+
+
+
A texture resource is a variable whose [=effective-value-type=] is a [=texture type=].
It is declared at [=module scope=].
It holds an opaque handle which is used to access the underlying grid of [=texels=] in a [=texture=].
@@ -7620,17 +7658,17 @@ path: syntax/for_init.syntax.bs.include
path: syntax/for_update.syntax.bs.include
-The for statement is syntactic sugar over a [=compound statement=]
+The for statement is syntactic sugar over a [=compound statement=]
containing a [=statement/loop=] statement.
-In general, the `for` statement takes the form
+In general, the `for` statement takes the form
> `for (` *initializer* `;` *condition* `;` *update_part* `) {` *body* `}`
When the condition expression is present, the `for` statement desugars to a loop of the form:
- {
- *initializer* ;
+ {
+ *initializer* ;
loop {
if !(*condition*) { break; }
*body*
@@ -7641,8 +7679,8 @@ When the condition expression is present, the `for` statement desugars to a loop
When the condition expression is absent, the `for` statement desugars to a loop of the form:
- {
- *initializer* ;
+ {
+ *initializer* ;
loop {
*body*
continuing { *update_part* }
@@ -9377,6 +9415,7 @@ The interface includes:
* [=Shader stage inputs=]
* [=Shader stage outputs=]
* [=Override-declarations=]
+* [=Immediate data=]
* Attached [=resources=], which include:
* [=Uniform buffers=]
* [=Storage buffers=]
@@ -9410,6 +9449,8 @@ We can now precisely define the interface of a shader as con
[=statically accessed=] by the shader.
- The [=override-declarations=]
[=statically accessed=] by the shader.
+ - The [=immediate data=] variables
+ [=statically accessed=] by the shader.
### Inter-stage Input and Output Interface ### {#stage-inputs-outputs}
@@ -10304,7 +10345,7 @@ If not, a [=pipeline-creation error=] [=behavioral requirement|will=] result.
### Resource Interface ### {#resource-interface}
A resource is an object which provides access to data external to a [=shader stage=],
-and which is not an [=override-declaration=] and not a [[#stage-inputs-outputs|shader stage input or output]].
+and which is not an [=override-declaration=], not an [=immediate data=] variable, and not a [[#stage-inputs-outputs|shader stage input or output]].
Resources are shared by all invocations of the shader.
There are four kinds of resources:
@@ -10324,6 +10365,9 @@ Together with the shader's stage, these identify the binding address
of the resource on the shader's pipeline.
See [[WebGPU#gpupipelinelayout]].
+[=Immediate data=] variables do not use [=attribute/group=] or [=attribute/binding=] attributes.
+
+
Two different resource variables in a [=shader=] [=shader-creation error|must
not=] have the same [=attribute/group=] and [=attribute/binding=] values, when
considered as a pair.
@@ -10595,6 +10639,11 @@ table.
Invocations in the same [=shader stage=]
| [=access/read=]
| For [=storage buffer=] variables
+ | | immediate
+ | Invocations in the same [=shader stage=]
+ | [=access/read=]
+ | For [=immediate data=] variables.
+ Each [=entry point=] can [=statically access=] at most one immediate variable.
| | handle
| Invocations in the same shader stage
| [=access/read=]
@@ -10666,6 +10715,18 @@ and |A| is a host-shareable or fixed footprint array or runtime-sized array:
[=StrideOf=](array<|E|, |N|>) = [=roundUp=]([=AlignOf=](E), [=SizeOf=](E))
[=StrideOf=](array<|E|>) = [=roundUp=]([=AlignOf=](E), [=SizeOf=](E))
+* AccessibleBytes(|T|) is the set of byte offsets within an instance of type |T| that contain data.
+ * If |T| is a scalar or vector, then [=AccessibleBytes=](|T|) is the set of integers `k` such that `0 <= k <` [=SizeOf=](|T|).
+ * If |T| is a matrix with |C| columns and |R| rows, then [=AccessibleBytes=](|T|) is the set calculated as:
+ * Let `Stride` be [=roundUp=]([=AlignOf=](vec|R|), [=SizeOf=](vec|R|)).
+ * For each `i` in `0..C-1`:
+ * For each `k` in [=AccessibleBytes=](vec|R|):
+ * The set contains `k + i * Stride`.
+ * If |T| is a structure |S|, then [=AccessibleBytes=](|T|) is the set calculated as:
+ * For each member `M_i` at byte offset `Offset` = [=OffsetOfMember=](|S|, `i`):
+ * For each `k` in [=AccessibleBytes=](`M_i`):
+ * The set contains `k + Offset`.
+* AccessibleSlots(|T|) is the set of integers `i` such that the intersection of the interval `[4*i, 4*i+4)` and [=AccessibleBytes=](|T|) is not empty.
### Alignment and Size ### {#alignment-and-size}
@@ -11129,7 +11190,7 @@ sections and then the resulting layout is validated against the
[=RequiredAlignOf=](|T|, |C|) rules.
-->
-When [=language_extension/uniform_buffer_standard_layout=] is **not** supported,
+When [=language_extension/uniform_buffer_standard_layout=] is **not** supported,
the [=address spaces/uniform=] address space requires that:
* Array elements are aligned to 16 byte boundaries.
That is, [=StrideOf=](array<|T|,|N|>) = 16 × |k|' for some positive integer |k|'.
| | | |