Signatur
Beschreibung
destroy() beendet ein logisches WebGPU-Gerät endgültig. Alle Ressourcen, die über dieses Gerät erzeugt wurden (Buffer, Texturen, Pipelines, Bind Groups usw.), werden damit ungültig. Laufende Mappings von Buffern werden abgebrochen, sodass ausstehende GPUBuffer.mapAsync()-Promises abgelehnt werden.
Vor dem Zerstören werden alle bereits über device.queue.submit() übermittelten Befehle noch fertig abgearbeitet. Danach wird das Promise GPUDevice.lost mit einem GPUDeviceLostInfo erfüllt, dessen reason den Wert "destroyed" hat. So kannst du einen gewollten Abbau von einem unerwarteten Geräteverlust (z. B. Treiberabsturz) unterscheiden.
Einsetzen solltest du die Methode, wenn eine GPU-Anwendung oder -Komponente nicht mehr gebraucht wird, z. B. beim Unmount einer Komponente in einer Single-Page-Application, beim Schließen eines Editors oder in Tests. So gibst du GPU-Speicher sofort frei, statt auf die Garbage Collection zu warten. Ein zerstörtes Gerät lässt sich nicht reaktivieren; für einen Neustart forderst du mit adapter.requestDevice() ein neues Gerät an.
Rückgabewert
device.lost, das mit reason: "destroyed" erfüllt wird.Beispiele
Gerät anfordern und gezielt zerstören
const init = async () => {
if (!navigator.gpu) throw new Error('WebGPU wird nicht unterstützt');
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
// Auf Geräteverlust reagieren
device.lost.then((info) => {
console.log(`Gerät verloren: ${info.reason}`);
});
// ... Rendering / Compute ...
device.destroy();
};
init();
Gewollten Abbau von unerwartetem Verlust unterscheiden
const createDevice = async () => {
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
device.lost.then(async (info) => {
if (info.reason === 'destroyed') {
console.log('Absichtlich zerstört – kein Neustart.');
return;
}
console.warn('Unerwarteter Verlust:', info.message);
await createDevice(); // neu initialisieren
});
return device;
};
const device = await createDevice();
device.destroy();
Aufräumen beim Entfernen einer Komponente
class GpuView {
async init(canvas) {
const adapter = await navigator.gpu.requestAdapter();
this.device = await adapter.requestDevice();
this.context = canvas.getContext('webgpu');
this.context.configure({
device: this.device,
format: navigator.gpu.getPreferredCanvasFormat(),
});
}
dispose() {
cancelAnimationFrame(this.frameId);
this.context?.unconfigure();
this.device?.destroy(); // GPU-Speicher sofort freigeben
this.device = null;
}
}
const view = new GpuView();
await view.init(document.querySelector('canvas'));
// später, z. B. beim Seitenwechsel:
view.dispose();
Ausstehendes mapAsync wird abgelehnt
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const buffer = device.createBuffer({
size: 16,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});
const pending = buffer.mapAsync(GPUMapMode.READ);
device.destroy();
try {
await pending;
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Nicht umkehrbar: Nach
destroy()ist das Gerät dauerhaft unbrauchbar. Ein erneuter Aufruf ist erlaubt, bewirkt aber nichts. Für einen Neustart brauchst du ein neues Gerät überadapter.requestDevice(). Ein Adapter, der schon ein Gerät geliefert hat, gilt je nach Implementierung als „verbraucht“. Fordere dann auch einen neuen Adapter an. - Keine Ausnahmen: Aufrufe auf einem zerstörten Gerät (z. B.
createBuffer()) werfen meist keinen Fehler, sondern erzeugen ungültige Objekte oder werden stillschweigend ignoriert. Prüfe den Zustand überdevice.lost, nicht übertry/catch. - Übermittelte Arbeit läuft noch fertig: Befehle, die vor
destroy()an die Queue übergeben wurden, werden noch ausgeführt. AusstehendemapAsync()-Promises werden dagegen mit einemAbortErrorabgelehnt. - Einzelne Ressourcen: Wenn du nur einzelne Buffer oder Texturen freigeben willst, nutze
GPUBuffer.destroy()bzw.GPUTexture.destroy(), statt das ganze Gerät zu zerstören. - Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung und wird noch nicht überall unterstützt. Prüfe vorher, ob
navigator.gpuvorhanden ist, und sieh einen Ersatzweg vor (z. B. WebGL).