Skip to content

Instantly share code, notes, and snippets.

@greggman
Last active January 9, 2026 17:55
Show Gist options
  • Select an option

  • Save greggman/98fe5b93196c48d921316036136415c7 to your computer and use it in GitHub Desktop.

Select an option

Save greggman/98fe5b93196c48d921316036136415c7 to your computer and use it in GitHub Desktop.
WebGPU: Bindless dynamic slot manager
/*bug-in-github-api-content-can-not-be-empty*/
/*bug-in-github-api-content-can-not-be-empty*/
// This class manages a range of dynamic slots
class BindlessSlotManager {
#lastSubmitIndex = 0;
#completedSubmitIndex = 0;
#firstSlotNumber = 0;
#availableAfterSubmit: number[];
#device: GPUDevice;
#resourceTable: GPUResourceTable;
constructor(device, resourceTable, firstSlotNumber, numSlots) {
this.#device;
this.#resourceTable;
this.#firstSlotNumber = firstSlotNumber;
this.#availableAfterSubmit = new Array(numSlots);
}
// private
#update(realSlot: number, resource: GPUBindingResource) {
this.#availableAfterSubmit[realSlot - this.#firstSlotNumber] = Number.POSITIVE_INFINITY;
this.#resourceTable.updateBinding(realSlot, resource);
}
insertBinding(resource: GPUBindingResource) {
const slot = this.#availableAfterSubmit.findIndex(e => e < #this.completedSubmitIndex);
if (slot < 0) {
return undefined; // or throw
}
this.#update(slot, resource);
return slot + this.#firstSlotNumber;
}
removeBinding(slot: number) {
this.#availableAfterSubmit[slot - this.#firstSlotNumber] = this.#lastSubmitIndex;
this.#resouceTable.removeBinding(slot);
}
// call this immediately after device.queue.submit
submit() {
++this.#lastSubmitIndex;
const submitIndex = this.#lastSubmitIndex;
this.#device.queue.onSubmittedWorkDone().then(() => {
this.#completedSubmitIndex = submitIndex;
});
}
}
{"name":"WebGPU: Bindless dynamic slot manager","settings":{},"filenames":["index.html","index.css","index.js"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment