The scalars are bool, i32, u32, f32 and f16 (which needs the shader-f16 feature and enable f16;). Vectors are vec2<T> to vec4<T>, aliased vec3f, vec4i, vec2u, vec3h. Matrices are floating point only: mat3x2f has 3 columns of 2 rows, stored column-major as in GLSL, so m[1] is the second column.
The chapter's WGSL lab page compiles a text/wgsl script, prints the first line of each compilation message and, if there is no error, runs main once and prints the array out, sized and typed by the first-line comment:
<script type="text/wgsl" id="wgsl">
// out: 6 x f32
enable f16;
@group(0) @binding(0) var<storage, read_write> out: array<f32>;
@compute @workgroup_size(1) fn main() {
out[0] = f32(1.0h / 3.0h); // f16: 11 significant bits
out[1] = 0.1 + 0.2; // f32: 24 significant bits
let m = mat3x3f(vec3f(1, 0, 0), vec3f(0, 2, 0), vec3f(0, 0, 3)); // three columns
let r = m * vec3f(1, 2, 3); // matrix times column vector
out[2] = r.x; out[3] = r.y; out[4] = r.z;
out[5] = f32(-7 / 2); // integer division truncates
}
</script>
<script type="module">
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice({ // f16 when the GPU has it (Section 4.6.1)
requiredFeatures: adapter.features.has('shader-f16') ? ['shader-f16'] : [] });
const code = wgsl.textContent.replace(/^\n/, ''); // line 1 = the comment
const [, count, type] = code.match(/out: (\d+) x (\w+)/);
const module = device.createShaderModule({ code });
const { messages } = await module.getCompilationInfo();
for (const m of messages) { // first line of each message
console.log(`${m.lineNum}:${m.linePos} ${m.type}: ${m.message.split('\n')[0]}`);
}
if (count > 0 && !messages.some((m) => m.type === 'error')) {
const size = 4 * count, { STORAGE, COPY_SRC, COPY_DST, MAP_READ } = GPUBufferUsage;
const out = device.createBuffer({ size, usage: STORAGE | COPY_SRC });
const read = device.createBuffer({ size, usage: COPY_DST | MAP_READ });
const pipeline = device.createComputePipeline({ layout: 'auto', compute: { module } });
const encoder = device.createCommandEncoder(), pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, device.createBindGroup({ layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: { buffer: out } }] }));
pass.dispatchWorkgroups(1);
pass.end();
encoder.copyBufferToBuffer(out, 0, read, 0, size);
device.queue.submit([encoder.finish()]), await read.mapAsync(GPUMapMode.READ);
const View = { f32: Float32Array, u32: Uint32Array, i32: Int32Array }[type];
console.log(`out: ${new View(read.getMappedRange()).join(', ')}`);
}
window.__done = true;
</script>out: 0.333251953125, 0.30000001192092896, 1, 4, 9, -3
f16 stores a third as 0.333251953125, about three decimal digits: fine for colors and normals, not for prices. The remaining WGSL listings in WGSL Types and Functions and Entry Points ran in this lab, and their outputs are the lab's.