Signatur
Beschreibung
clearBuffer() fügt dem GPUCommandEncoder einen Befehl hinzu, der einen Bereich eines GPUBuffer mit Null-Bytes überschreibt. Der Befehl läuft nicht sofort: Er wird erst ausgeführt, wenn der mit finish() erzeugte GPUCommandBuffer über device.queue.submit() an die GPU geschickt wird.
Typische Einsatzfälle sind das Zurücksetzen von Zählern, Histogrammen, atomaren Akkumulatoren oder Indirect-Draw-Argumenten vor einem Compute- oder Render-Pass. Gegenüber queue.writeBuffer() mit einem Null-Array spart clearBuffer() den Upload von der CPU: Es wird kein Speicher im Hauptprozess angelegt und nichts übertragen. Der Befehl ordnet sich außerdem sauber in die Befehlsfolge des Encoders ein, lässt sich also zwischen zwei Passes platzieren.
Ohne offset und size wird der ganze Puffer geleert. Mit offset allein wird alles ab dieser Position geleert. Beide Werte müssen Vielfache von 4 sein. Der Puffer muss mit dem Verwendungs-Flag GPUBufferUsage.COPY_DST angelegt worden sein.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $buffer Pflicht | GPUBuffer | Der Puffer, der geleert werden soll. Er muss mit GPUBufferUsage.COPY_DST erstellt worden sein. |
|
| $offset | number | 0 | Startposition in Bytes ab Pufferanfang. Muss ein Vielfaches von 4 sein. |
| $size | number | buffer.size - offset | Anzahl der zu leerenden Bytes. Muss ein Vielfaches von 4 sein, und offset + size darf buffer.size nicht überschreiten. |
Rückgabewert
Beispiele
Ganzen Puffer leeren und das Ergebnis prüfen
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
// Quellpuffer mit Testdaten, muss COPY_DST (für clearBuffer) und COPY_SRC haben
const data = device.createBuffer({
size: 16,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
});
device.queue.writeBuffer(data, 0, new Uint32Array([1, 2, 3, 4]));
// Lesepuffer zum Zurücklesen auf die CPU
const readback = device.createBuffer({
size: 16,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
const encoder = device.createCommandEncoder();
encoder.clearBuffer(data); // kompletter Puffer auf 0
encoder.copyBufferToBuffer(data, 0, readback, 0, 16);
device.queue.submit([encoder.finish()]);
await readback.mapAsync(GPUMapMode.READ);
console.log(new Uint32Array(readback.getMappedRange()));
readback.unmap();
Nur einen Teilbereich leeren
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const buf = device.createBuffer({
size: 16,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
});
device.queue.writeBuffer(buf, 0, new Uint32Array([10, 20, 30, 40]));
const readback = device.createBuffer({
size: 16,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
const encoder = device.createCommandEncoder();
// Bytes 4 bis 11 leeren, also die Elemente 1 und 2
encoder.clearBuffer(buf, 4, 8);
encoder.copyBufferToBuffer(buf, 0, readback, 0, 16);
device.queue.submit([encoder.finish()]);
await readback.mapAsync(GPUMapMode.READ);
console.log(new Uint32Array(readback.getMappedRange()));
readback.unmap();
Atomaren Zähler vor jedem Compute-Pass zurücksetzen
// Setzt voraus: device, pipeline und bindGroup existieren bereits.
// Der Shader zählt mit atomicAdd in counterBuffer.
const counterBuffer = device.createBuffer({
size: 4,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
});
const runFrame = () => {
const encoder = device.createCommandEncoder();
// Muss AUSSERHALB eines Passes stehen
encoder.clearBuffer(counterBuffer);
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(64);
pass.end();
device.queue.submit([encoder.finish()]);
requestAnimationFrame(runFrame);
};
requestAnimationFrame(runFrame);
// Wichtig · Fallstricke
- Ausrichtung:
offsetundsizemüssen Vielfache von 4 sein. Andernfalls entsteht ein Validierungsfehler, und der Encoder wird ungültig. Das zeigt sich erst beim Aufruf vonfinish()bzw.submit()und nicht als JavaScript-Exception. Fehler fangen Sie mitdevice.pushErrorScope('validation')/popErrorScope()oder über das Ereignisuncapturederror. - Verwendungs-Flag: Fehlt
GPUBufferUsage.COPY_DSTbeim Anlegen des Puffers, ist der Aufruf ungültig. - Grenzen:
offset + sizedarfbuffer.sizenicht überschreiten. - Kein aktiver Pass:
clearBuffer()darf nicht zwischenbeginRenderPass()/beginComputePass()undend()stehen, solange ein Pass offen ist. - Der Puffer darf zum Zeitpunkt von
submit()nicht gemappt sein. - Neu erstellte
GPUBuffersind laut Spezifikation schon mit Nullen gefüllt.clearBuffer()brauchen Sie also nur zum erneuten Zurücksetzen. - Kompatibilität: WebGPU ist noch nicht überall verfügbar. Prüfen Sie vorher mit
if (!navigator.gpu)und planen Sie einen Ersatzweg ein. Die API gibt es nur in sicheren Kontexten und unter anderem auch in Web Workern.