Signatur
Beschreibung
Mit pushDebugGroup() öffnen Sie innerhalb eines GPUComputePassEncoder eine Debug-Gruppe mit eigenem Namen. Alle danach kodierten Befehle wie setPipeline(), setBindGroup() oder dispatchWorkgroups() gehören zu dieser Gruppe, bis sie mit popDebugGroup() wieder geschlossen wird.
Debug-Gruppen ändern nichts am Ergebnis der Berechnung. Sie dienen nur der Übersicht: GPU-Debugger und Profiler wie PIX, RenderDoc, der Xcode GPU Frame Debugger oder die WebGPU-Werkzeuge im Browser zeigen die Befehle nach diesen Gruppen gegliedert an. Auch Validierungsfehler können den Gruppennamen enthalten, sodass Sie einen Fehler schneller einem Abschnitt Ihres Codes zuordnen.
Gruppen lassen sich verschachteln. So können Sie etwa eine Gruppe „Physik“ anlegen und darin die Untergruppen „Kollision“ und „Integration“. Jeder Aufruf von pushDebugGroup() braucht ein passendes popDebugGroup(), und zwar im selben Pass-Encoder und vor dem Aufruf von end().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $groupLabel Pflicht | string | Name der Debug-Gruppe, wie er in GPU-Debuggern und Fehlermeldungen erscheint, z. B. "Partikel-Update". |
Rückgabewert
Beispiele
Einfache Debug-Gruppe um einen Dispatch
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const module = device.createShaderModule({
code: `
@group(0) @binding(0) var<storage, read_write> data: array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3u) {
if (id.x < arrayLength(&data)) { data[id.x] *= 2.0; }
}`
});
const pipeline = device.createComputePipeline({
layout: 'auto',
compute: { module, entryPoint: 'main' }
});
const buffer = device.createBuffer({
size: 1024 * 4,
usage: GPUBufferUsage.STORAGE
});
const bindGroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: { buffer } }]
});
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass({ label: 'Verdopplungs-Pass' });
pass.pushDebugGroup('Werte verdoppeln');
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(Math.ceil(1024 / 64));
pass.popDebugGroup();
pass.end();
device.queue.submit([encoder.finish()]);
Verschachtelte Gruppen für mehrere Simulationsschritte
// pipelines und bindGroups wurden vorher angelegt
const encodeSimulation = (device, pipelines, bindGroups, workgroups) => {
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.pushDebugGroup('Physik');
pass.pushDebugGroup('Kollision');
pass.setPipeline(pipelines.collision);
pass.setBindGroup(0, bindGroups.particles);
pass.dispatchWorkgroups(workgroups);
pass.popDebugGroup(); // Ende Kollision
pass.pushDebugGroup('Integration');
pass.setPipeline(pipelines.integrate);
pass.dispatchWorkgroups(workgroups);
pass.popDebugGroup(); // Ende Integration
pass.popDebugGroup(); // Ende Physik
pass.end();
return encoder.finish();
};
device.queue.submit([encodeSimulation(device, pipelines, bindGroups, 256)]);
Validierungsfehler durch fehlendes popDebugGroup() abfangen
device.pushErrorScope('validation');
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.pushDebugGroup('Nicht geschlossen');
pass.end(); // Fehler: Gruppe ist noch offen
const commandBuffer = encoder.finish();
const error = await device.popErrorScope();
if (error) {
console.warn('WebGPU-Validierung:', error.message);
}
// Wichtig · Fallstricke
- Push und Pop müssen zusammenpassen: Ist beim Aufruf von
end()noch eine Gruppe offen, wird der Encoder ungültig. Dann liefertfinish()einen ungültigenGPUCommandBufferundqueue.submit()meldet einen Validierungsfehler. Umgekehrt ist auch einpopDebugGroup()ohne offene Gruppe ein Fehler. - Gilt nur für diesen Pass: Eine Gruppe, die im
GPUComputePassEncodergeöffnet wurde, muss auch dort geschlossen werden. Sie kann nicht über die Grenze zum übergeordnetenGPUCommandEncoderhinweg reichen. - Kein Einfluss auf das Ergebnis: Die Gruppe ändert nichts an der Berechnung. Der Laufzeitaufwand ist gering, aber nicht immer null. In zeitkritischem Produktionscode können Sie die Aufrufe daher bei Bedarf hinter einem Debug-Schalter kapseln.
- Einzelne Punkte ohne eigene Gruppe markieren Sie mit
insertDebugMarker(). - Kompatibilität: WebGPU ist nur in sicheren Kontexten verfügbar und wird noch nicht überall unterstützt. Prüfen Sie vorher mit
if (!navigator.gpu), ob die API vorhanden ist. Ob die Gruppennamen im Debugger erscheinen, hängt vom Browser und vom verwendeten Werkzeug ab.