Kernel and RenderKernel
Overview
Kernel and RenderKernel are lightweight WebGPU execution objects for already assembled WGSL.
They own compiled shaders and cached pipelines while leaving shader assembly, uniform policy,
geometry ownership, scene state, and command-graph scheduling to higher-level APIs.
Motivation
Computation and Model provide valuable engine conveniences, but many low-level GPU algorithms do
not need those conveniences. A graph primitive that already owns its WGSL source generally needs
only to compile a pipeline, bind resources, and dispatch or draw.
Using Computation for that job couples low-level GPU algorithms to shadertools modules,
ShaderInputs, UniformStore, mutable binding state, and other engine policy. The kernel classes
separate the minimal execution mechanism from those higher-level concerns.
This separation is useful both for command-graph internals and for applications that want a thin
WebGPU execution helper without adopting Model or Computation.
Kernel
Kernel wraps one immutable WebGPU compute program:
const kernel = new Kernel(device, {
source,
shaderLayout
});
kernel.dispatch(computePass, {
bindings: {input, output},
x: workgroupCount
});
Bindings are supplied per dispatch rather than retained as mutable kernel state. Direct and indirect dispatch are supported.
GPU core integration
GPU core primitives execute their generated WGSL through Kernel. Each graph node resolves its
current physical resources during encoding and supplies the complete bindings to dispatch() or
dispatchIndirect(). Reusing a compiled graph with different imported buffers does not retain the
previous encoding's bindings. Shader and pipeline factories retain shared compiled resources until
the last kernel releases them. GPUCommandGraph.compileAsync() also prepares kernel pipelines
asynchronously.
The kernel migration preserves operation semantics, chunk topology, dispatch dimensions, and
resource ownership. Device-owned FFT and solver APIs still need the separate graph/program
lifecycle migration; using Kernel does not change their public storage contracts. Kernel itself
still uses luma core resource objects.
RenderKernel
RenderKernel is the render-side counterpart. It owns vertex/fragment shaders and a render pipeline,
while bindings and vertex arrays are supplied per draw:
const kernel = new RenderKernel(device, {
vertexSource,
fragmentSource,
shaderLayout,
bufferLayout
});
kernel.draw(renderPass, {
bindings,
vertexArray,
vertexCount
});
It also supports non-indexed and indexed indirect draws.
What kernels do not do
The kernel layer deliberately does not own:
- shadertools module/plugin assembly
ShaderInputsor uniform stores- geometry or application data
- animation or scenegraph state
- command graphs or scheduling
- draw/dispatch policy beyond recording the requested command
Higher-level APIs remain free to compose these facilities around kernels.
Relationship to Model and Computation
The intended layering is:
shader assembly / uniforms / model policy
↓
Computation / Model
↓
minimal kernel execution
↓
WebGPU
The initial implementation lives in @luma.gl/engine while this boundary is validated. A later
refactor can decide whether the minimal kernel layer belongs in a lower-level package without
changing its responsibilities.