Signatur
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
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}`);
}
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}`);
}
};
// Wichtig · Fallstricke
- Kein Ersatz für Fehlerbehandlung:
createShaderModule()wirft bei fehlerhaftem WGSL keine Ausnahme. OhnegetCompilationInfo()oderdevice.pushErrorScope('validation')tauchen Fehler erst später beim Erstellen der Pipeline auf. - Zeilenangaben:
lineNumundlinePoszählen ab 1. Der Wert0bedeutet, dass es keine Positionsangabe gibt.offsetundlengthzä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
typeund 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.gpuprüfen, ob die API vorhanden ist.