Skip to main content

DynamicBuffer

From v10

DynamicBuffer is the engine-level wrapper for applications that need a stable buffer object whose underlying GPU Buffer can grow or be replaced. It is useful for streaming geometry, dynamic index data, uniform data, and any workflow where the required byte length is not known up front.

Model and Material accept DynamicBuffer bindings directly and resolve them to the current backing buffer during draw preparation.

DynamicBuffer infographic showing a stable DynamicBuffer handle, replaceable backing Buffer, resize and write flow, and Model and Material integration

Usage​

import {Buffer} from '@luma.gl/core';
import {DynamicBuffer, Model} from '@luma.gl/engine';

const positions = new DynamicBuffer(device, {
data: new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]),
usage: Buffer.VERTEX | Buffer.COPY_DST | Buffer.COPY_SRC
});

const model = new Model(device, {
vs,
fs,
attributes: {positions},
bufferLayout: [{name: 'positions', format: 'float32x3'}]
});

positions.ensureSize(1024, {preserveData: true});
positions.write(new Float32Array([0, 0, 0]), 0);

Types​

DynamicBufferProps​

export type DynamicBufferProps = Omit<BufferProps, 'handle' | 'onMapped'> & {
debugData?: boolean | {maxByteLength?: number};
};

DynamicBufferProps mirrors normal BufferProps except that it owns buffer creation and does not accept an external handle or mapped callback.

DynamicBufferRange​

export type DynamicBufferRange = {
buffer: Buffer | DynamicBuffer;
offset?: number;
size?: number;
};

Use a range when a shader binding should point at only part of the current backing buffer.

Properties​

device, id​

Owning device and application-provided identifier.

buffer: Buffer​

Current immutable core buffer. This object changes after a successful resize().

byteLength: number​

Current backing buffer byte length.

ready: Promise<Buffer>, isReady: boolean​

Compatibility properties for engine code that handles dynamic resources. DynamicBuffer is ready synchronously after construction.

generation: number​

Increments whenever resize() replaces the backing buffer. Engine binding caches use this value to detect when they must rebind.

updateTimestamp: number​

Tracks writes, resize operations, and debug-data-producing readbacks.

debugData: ArrayBuffer​

Optional CPU-side mirror of recent writes and readbacks. Enable it with debugData: true or debugData: {maxByteLength}.

destroyed: boolean​

Indicates whether the dynamic buffer has been destroyed.

Methods​

constructor(device: Device, props: DynamicBufferProps)​

Creates the initial backing buffer.

write(data, byteOffset = 0): void​

Writes data into the current backing buffer.

mapAndWriteAsync(callback, byteOffset?, byteLength?): Promise<void>​

Maps a range for writing through the backing buffer API.

readAsync(byteOffset?, byteLength?): Promise<Uint8Array>​

Reads bytes from the backing buffer.

mapAndReadAsync(callback, byteOffset?, byteLength?): Promise<T>​

Maps a range for reading through the backing buffer API.

resize(options): boolean​

Replaces the backing buffer with options.byteLength. Pass preserveData: true to copy bytes from the previous buffer into the new buffer. Returns false when the byte length is unchanged.

ensureSize(byteLength, options?): boolean​

Grows the backing buffer only when byteLength is larger than the current size.

getBinding(range?): Binding​

Returns the current backing buffer, or a core buffer range binding when offset or size is supplied.

destroy(): void​

Destroys the current backing buffer and clears debug data.

Remarks​

  • DynamicBuffer is directly supported by Model attributes, index buffers, and bindings.
  • DynamicBuffer is directly supported by material-owned bindings created with MaterialFactory.
  • Resizing replaces the underlying Buffer; keep the DynamicBuffer object as the long-lived application handle.
  • Data preservation during resize requires copy support and is not available on NullDevice.