Rule 8.3
Chapter 8, Functions and entry points Test
A builtin WGSL confines by stage may be used in an entry of a permitted stage, and in a helper that no entry of an excluded stage can reach.
The derivatives, implicit-LOD sampling, and discard may be used in the fragment stage only.
Barriers and workgroup memory may be used in the compute stage only.
The atomic builtins may be used in the compute and fragment stages, and must not be used in the vertex stage.
The rule text and the parts under it are the compiler's own English, as the design document writes them.
Rationale
the stage rule is Tint’s, and the call graph is how a helper inherits it.
Derives from
- Derivative Built-in Functions (“must only be used in a fragment shader stage”);
- Discard Statement;
- Synchronization Built-in Functions (“all synchronization functions must only be used in the compute shader stage”);
- Address Spaces (“variables in the workgroup address space must only be statically accessed in a compute shader stage”);
- Atomic Built-in Functions (“atomic built-in functions must not be used in a vertex shader stage”, with no other stage restriction);
- surface §10, §24, and §25.
How it is verified
Checked by a test. A test, a gate script or a CI workflow names this rule, and the traceability check fails when a file listed below stops naming it.
Where the rule says the compiler enforces it:
- the reachability check in
src/compiler/ts/lower/function.ts(TS8099names the builtin, the helper, and the entry) for the fragment-only builtins; TS8033for workgroup memory, andTS8034for a barrier outside a compute entry (a barrier in a branch is Rule 8.5’sTS8052);TS8099for an atomic builtin in a@vertexentry or in a helper it reaches ("atomicAdd" is only valid in a fragment or compute shader; "vs" is a vertex entry. WGSL allows an atomic built-in in a fragment or compute stage only.), pinned bysrc/compiler/ts/atomics.test.ts(refuses atomicAdd in a vertex entry).
The files that verify it at commit 26de7be8, each at the first line that names the rule:
Explained in
The sections of the surface document that explain this rule, at commit 26de7be8:
Error codes that enforce it
The diagnostic codes the rule names under Enforced by, or whose registry text names the rule:
-
TS8033MODULE_VAR - A module variable (
let x: workgroup<T>,let y: T = init, §24) declared or used where its address space forbids: aconstwith an address-space wrapper, aworkgroupvariable with an initializer, a type the space cannot hold (a texture, a runtime-sized array, an atomic in a per-invocation variable), an initializer that is not a constant, or aworkgroupvariable reached from a vertex or fragment entry (roadmap 0.2 item 5). -
TS8034BARRIER_PLACEMENT workgroupBarrier()/storageBarrier()somewhere a barrier cannot stand (§25): in a vertex or fragment entry, which has no workgroup; or as a value, since a barrier is a statement (roadmap 0.2 item 5).-
TS8052UNIFORMITY - A call that needs uniform control flow —
textureSampleand the other implicit-LOD forms, the derivatives, a barrier, orworkgroupUniformLoad— reached under a condition that is not uniform across the invocations that run together (anif, aswitch, a loop's condition, the left side of&&or||, the condition of a?:WGSL writes as anif), or after areturn,breakorcontinuetaken under one (§54). -
TS8099UNSUPPORTED UNSUPPORTED(TS8099) is the one deliberate exception to "sequential": it is the catch-all for a diagnostic whose site does not yet deserve its own code, so it stays parked past the sequential range instead of at its head.
See also
Source
The rule at commit 26de7be8:
docs/language-design.md:624(the design document)reqs/rules/RULE-0803.md(its traceability item)