Start · Sprachen · JavaScript · Referenz · GPUComputePassEncoder.pushDebugGroup()

GPUComputePassEncoder.pushDebugGroup()

Methode

Öffnet in einem Compute-Pass eine benannte Debug-Gruppe, die alle folgenden Befehle bis zum passenden <code>popDebugGroup()</code> umschließt.

seit JavaScript WebGPU – Chrome/Edge 113+, Firefox 141+ (Windows), Kategorie: webapi

Signatur

GPUComputePassEncoder.prototype.pushDebugGroup(groupLabel)

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

Typ
undefined
Beschreibung
Die Methode gibt keinen Wert zurück.

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);
}
WebGPU-Validierung: (Meldung je nach Browser, z. B. "Debug group stack is not empty" …)

// Wichtig · Fallstricke

  • Push und Pop müssen zusammenpassen: Ist beim Aufruf von end() noch eine Gruppe offen, wird der Encoder ungültig. Dann liefert finish() einen ungültigen GPUCommandBuffer und queue.submit() meldet einen Validierungsfehler. Umgekehrt ist auch ein popDebugGroup() ohne offene Gruppe ein Fehler.
  • Gilt nur für diesen Pass: Eine Gruppe, die im GPUComputePassEncoder geöffnet wurde, muss auch dort geschlossen werden. Sie kann nicht über die Grenze zum übergeordneten GPUCommandEncoder hinweg 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.