Slang reflection helpers
Status: Exploration
ExperimentalSince v10
Start with the Slang overview to compile source and run the live example.
Application-owned integration
Import these helpers from @luma.gl/slang/luma. This separate entry point consumes existing
compiler reflection; it does not parse generated WGSL, import luma at runtime, or add any
package dependencies. The compiler entry point does not import these helpers.
getSlangShaderLayout(compiled, options?)returns a structurally compatible lumaShaderLayout: vertex attributes, active resource bindings, stage visibility, uniform buffer sizes, storage access, texture dimensions/sample types/formats, and comparison sampler types.getSlangBindingNames(compiled)maps active source resource names to generated binding names, including GLSL block names and combined texture/sampler uniforms.getSlangUniformBufferLayouts(compiled)returns each active source uniform buffer's generatedname,byteLength, and packinglayout. Use the existingpackSlangUniformsto upload values.getSlangShaderRequirements(compiled)reports compute/storage buffer usage, the actual GLSL version, declared storage texture formats/access, required WGSL language features, and optional WebGPU device features.unsupportedStorageTextureslists active bindings with unsupported WebGPU storage access.
compiled may be a transpileSlang result, a unified transpileSlangWGSL result, or an array
of separately compiled render stages using the same target/version and compatible resource slots.
For pipeline layouts, select one entry point per stage and compile compute separately from render.
Shared bindings combine visibility without modifying source reflection. Reflection visibility is
1 for vertex, 2 for fragment, 4 for compute, or 0 when unused by that entry point.
Usage includes resolved reachable helper overloads and respects local variable shadowing; it does
not perform constant-condition elimination.
The example assumes an existing WebGPU device, a compute source declaring a
ConstantBuffer<Settings> settings, and values matching that buffer. Bind any remaining
resources before dispatch.
import {Buffer} from '@luma.gl/core';
import {transpileSlang, packSlangUniforms} from '@luma.gl/slang';
import {
getSlangShaderLayout,
getSlangBindingNames,
getSlangUniformBufferLayouts,
getSlangShaderRequirements
} from '@luma.gl/slang/luma';
const compiled = transpileSlang(source, {target: 'wgsl', stage: 'compute'});
const requirements = getSlangShaderRequirements(compiled);
// Check requirements.deviceFeatures before device creation and request them explicitly.
// Check requirements.wgslLanguageFeatures against navigator.gpu.wgslLanguageFeatures.
// Reject requirements.unsupportedStorageTextures when nonempty.
// Check storage texture format/access support on the destination device.
const uniform = getSlangUniformBufferLayouts(compiled).settings;
const uniformBuffer = device.createBuffer({
byteLength: uniform.byteLength,
usage: Buffer.UNIFORM | Buffer.COPY_DST
});
uniformBuffer.write(packSlangUniforms(uniform.layout, values));
const shader = device.createShader({stage: compiled.stage, source: compiled.code});
const pipeline = device.createComputePipeline({
shader,
entryPoint: compiled.entryPoint,
shaderLayout: getSlangShaderLayout(compiled)
});
pipeline.setBindings({[getSlangBindingNames(compiled).settings]: uniformBuffer});
Applications still import/register their compiler and own resources, sampler state, feature
requests, and device-limit checks. Requirements are compiler-known facts, not a full device
compatibility validator. WGSL storage declarations need their language features even when unused
by a selected entry point. Active read/write rgba8unorm, rgba16float, and rgba32*
storage bindings require texture-formats-tier2; r32* read/write storage is available in core
WebGPU. Read/write rgba8snorm storage is unsupported on WebGPU and is reported separately.
These distinctions follow the WebGPU format capabilities.
Concrete sampled texture formats are not knowable from source types:
use textureSampleTypes: {sourceName: 'unfilterable-float'} and
samplerTypes: {sourceName: 'non-filtering'} when appropriate. Comparison samplers stay comparison.
GLSL ES 300 remains the WebGL target, and binding groups must be zero for the layout helper.
Plain GLSL uniform globals remain application-managed with setUniforms and are omitted from
uniform-buffer layouts. Pass the returned layout explicitly to a native pipeline, Model, or
Computation; registering a transpiler alone does not install the helpers in the framework.
The sculpture adapter shows how an application collects reflection while assembling a render program. The particle example uses the helpers for compute and rendering.