Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
init
  • Loading branch information
Peter McNeeley committed Mar 22, 2026
commit 8b953efd6b1b606502ebf76874c793abe6dfe59b
11 changes: 11 additions & 0 deletions spec/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -3049,6 +3049,7 @@ enum GPUFeatureName {
"texture-formats-tier2",
"primitive-index",
"texture-component-swizzle",
"atomic-vec2u-min-max",
};
</script>

Expand Down Expand Up @@ -17400,6 +17401,16 @@ This feature adds the following [=optional API surfaces=]:
- New {{GPUTextureViewDescriptor}} dictionary members:
- {{GPUTextureViewDescriptor/swizzle}}

<h3 id=dom-gpufeaturename-atomic-vec2u-min-max data-dfn-type=enum-value data-dfn-for=GPUFeatureName>`"atomic-vec2u-min-max"`
</h3>

Allows the use of 64-bit atomic minimum and maximum operations on `atomic<vec2u>` in WGSL.

This feature adds the following [=optional API surfaces=]:

- New WGSL language extensions:
- [=language_extension/atomic_vec2u_min_max=]
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated

# Appendices # {#appendices}

## Texture Format Capabilities ## {#texture-format-caps}
Expand Down
106 changes: 91 additions & 15 deletions wgsl/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ spec: WebGPU; urlPrefix: https://gpuweb.github.io/gpuweb/#
text: subgroupMaxSize; url: dom-gpuadapterinfo-subgroupmaxsize
text: primitive restart value; url: primitive-restart-value
text: texture view swizzle; url: dom-gputextureviewdescriptor-swizzle
text: shader-f16; url: shader-f16
text: clip-distances; url: dom-gpufeaturename-clip-distances
text: dual-source-blending; url: dom-gpufeaturename-dual-source-blending
Comment thread
petermcneeleychromium marked this conversation as resolved.
text: atomic-vec2u-min-max; url: dom-gpufeaturename-atomic-vec2u-min-max
for: supported limits
text: maxComputeWorkgroupStorageSize; url: dom-supported-limits-maxcomputeworkgroupstoragesize
type: attribute
Expand All @@ -286,6 +290,7 @@ spec: WebGPU; urlPrefix: https://gpuweb.github.io/gpuweb/#
type: enum-value
for: GPUFeatureName
text: "primitive-index"; url: dom-gpufeaturename-primitive-index
text: "atomic-vec2u-min-max"; url: dom-gpufeaturename-atomic-vec2u-min-max
</pre>

# Introduction # {#intro}
Expand Down Expand Up @@ -1002,7 +1007,7 @@ When the scanner attempts to match the [=syntax_sym/_disambiguate_template=] tok
Future token scanning steps will use the recorded template list delimiter positions to yield
[=syntax_sym/_template_args_start=] and [=syntax_sym/_template_args_end=] tokens as indicated.

