Start · Sprachen · JavaScript · Referenz · GPUShaderModule.getCompilationInfo()

GPUShaderModule.getCompilationInfo()

Methode

Liefert ein Promise mit einem <code>GPUCompilationInfo</code>-Objekt, das alle Fehler, Warnungen und Hinweise aus der Kompilierung des WGSL-Shadermoduls enthält.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPUShaderModule.prototype.getCompilationInfo()

Beschreibung

Mit getCompilationInfo() fragt man ab, was der WGSL-Compiler beim Erzeugen eines GPUShaderModule über GPUDevice.createShaderModule() gemeldet hat. Das Promise wird mit einem GPUCompilationInfo-Objekt erfüllt. Dessen Eigenschaft messages ist ein Array aus GPUCompilationMessage-Objekten.

Jede Nachricht hat einen type ("error", "warning" oder "info"), einen Text in message und Angaben zur Position im Quelltext: lineNum und linePos (beide ab 1 gezählt) sowie offset und length. Die beiden letzten zählen in UTF-16-Codeeinheiten. So lassen sich Fehler direkt im Shader-Code markieren, zum Beispiel in einem Live-Editor oder in den Entwicklerwerkzeugen einer Engine.

createShaderModule() wirft bei Syntaxfehlern keine Ausnahme. Das Modul wird trotzdem angelegt, ist aber ungültig. Erst beim Erstellen der Pipeline fällt der Fehler auf, und dann nur als Validierungsfehler. Deshalb sollte man getCompilationInfo() in der Entwicklung immer direkt nach dem Erzeugen des Moduls aufrufen, damit man verständliche Fehlermeldungen mit Zeilenangabe bekommt.

Rückgabewert

Typ
Promise<GPUCompilationInfo>
Beschreibung
Ein Promise, das mit einem GPUCompilationInfo-Objekt erfüllt wird. Dessen schreibgeschützte Eigenschaft messages ist ein Array von GPUCompilationMessage-Objekten mit den Eigenschaften type, message, lineNum, linePos, offset und length. Ist das Array leer, gab es keine Meldungen.

Beispiele

Kompilierungsfehler eines Shaders ausgeben

const adapter = await navigator.gpu?.requestAdapter();
if (!adapter) throw new Error('WebGPU wird nicht unterstützt');
const device = await adapter.requestDevice();

// Absichtlicher Fehler: Semikolon fehlt
const code = `
@vertex
fn main() -> @builtin(position) vec4f {
  return vec4f(0.0, 0.0, 0.0, 1.0)
}`;

const module = device.createShaderModule({ code });
const info = await module.getCompilationInfo();

for (const msg of info.messages) {
  console.log(`${msg.type} (Zeile ${msg.lineNum}:${msg.linePos}): ${msg.message}`);
}
error (Zeile 5:1): expected ';' for return statement

Hilfsfunktion: Modul erst nach erfolgreicher Prüfung verwenden

const createCheckedModule = async (device, code, label = 'shader') => {
  const module = device.createShaderModule({ code, label });
  const { messages } = await module.getCompilationInfo();

  const errors = messages.filter((m) => m.type === 'error');
  messages
    .filter((m) => m.type === 'warning')
    .forEach((w) => console.warn(`[${label}] ${w.lineNum}:${w.linePos} ${w.message}`));

  if (errors.length > 0) {
    const text = errors
      .map((e) => `${e.lineNum}:${e.linePos} ${e.message}`)
      .join('\n');
    throw new Error(`Shader "${label}" fehlerhaft:\n${text}`);
  }
  return module;
};

// Aufruf
// const module = await createCheckedModule(device, wgslSource, 'dreieck');

Fehlerstelle im Quelltext markieren (Editor-Anzeige)

const highlightErrors = async (module, source) => {
  const { messages } = await module.getCompilationInfo();
  const lines = source.split('\n');

  for (const m of messages) {
    if (m.lineNum === 0) continue; // keine Positionsangabe
    const line = lines[m.lineNum - 1] ?? '';
    const marker = ' '.repeat(m.linePos - 1) + '^'.repeat(Math.max(1, m.length));
    console.log(`${m.type.toUpperCase()}: ${m.message}\n${line}\n${marker}`);
  }
};
ERROR: unresolved identifier 'colr' return colr; ^^^^

// Wichtig · Fallstricke

  • Kein Ersatz für Fehlerbehandlung: createShaderModule() wirft bei fehlerhaftem WGSL keine Ausnahme. Ohne getCompilationInfo() oder device.pushErrorScope('validation') tauchen Fehler erst später beim Erstellen der Pipeline auf.
  • Zeilenangaben: lineNum und linePos zählen ab 1. Der Wert 0 bedeutet, dass es keine Positionsangabe gibt. offset und length zählen in UTF-16-Codeeinheiten und passen damit direkt zu JavaScript-Strings.
  • Nachrichtentexte unterscheiden sich je nach Browser und Compiler (z. B. Tint in Chrome, Naga in Firefox). Man sollte sie nicht maschinell auswerten, sondern nur type und die Positionsfelder verwenden.
  • Performance: Die Methode ist asynchron und kann auf die GPU-Prozess-Kommunikation warten. Im Produktivbetrieb mit bereits geprüften Shadern kann man sie weglassen oder nur im Debug-Modus aufrufen.
  • Kompatibilität: WebGPU gibt es nur in sicheren Kontexten und noch nicht in allen Browsern bzw. auf allen Plattformen. Vorher mit navigator.gpu prüfen, ob die API vorhanden ist.