GPUTableShaderBindings
GPUTableShaderBindings owns backend-specific resources prepared by resolving one
GPUTable against a fixed GPUInputSchema and ShaderLayout. It preserves table
batches and returns ordinary resources suitable for Model.setAttributes() and
Model.setBindings().
Use GPUTableModel for automatic integration. Use this class directly when an
application owns its model or render-pipeline lifecycle.
Usage
const prepared = new GPUTableShaderBindings(device, {
table,
gpuInputSchema: PointModel.gpuInputSchema,
shaderLayout
});
const model = new Model(device, {
source,
modules: prepared.shaderModule ? [prepared.shaderModule] : [],
shaderLayout,
bufferLayout: prepared.bufferLayout,
attributes: prepared.batches[0]?.attributes,
bindings: prepared.batches[0]?.bindings
});
for (const batch of prepared.batches) {
model.setAttributes(batch.attributes);
model.setBindings(batch.bindings);
model.setConstantAttributes(prepared.constantAttributes);
model.draw(renderPass);
}
model.destroy();
prepared.destroy();
Constructor
new GPUTableShaderBindings(device, {
table,
gpuInputSchema,
shaderLayout
});
The schema and shader layout define the pipeline contract and remain fixed for the
object lifetime. Use updateBindings() to replace only the table.
Properties
| Property | Type | Meaning |
|---|---|---|
device | Device | Device used for backend preparation. |
table | GPUTable | Currently prepared table. |
gpuInputSchema | GPUInputSchema | Fixed logical input contract. |
shaderLayout | ShaderLayout | Fixed shader attribute and binding contract. |
bufferLayout | BufferLayout[] | Final backend-ready attribute layouts. |
batches | GPUTableShaderBindingBatch[] | Draw-ready resources per preserved batch. |
constantAttributes | Record<string, TypedArray> | WebGL context constant values. |
shaderModule | ShaderModule | undefined | Generated WebGPU storage row-index module. |
ownedByteLength | number | Current byte length of resources owned by this object. |
type GPUTableShaderBindingBatch = {
attributes: Record<string, Buffer | DynamicBuffer>;
attributeBuffers: Array<Buffer | DynamicBuffer>;
bindings: Record<string, Binding>;
};
attributeBuffers follows bufferLayout order. attributes exposes the same
resources by logical layout name.
updateBindings(table)
Validates and prepares a replacement table using the existing schema and shader layout. Compatible owned buffers are reused and rewritten. Obsolete owned resources are destroyed after the next state has been prepared.
The replacement table may change row count, batch count, or whether an optional
input is varying or constant. A resulting attribute-layout change requires the model
to apply the new bufferLayout; GPUTableModel does this automatically.
destroy()
Destroys zero-stride vertex buffers, one-row storage buffers, and the generated row
multiplier uniform. It does not destroy the caller-owned table or its GPUData.
Repeated calls are safe. Updating a destroyed object throws.
Attribute Resolution
For varying inputs, columnName selects the table layout and attributeName selects
the shader attribute. Interleaved layouts retain only attributes selected as varying.
For WebGPU constants, compatible values with the same step mode are packed into a
single buffer layout with byteStride: 0. Every draw therefore reads the same payload
for every vertex or instance.
For WebGL constants, no vertex buffer is allocated. Raw memory values are converted
to the float or integer values visible to the shader, including normalized integer,
half-float, packed unorm10-10-10-2, and BGRA formats.
Storage Resolution
Varying columns produce batch-local Binding ranges that preserve GPUData.byteOffset
and uploaded byte size. Constants produce aligned one-row storage buffers.
When storage declarations are present, shaderModule contributes:
@group(0) @binding(auto)
var<uniform> gpuTableColumns : GPUTableColumnUniforms;
fn gpuTable_getRowIndex(rowIndex : u32, rowMultiplier : u32) -> u32 {
return rowIndex * rowMultiplier;
}
Each storage binding receives a generated field named
<storageBindingName>RowMultiplier:
let color = pointColors[
gpuTable_getRowIndex(
instanceIndex,
gpuTableColumns.pointColorsRowMultiplier
)
];
The multiplier is 1 for varying columns and 0 for constants. The uniform binding
is added to every prepared batch as gpuTableColumns.
GPUTableModel Integration
const model = new GPUTableModel(device, {
source,
shaderLayout,
gpuInputSchema: PointModel.gpuInputSchema,
table,
tableCount: 'instance'
});
model.drawBatches(renderPass);
model.setProps({table: replacementTable});
model.destroy();
The model owns its GPUTableShaderBindings but does not own the table.
Remarks
- Pipeline compatibility:
GPUInputSchemaandShaderLayoutcannot change throughupdateBindings(). Construct a new object for a new pipeline contract. - Schema validation: required inputs must exist as varying vectors. Optional fixed-width inputs may be vectors or constants if their format is listed.
- Dynamic buffers: prepared attributes retain
DynamicBufferwrappers; storage ranges resolve their current concrete buffers when prepared. - Batch preservation: the class never packs table batches.
batches[n]corresponds totable.batches[n]. - Interleaving: a constant override is removed from its varying interleaved layout. Empty layouts are omitted from the pipeline.
- Allocation reuse: update reuses an owned buffer only when purpose, usage, and byte length remain compatible.
- Alignment:
ownedByteLengthreports actual allocated bytes, which may exceedGPUConstant.byteLength. - Failure behavior: validation runs before table state is replaced. A failed update leaves the previously published binding state active.
- Optional absence: this class omits absent optional table resources. A shader that statically requires such a binding still needs a model-specific dummy or fallback.
- Ownership: caller-owned
GPUData,GPUVector,GPUTable, and explicit model bindings are never destroyed by this object.