Rule 8.24
Chapter 8, Functions and entry points Test
An exported @compute entry is called from host code as entry(bindings, workgroups).
bindings has one property for each binding the entry reaches through its calls, and no other, each the binding’s host value (Rule 8.21); workgroups is the workgroup count, n or [x, y?, z?], dispatched as written with no bound added; the call returns a promise, and when it resolves every storage binding the entry wrote has been read back into the caller’s value in place, or stays on the device in the Resident passed for it (Rule 11.8).
It runs on WebGPU where there is a device, the device of the runtime configure({ runtime }) names or else the one the call layer requests and the default program runtime shares (Rule 11.11), and otherwise on the CPU tier (Rule 11.7), in the order configure sets (Rule 11.8), every invocation of every workgroup in turn, z, then y, then x, with the workgroup memory zeroed for each workgroup; an entry that reaches a barrier needs WebGPU, and where there is none the call is refused with a TypeError naming the barrier and its line.
In vite dev, and in a production build whose plugin says console: 'always', an entry’s WGSL records its console.* calls (Rule 11.9), and the runtime prints the decoded events to the host’s console after the dispatch or the draw, in the CPU tier’s order; console: 'never' records in neither, and the default, 'dev', records in vite dev alone. Each printed line, from the GPU or the CPU tier, starts with its tier, the call’s file and line, and the invocation when the event has one, in the format string, with the event’s arguments after it and its method kept.
An exported @fragment entry that reads no builtin but position and front_facing and writes one @location(0) vec4 (its result, or a struct of that one field) is drawn as entry(target, bindings): one frame, with a full-screen triangle, into target, an HTMLCanvasElement or an OffscreenCanvas, filling its width by height; the draw returns a promise that resolves when the frame is submitted, and reads nothing back.
It draws on WebGPU, then WebGL2 (the entry’s GLSL ES 3.00 fragment program, its rows copied so the first is the canvas’s top, as WGSL’s position counts them), then the CPU tier, pixel by pixel; the first draw into a canvas decides its tier, since a canvas keeps the first kind of context it hands out, and every later draw into it uses that tier; the frame is opaque on every tier.
An entry the CPU tier cannot run (one that reaches a texture, or a call only a GPU computes) needs a GPU tier, and where it has none the call or the draw is refused with a TypeError naming why.
An entry that reaches a binding with no host value (a storage texture, a depth texture, a texture of another dimension, an emulated f64), a fragment entry that reads what a vertex entry writes, and a vertex entry stay never in the host view, naming the work that adds it.
The rule text and the parts under it are the compiler's own English, as the design document writes them.
Rationale
an entry is the escape hatch below the loop that becomes a kernel (change 0013), and it runs as its author wrote it: WGSL’s unit, the author’s own bound check, no guard added.
The call replaces what a host otherwise writes by hand around compile() and reflect(): the device, the module, the layouts, the packing, the dispatch and the readback.
The workgroup memory and the order of invocations on the CPU tier are those of the interpreter’s own dispatch, so the two agree; a barrier needs the interpreter’s generators to run in lockstep, which the runtime does not ship.
A fragment entry that reads only its pixel’s position needs no vertex data, so one triangle the runtime supplies draws it on every tier; one that reads interstage values needs a mesh, a vertex count and a topology, which is #204’s rendering design.
GLSL’s gl_FragCoord counts rows from the bottom and WGSL’s position from the top, so the WebGL2 tier draws into a framebuffer and copies it upside down, and one program gives one picture on both.
Derives from
change 0016 in changes/ (roadmap item 16, second half); Rule 8.21; docs/dx.md principle 6.
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:
callCompute in src/core/host-compute.ts, over the dispatch in src/core/host-entry.ts, and callDraw in src/core/host-draw.ts, what the generated module calls, and computeFace and fragmentFace in src/compiler/ts/host-face.ts, which write the entry’s layouts, its GLSL program and its view type; the printed line by consoleCalls in src/core/console-print.ts, and the console option by typeshade in src/vite.ts, pinned by src/core/console-print.test.ts and src/vite.test.ts; pinned by src/compiler/ts/host-entry.test.ts, which holds the CPU tier equal to the interpreter’s dispatch and checks each refusal’s text, by src/compiler/ts/host-draw.test.ts, which holds a CPU-tier frame to the reference and checks which fragment entries draw on which tier, by the import journey in scripts/user-journey.ts, which calls two entries on WebGPU and draws two on WebGPU, WebGL2 and the CPU in Chromium from the packed tarball, each frame against the reference, and by the compile gate’s entry-call leg (scripts/entry-calls.ts), which calls every callable entry of the .shade.ts examples through its generated host module, a compute entry on WebGPU and the CPU tier and a draw on WebGPU, WebGL2 and the CPU tier, each tier against WebGPU.
The files that verify it at commit 26de7be8, each at the first line that names the rule:
-
scripts/entry-calls.ts:1 -
scripts/user-journey.ts:259 -
src/compiler/ts/host-draw.test.ts:1 -
src/compiler/ts/host-entry.test.ts:1 -
src/compiler/ts/host-face.ts:111 -
src/core/console-print.test.ts:4 -
src/core/console-print.ts:1 -
src/core/host-compute.ts:36 -
src/core/host-draw.ts:1 -
src/core/host-entry.ts:1 -
src/vite.test.ts:3 -
src/vite.ts:13
See also
Source
The rule at commit 26de7be8:
docs/language-design.md:886(the design document)reqs/rules/RULE-0824.md(its traceability item)