Unless I'm mistaken, storing the compute shader workgroup size in a const or override variable is the only way to use it inside WGSL without resorting to copy/paste. Getting access to this value in JS is also a precious information to compute the dispatchWorkgroups() size.
example:
override workgroupxy_size = 8;
@group(0) @binding(0) var input_sampler: sampler;
@group(0) @binding(1) var input_texture: texture_2d<f32>;
@group(0) @binding(2) var output_texture: texture_storage_2d<rgba8unorm, write>;
@compute @workgroup_size(workgroupxy_size, workgroupxy_size, 1)
fn resize(@builtin(global_invocation_id) global_id: vec3<u32>) {
let pixel_pos = global_id.xy;
let texture_size = textureDimensions(output_texture);
if all(pixel_pos < texture_size) {
let texel = textureSampleLevel(input_texture, input_sampler, (vec2f(pixel_pos) + vec2f(0.5)) / vec2f(texture_size), 0);
textureStore(output_texture, pixel_pos, texel);
}
}
export async function loadWgsl (device, url, constants = {}) {
const shaderCode = await (await fetch(url)).text()
const defs = makeShaderDataDefinitions(shaderCode)
console.log('DEF', defs)
const module = device.createShaderModule({
label: `${url} module`, code: shaderCode,
})
const pipelineDescs = objMap(defs.entryPoints, (key, _v) => ({
label: `${key} pipeline`,
layout: 'auto',
compute: {module: module, entryPoint: key, constants: constants}
}))
const pipelines = objMap(pipelineDescs, (key, v) => {
return device.createComputePipeline(v)
})
return {pipelines, defs, descriptors: pipelineDescs}
}
export async function run() {
(...)
const wgSizeXY = 8
const {pipelines, defs, descriptors} = await loadWgsl(device, 'resize.wgsl', {workgroupxy_size: wgSizeXY})
const commandEncoder = device.createCommandEncoder()
const computePass = commandEncoder.beginComputePass({label: 'image doubling compute pass'})
await encodePipePrep(device, pipelines['resize'], computePass, {
input_sampler: device.createSampler({magFilter: 'linear', minFilter: 'linear'}),
input_texture: inputTexture.createView(),
output_texture: outputTexture.createView()
}, defs.entryPoints['resize'].resources)
computePass.dispatchWorkgroups(Math.ceil(outputWidth / wgSizeXY), Math.ceil(outputHeight / wgSizeXY))
(...)
}
receiving workgroupxy_size from the wgsl file would allow setting the value in the shader and using it in JS.
Unless I'm mistaken, storing the compute shader workgroup size in a
constoroverridevariable is the only way to use it inside WGSL without resorting to copy/paste. Getting access to this value in JS is also a precious information to compute thedispatchWorkgroups()size.example:
receiving
workgroupxy_sizefrom the wgsl file would allow setting the value in the shader and using it in JS.