Signatur
Beschreibung
Mit destroy() gibt man ein GPUQuerySet ausdrücklich frei. Ein Query-Set enthält eine feste Anzahl von Abfrageslots vom Typ "occlusion" oder "timestamp". Damit misst man zum Beispiel, ob Fragmente einen Tiefentest bestanden haben, oder wie lange ein Render- bzw. Compute-Durchlauf auf der GPU gedauert hat.
Ohne Aufruf bleibt der GPU-Speicher belegt, bis der Garbage Collector das JavaScript-Objekt einsammelt – und wann das passiert, lässt sich nicht vorhersagen. Wenn eine Anwendung Query-Sets oft neu anlegt, etwa nach einer Größenänderung, beim Umschalten von Profiling-Modi oder beim Abbau einer Szene, sollte sie nicht mehr benötigte Sets mit destroy() sofort freigeben.
Nach dem Aufruf ist das Query-Set ungültig. Jede weitere Verwendung, etwa in beginRenderPass() (occlusionQuerySet, timestampWrites) oder in GPUCommandEncoder.resolveQuerySet(), führt beim Abschicken (queue.submit()) zu einem Validierungsfehler. Befehle, die schon vorher abgeschickt wurden, laufen dagegen noch sauber zu Ende: Die Implementierung gibt die Ressource erst frei, wenn keine laufende Arbeit sie mehr braucht.
Rückgabewert
undefined).Beispiele
Query-Set anlegen und wieder freigeben
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const querySet = device.createQuerySet({
type: 'occlusion',
count: 32,
label: 'Occlusion-Queries'
});
console.log(querySet.type, querySet.count);
// Nicht mehr benötigt – GPU-Speicher sofort freigeben
querySet.destroy();
console.log('Query-Set zerstört');
Timestamp-Profiling ein- und ausschalten
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice({
requiredFeatures: adapter.features.has('timestamp-query') ? ['timestamp-query'] : []
});
let timestampSet = null;
const enableProfiling = () => {
if (!device.features.has('timestamp-query') || timestampSet) return;
timestampSet = device.createQuerySet({ type: 'timestamp', count: 2 });
};
const disableProfiling = () => {
timestampSet?.destroy();
timestampSet = null;
};
enableProfiling();
console.log('Profiling aktiv:', timestampSet !== null);
disableProfiling();
console.log('Profiling aktiv:', timestampSet !== null);
Validierungsfehler nach destroy() abfangen
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const querySet = device.createQuerySet({ type: 'occlusion', count: 1 });
const resolveBuffer = device.createBuffer({
size: 8,
usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
});
querySet.destroy();
device.pushErrorScope('validation');
const encoder = device.createCommandEncoder();
encoder.resolveQuerySet(querySet, 0, 1, resolveBuffer, 0);
device.queue.submit([encoder.finish()]);
const error = await device.popErrorScope();
console.log(error ? 'Validierungsfehler: Query-Set ist zerstört' : 'kein Fehler');
// Wichtig · Fallstricke
- Kein Rückgängigmachen: Ein zerstörtes Query-Set lässt sich nicht wiederherstellen. Wenn du es wieder brauchst, lege mit
device.createQuerySet()ein neues an. - Fehler erst beim Abschicken: Wird ein zerstörtes Set weiter benutzt, wirft das keine JavaScript-Ausnahme. Stattdessen entsteht beim
queue.submit()ein WebGPU-Validierungsfehler. Den fängst du mitpushErrorScope()/popErrorScope()oder über das Ereignisuncapturederrorab. - Laufende Arbeit ist sicher: Vorher abgeschickte Befehle, die das Set nutzen, werden noch korrekt ausgeführt. Du musst also nicht auf
onSubmittedWorkDone()warten. - Mehrfacher Aufruf: Ein zweites
destroy()auf dasselbe Set ist erlaubt und bewirkt nichts. - Timestamp-Queries: Für den Typ
"timestamp"muss beim Anfordern des Geräts das Feature"timestamp-query"aktiviert werden. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten (HTTPS). Die Browser-Unterstützung ist noch lückenhaft. Prüfe daher vorher, ob
navigator.gpuvorhanden ist, und sieh einen Ersatzweg vor, z. B. WebGL.