compileModule method

  1. @override
Object compileModule(
  1. String name,
  2. String wgsl
)
override

Turns wgsl into a GPUShaderModule, and asks the browser what it thought of it.

Nothing is thrown for text that does not compile, and nothing can be. A module is created whether or not the code was valid, the same way a pipeline is created whether or not the descriptor was — and a bad shader is not an error scope's business at all: createShaderModule succeeds, and the complaint arrives at the first pipeline built from it as [Invalid ShaderModule "X"] is invalid due to a previous error, naming neither the line nor what was wrong with it. getCompilationInfo has the line and the column and is a promise, so the verdict cannot reach a caller standing here. It is thrown at the next beginFrame as a ShaderCompileException instead (see webgpu_error_ledger.dart), and a test — open_test.dart is the one that asks a browser what it makes of the generated WGSL — reads it sooner from debugDrainErrors. The WGSL a translator produced is WGSL nobody typed.

Every module this backend ever compiles goes through here, the engine's stages and a loaded bundle's alike, so a stage that arrives broken at half past a reload is reported in the same words as one that shipped broken.

Implementation

@override
Object compileModule(String name, String wgsl) {
  final module = _gpuDevice.createShaderModule(
    GPUShaderModuleDescriptor(code: wgsl, label: name),
  );
  _ledger.track(
    module.getCompilationInfo().toDart.then((GPUCompilationInfo info) {
      for (final message in info.messages.toDart) {
        if (message.type != 'error') continue;
        final line = message.lineNum;
        final lines = wgsl.split('\n');
        _ledger.complainOfShader(
          name,
          'line $line, column ${message.linePos}: ${message.message}',
          // WebGPU counts both from one, and zero when it names no place.
          diagnostic: ShaderDiagnostic(
            message.message,
            line: line > 0 ? line : null,
            column: message.linePos > 0 ? message.linePos : null,
            excerpt: line > 0 && line <= lines.length
                ? lines[line - 1]
                : null,
          ),
        );
      }
    }),
  );
  return module;
}