Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 13 additions & 1 deletion spec/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ spec: WGSL; urlPrefix: https://gpuweb.github.io/gpuweb/wgsl/#
text: dual_source_blending; url: extension-dual_source_blending
text: subgroups; url: extension-subgroups
text: primitive_index; url: extension-primitive_index
text: atomic_vec2u_min_max; url: extension-atomic_vec2u_min_max
for: language-extension
text: readonly_and_readwrite_storage_textures; url: language_extension-readonly_and_readwrite_storage_textures
text: packed_4x8_integer_dot_product; url: language_extension-packed_4x8_integer_dot_product
Expand Down Expand Up @@ -3049,6 +3050,7 @@ enum GPUFeatureName {
"texture-formats-tier2",
"primitive-index",
"texture-component-swizzle",
"atomic-vec2u-min-max",
};
</script>

Expand Down Expand Up @@ -11921,7 +11923,7 @@ dictionary GPUComputePassDescriptor
- all of |workgroupCountX|, |workgroupCountY| and |workgroupCountZ| are &le;
|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| &times; |workgroupCountY|
&times; |workgroupCountZ|
Expand Down Expand Up @@ -17400,6 +17402,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:
- [=extension/atomic_vec2u_min_max=]

# 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&lt;[=vec2u=]&gt;
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.

Nit: I'd definitely link atomic to atomic types here.

types in the [=address spaces/storage=] address space. 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 @@ -3042,14 +3053,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=]. This composite constitutes an unsigned [=64-bit integer=] atomic type whose value is equivalent to `bitcast<u64>`. Enabled by the [=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.
The encapsulated type [=shader-creation error|must not=] be [=vec2u=] if the [=address space=] is [=address spaces/workgroup=].
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 +7634,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 +7655,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 +11143,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 +11981,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 +12240,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 +18740,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 +18975,69 @@ 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 [=extension/atomic_vec2u_min_max=] [=enable-extension=] is enabled.

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 a value.

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=].
- This composite operationally behaves as a single 64-bit unsigned integer scalar.
- `AS` [=shader-creation error|must=] be [=address spaces/storage=].

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

```wgsl
fn atomicStoreMin(atomic_ptr: ptr<storage, atomic<vec2<u32>>, read_write>,
v: vec2<u32>)
```

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<storage, atomic<vec2<u32>>, read_write>,
v : vec2<u32>) {
// both 'old' and 'v' behave operationally as 64-bit unsigned integer scalars
let old = *atomic_ptr;
*atomic_ptr = min(old, v);
}
</xmp>
</div>

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

```wgsl
fn atomicStoreMax(atomic_ptr: ptr<storage, atomic<vec2<u32>>, read_write>, v: vec2<u32>)
```

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<storage, atomic<vec2<u32>>, read_write>, v : vec2<u32>) {
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.

Same here.

// both 'old' and 'v' behave operationally as 64-bit unsigned integer scalars
let old = *atomic_ptr;
*atomic_ptr = max(old, v);
}
</xmp>
</div>

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

Expand Down
Loading
Loading