Skip to main content

STENCIL_EVAL_WGSL

Constant STENCIL_EVAL_WGSL 

Source
pub const STENCIL_EVAL_WGSL: &str = "// Uniform stencil evaluation compute kernel.\n//\n// Ported from opensubdiv-petite\'s `shaders/wgsl/stencil_eval.wgsl` (which itself\n// mirrors OpenSubdiv\'s `glslComputeKernel.glsl`), specialised to subdiv-kernels\'\n// CSR `StencilTable`: row `i`\'s entries span `offsets[i]..offsets[i+1]`, so the\n// per-row size is derived from the offsets and no separate `sizes` buffer is\n// needed. Positions/primvars only -- the limit-derivative (b1) path is separate.\n\noverride WORKGROUP_SIZE: u32 = 64u;\n\nstruct Params {\n    // All offsets/strides are in floats.\n    src_offset: u32,\n    dst_offset: u32,\n    src_stride: u32,\n    dst_stride: u32,\n    length: u32,       // components per element (e.g. 3 for xyz)\n    batch_start: u32,  // first output row (inclusive)\n    batch_end: u32,    // last output row (exclusive)\n}\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> src_buffer: array<f32>;\n@group(0) @binding(2) var<storage, read_write> dst_buffer: array<f32>;\n// CSR row offsets, length = output_count + 1.\n@group(0) @binding(3) var<storage, read> stencil_offsets: array<u32>;\n@group(0) @binding(4) var<storage, read> stencil_indices: array<u32>;\n@group(0) @binding(5) var<storage, read> stencil_weights: array<f32>;\n// Indirection: output-row indices for the sparse (indexed) entry point.\n@group(0) @binding(6) var<storage, read> stencil_indirection: array<u32>;\n\n// Cap per-element component count (matches the host MAX_COMPONENTS).\nconst MAX_LENGTH: u32 = 32u;\n\n// Evaluate output row `current` into dst_buffer.\nfn eval_row(current: u32) {\n    let row_start = stencil_offsets[current];\n    let row_end = stencil_offsets[current + 1u];\n    let dst_base = params.dst_offset + current * params.dst_stride;\n\n    for (var c: u32 = 0u; c < params.length && c < MAX_LENGTH; c = c + 1u) {\n        var sum: f32 = 0.0;\n        for (var si: u32 = row_start; si < row_end; si = si + 1u) {\n            let vi = params.src_offset + stencil_indices[si] * params.src_stride + c;\n            sum = sum + stencil_weights[si] * src_buffer[vi];\n        }\n        dst_buffer[dst_base + c] = sum;\n    }\n}\n\n// Dense: invocation gid.x handles output row gid.x + batch_start, in\n// [batch_start, batch_end).\n@compute @workgroup_size(WORKGROUP_SIZE)\nfn eval_stencils(@builtin(global_invocation_id) gid: vec3<u32>) {\n    let current = gid.x + params.batch_start;\n    if (current >= params.batch_end) {\n        return;\n    }\n    eval_row(current);\n}\n\n// Sparse: invocation gid.x handles the output row named by the indirection\n// buffer; `batch_end` is the number of indirection entries.\n@compute @workgroup_size(WORKGROUP_SIZE)\nfn eval_stencils_indexed(@builtin(global_invocation_id) gid: vec3<u32>) {\n    if (gid.x >= params.batch_end) {\n        return;\n    }\n    eval_row(stencil_indirection[gid.x]);\n}\n";
Available on crate feature wgpu only.
Expand description

Canonical WGSL source for the stencil-eval compute kernel.