This alternative approach is non-normative.
This alternative approach is non-normative.
The normative grammar includes [=syntax_sym/_disambiguate_template=] tokens as a help to implementations
using the alternative approach.
A parser using the standard approach can either ignore the synthetic token, or equivalently, always successfully
Expand Down Expand Up @@ -1855,6 +1860,12 @@ The valid [=enable-extensions=] are listed in the following table.
<td>The built-in variable [=built-in values/primitive_index=] is valid to use in the WGSL
module. Otherwise, using [=built-in values/primitive_index=] will result in a
[=shader-creation error=].
<tr><td><dfn noexport dfn-for="extension">`atomic_vec2u_min_max`</dfn>
<td>[=atomic-vec2u-min-max|"atomic-vec2u-min-max"=]
<td>The built-in functions [[#atomic-store-min|atomicStoreMin]] and
[[#atomic-store-max|atomicStoreMax]] are valid to use on `atomic<vec2u>`
objects in the WGSL module. Otherwise, using these will result in a
[=shader-creation error=].
</table>

<div class='example wgsl using extensions expect-error' heading="Using hypothetical enable-extensions">
Expand Down Expand Up @@ -1998,6 +2009,11 @@ Extension names are not [=identifiers=]: they do not [=resolves|resolve=] to [=d
<td>
Supports the [=built-in values/global_invocation_index=] and
[=built-in values/workgroup_index=] [=built-in values=].
<tr><td><dfn for="language_extension">atomic_vec2u_min_max</dfn>
<td>
Supports the [[#atomic-store-min|atomicStoreMin]] and
[[#atomic-store-max|atomicStoreMax]] built-in functions
on [[#atomic-types|atomic&lt;vec2u&gt;]] objects.

</table>

Expand Down Expand Up @@ -3042,14 +3058,17 @@ An <dfn noexport>atomic type</dfn> encapsulates a [=type/concrete=] [=integer sc
<thead>
<tr><th>Type<th>Description
</thead>
<tr algorithm="atomic type"><td>atomic&lt;|T|&gt;
<td>Atomic of type |T|. |T| [=shader-creation error|must=] be either [=u32=] or [=i32=].
<tr algorithm="atomic type"><td>atomic&lt;<dfn dfn-for="atomic" noexport>|T|</dfn>&gt;
Comment thread
petermcneeleychromium marked this conversation as resolved.
<td>Atomic of type |T|. Unless otherwise specified, |T| [=shader-creation error|must=] be either [=u32=] or [=i32=].
<tr algorithm="atomic type vecu"><td>atomic&lt;[=vec2u=]&gt;
<td>Atomic of type [=vec2u=]. A 64-bit atomic type via a composite. Requires the [=language_extension/atomic_vec2u_min_max=] extension.
</table>

An expression [=shader-creation error|must not=] evaluate to an atomic type.

Atomic types may only be instantiated by variables in the [=address spaces/workgroup=]
address space or by [=storage buffer=] variables with a [=access/read_write=] access mode.
[=atomic/T=] [=shader-creation error|must not=] be [=vec2u=] if the [=address space=] is [=address spaces/workgroup=].
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated
The [=memory scope=] of operations on the type is determined by the [=address space=]
it is instantiated in.
Atomic types in the [=address spaces/workgroup=] address space have a
Expand Down Expand Up @@ -7620,17 +7639,17 @@ path: syntax/for_init.syntax.bs.include
path: syntax/for_update.syntax.bs.include
</pre>

The <dfn dfn-for="statement">for</dfn> statement is syntactic sugar over a [=compound statement=]
The <dfn dfn-for="statement">for</dfn> 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:

<blockquote>
{ <br> &nbsp; &nbsp;
*initializer* ; <br> &nbsp; &nbsp;
{ <br> &nbsp; &nbsp;
*initializer* ; <br> &nbsp; &nbsp;
loop { <br> &nbsp; &nbsp; &nbsp; &nbsp;
if !(*condition*) { break; } <br> &nbsp; &nbsp; &nbsp; &nbsp;
*body* <br> &nbsp; &nbsp; &nbsp; &nbsp;
Expand All @@ -7641,8 +7660,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:

<blockquote>
{ <br> &nbsp; &nbsp;
*initializer* ; <br> &nbsp; &nbsp;
{ <br> &nbsp; &nbsp;
*initializer* ; <br> &nbsp; &nbsp;
loop { <br> &nbsp; &nbsp; &nbsp; &nbsp;
*body* <br> &nbsp; &nbsp; &nbsp; &nbsp;
continuing { *update_part* } <br> &nbsp; &nbsp;
Expand Down Expand Up @@ -11129,7 +11148,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&lt;|T|,|N|&gt;) = 16 &times; |k|' for some positive integer |k|'.
Expand Down Expand Up @@ -11967,7 +11986,7 @@ In analyzing loops, we use the following patterns:
uniformity when first arriving at the loop.
* Note: [[#behaviors|Statement behavior analysis]] implies that the
behavior of a loop is one of {Next}, {Return}, or {Next,Return}.

<table class='data'>
<caption>Uniformity rules for statements</caption>
<thead>
Expand Down Expand Up @@ -12226,7 +12245,7 @@ Here is the list of exceptions:
- If there is no such *DF*,
the call site tag is [=CallSiteRequiredToBeUniform.S|CallSiteRequiredToBeUniform.error=], with [=potential-trigger-set=]
consisting of a [=trigger/derivative_uniformity=] element.
- [=CallSiteNoRestriction=] otherwise.
- [=CallSiteNoRestriction=] otherwise.
- A call to [[#textureload]]:
- Has a [=call site tag=] of [=CallSiteNoRestriction=]
- Has a [=function tag=] as follows:
Expand Down Expand Up @@ -18726,7 +18745,8 @@ Atomic built-in functions [=shader-creation error|must not=] be used in a [=vert
The address space `AS` of the `atomic_ptr` parameter in all atomic built-in
functions [=shader-creation error|must=] be either [=address spaces/storage=] or [=address spaces/workgroup=].

|T| [=shader-creation error|must=] be either [=u32=] or [=i32=]
Unless otherwise specified, |T| [=shader-creation error|must=] be either [=u32=] or [=i32=].


### `atomicLoad` ### {#atomic-load}

Expand Down Expand Up @@ -18960,8 +18980,64 @@ fn atomicCompareExchangeWeak(atomic_ptr: ptr<AS, atomic<T>, read_write>, cmp : T
</div>

Note: The equality comparison may spuriously fail on some implementations. That
is, the second component of the result vector may be `false` even if the first
component of the result vector equals `cmp`.
is, the `exchanged` member of the result structure may be `false` even if the
`old_value` member equals `cmp`.

### Atomic Store Min and Max Functions ### {#atomic-store-min-max}

The functions in this section [=behavioral requirement|will=] be available only if
the [=language_extension/atomic_vec2u_min_max=] [=language extension=] is supported.

Each function performs the following steps atomically:

1. Load the original value pointed to by `atomic_ptr`.
2. Obtains a new value by performing the operation (e.g. max) from the function
name with the value |v|.
3. Store the new value using `atomic_ptr`.

The functions do not return any values.

For the functions in this section:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe hardcoding these constraints is better.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With that done, these constraints can be removed.

- |T| [=shader-creation error|must=] be [=vec2u=].
- `AS` [=shader-creation error|must=] be [=address spaces/storage=].

#### `atomicStoreMin` #### {#atomic-store-min}

```wgsl
fn atomicStoreMin(atomic_ptr: ptr<AS, atomic<T>, read_write>, v: T)
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated
```

Atomically performs a minimum operation on the atomic object pointed to by `atomic_ptr`
with the value `v`.

<div class='example wgsl global-scope' heading='Operation of atomic store min as a function'>
<xmp highlight=wgsl>
// All operations are performed atomically
fn atomicStoreMin(atomic_ptr: ptr<AS, atomic<T>, read_write>, v : T) {
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated
let old = *atomic_ptr;
*atomic_ptr = min(old, v);
}
</xmp>
</div>

#### `atomicStoreMax` #### {#atomic-store-max}

```wgsl
fn atomicStoreMax(atomic_ptr: ptr<AS, atomic<T>, read_write>, v: T)
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated
```

Atomically performs a maximum operation on the atomic object pointed to by `atomic_ptr`
with the value `v`.

<div class='example wgsl global-scope' heading='Operation of atomic store max as a function'>
<xmp highlight=wgsl>
// All operations are performed atomically
fn atomicStoreMax(atomic_ptr: ptr<AS, atomic<T>, read_write>, v : T) {
Comment thread
petermcneeleychromium marked this conversation as resolved.
Outdated
let old = *atomic_ptr;
*atomic_ptr = max(old, v);
}
</xmp>
</div>

## Data Packing Built-in Functions ## {#pack-builtin-functions}

Expand Down