Dawn repository overview

This repository contains the implementation of Dawn, which is itself composed of two main libraries (dawn_native and dawn_wire), along with support libraries, tests, and samples. Dawn makes heavy use of code-generation based on the dawn.json file that describes the native WebGPU API. It is used to generate the API headers, C++ wrapper, parts of the client-server implementation, and more!

Directory structure

  • dawn.json: contains a description of the native WebGPU in JSON form. It is the data model that's used by the code generators.
  • dawn_wire.json: contains additional information used to generate dawn_wire files, such as commands in addition to regular WebGPU commands.
  • examples: a small collection of samples using the native WebGPU API. They were mostly used when bringing up Dawn for the first time, and to test the WGPUSwapChain object.
  • generator: directory containg the code generators and their templates. Generators are based on Jinja2 and parse data-models from JSON files.
    • dawn_json_generator.py: the main code generator that outputs the WebGPU headers, C++ wrapper, client-server implementation, etc.
    • templates: Jinja2 templates for the generator, with subdirectories for groups of templates that are all used in the same library.
  • infra: configuration file for the commit-queue infrastructure.
  • scripts: contains a grab-bag of files that are used for building Dawn, in testing, etc.
  • src:
    • common: helper code that is allowed to be used by Dawn's core libraries, dawn_native and dawn_wire. Also allowed for use in all other Dawn targets.
    • dawn_native: code for the implementation of WebGPU on top of graphics APIs. Files in this folder are the “frontend” while subdirectories are “backends”.
      • <backend>: code for the implementation of the backend on a specific graphics API, for example d3d12, metal or vulkan.
    • dawn_platform: definition of interfaces for dependency injection in dawn_native or dawn_wire.
    • dawn_wire: code for an implementation of WebGPU as a client-server architecture.
    • fuzzers: various fuzzers for Dawn that are running in Clusterfuzz.
    • include: public headers with subdirectories for each library. Note that some headers are auto-generated and not present directly in the directory.
    • tests:
      • end2end: tests for the execution of the WebGPU API and require a GPU to run.
      • perf_tests: benchmarks for various aspects of Dawn.
      • unittests: code unittests of internal classes, but also by extension WebGPU API tests that don't require a GPU to run.
      • white_box: tests using the GPU that need to access the internals of dawn_native or dawn_wire.
    • utils: helper code to use Dawn used by tests and samples but disallowed for dawn_native and dawn_wire.

Dawn Native (dawn_native)

The largest library in Dawn is dawn_native which implements the WebGPU API by translating to native graphics APIs such as D3D12, Metal or Vulkan. It is composed of a frontend that does all the state-tracking and validation, and backends that do the actual translation to the native graphics APIs.

dawn_native hosts the spirv-val for validation of SPIR-V shaders and uses SPIRV-Cross shader translator to convert SPIR-V shaders to an equivalent shader for use in the native graphics API (HLSL for D3D12, MSL for Metal or Vulkan SPIR-V for Vulkan).

Dawn Wire (dawn_wire)

A second library that implements both a client that takes WebGPU commands and serializes them into a buffer, and a server that deserializes commands from a buffer, validates they are well-formed and calls the relevant WebGPU commands. Some server to client communication also happens so the API's callbacks work properly.

Note that dawn_wire is meant to do as little state-tracking as possible so that the client can be lean and defer most of the heavy processing to the server side where the server calls into dawn_native.

Dawn Proc (dawn_proc)

Normally libraries implementing webgpu.h should implement function like wgpuDeviceCreateBuffer but instead dawn_native and dawn_wire implement the dawnProcTable which is a structure containing all the WebGPU functions Dawn implements. Then a dawn_proc library contains a static version of this dawnProcTable and for example forwards wgpuDeviceCreateBuffer to the procTable.deviceCreateBuffer function pointer. This is useful in two ways:

  • It allows deciding at runtime whether to use dawn_native and dawn_wire, which is useful to test boths paths with the same binary in our infrastructure.
  • It avoids applications that know they will only use Dawn to query all entrypoints at once instead of using wgpuGetProcAddress repeatedly.

Code generation

When the WebGPU API evolves, a lot of places in Dawn have to be updated, so to reduce efforts, Dawn relies heavily on code generation for things like headers, proc tables and de/serialization. For more information, see codegen.md.