Skip to content

expose override and const variables and their default value in makeShaderDataDefinitions() ? #17

@nraynaud

Description

@nraynaud

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions