An override is a module-scope constant fixed when a pipeline is created. The stage's constants record sets it by name or, with @id(n), by number, and a default makes it optional. One module yields several specialized pipelines, and overrides can even size workgroups:
<script type="module">
const device = await (await navigator.gpu.requestAdapter()).requestDevice();
const module = device.createShaderModule({ code: /* wgsl */ `
override percentOff: f32 = 0; // set per pipeline, by name
@id(7) override size: u32 = 64; // or by numeric id
const prices = array(14.99, 39.50, 24.00, 18.75, 16.20, 21.30);
@group(0) @binding(0) var<storage, read_write> out: array<f32, 6>;
@compute @workgroup_size(size) fn main(@builtin(local_invocation_index) i: u32) {
if (i < 6) { out[i] = round(prices[i] * (100 - percentOff)) / 100; }
}` });
const { STORAGE, COPY_SRC, COPY_DST, MAP_READ } = GPUBufferUsage;
const out = device.createBuffer({ size: 24, usage: STORAGE | COPY_SRC });
async function run(constants) {
device.pushErrorScope('validation');
const pipeline = device.createComputePipeline({ layout: 'auto',
compute: { module, constants } });
const error = await device.popErrorScope(), label = JSON.stringify(constants);
if (error) return console.log(`${label}: ${error.message.split('\n')[0].split('. ')[0]}`);
const read = device.createBuffer({ size: 24, usage: COPY_DST | MAP_READ });
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, 24);
device.queue.submit([encoder.finish()]), await read.mapAsync(GPUMapMode.READ);
const prices = [...new Float32Array(read.getMappedRange())].map((p) => p.toFixed(2));
console.log(`${label}: ${prices}`);
}
await run({});
await run({ percentOff: 15, 7: 8 });
await run({ 7: 512 });
</script>{}: 14.99,39.50,24.00,18.75,16.20,21.30
{"7":8,"percentOff":15}: 12.74,33.58,20.40,15.94,13.77,18.10
{"7":512}: Entry-point uses workgroup_size(512, 1, 1) that exceeds the maximum allowed (256,
256, 64)15% off with 8-wide workgroups gave Shared Book Struct's sale prices. A size of 512 failed only at pipeline creation, against the default limit of 256; { size: 8 } failed too, since an @id override answers only to its number. Use overrides for per-pipeline choices (quality, workgroup size, features) and uniforms for per-frame values.