Open-Source Wikis

/

wgpu

/

wgpu

/

Architecture

gfx-rs/wgpu

Architecture

wgpu is a layered system. The top layer is the public Rust or JavaScript API; the bottom layer is the platform's native graphics driver (Vulkan, Metal, D3D12, GL, or the browser's WebGPU). Between them sit two layers of wgpu's own code that implement WebGPU semantics, plus a separate library for shader translation.

There is a canonical block diagram in docs/big-picture.png (and the editable docs/big-picture.xml). The text below describes the same picture.

High-level layering

graph TD
    subgraph Clients
        App[Native Rust app]
        FF[Firefox / Servo]
        Deno[Deno runtime]
        Web[Web page in a browser]
    end

    subgraph wgpu_repo[This repository]
        Wgpu[wgpu crate<br/>idiomatic Rust API]
        DenoBindings[deno_webgpu<br/>JS bindings]
        Core[wgpu-core<br/>WebGPU semantics + validation]
        Naga[naga<br/>shader translator]
        Hal[wgpu-hal<br/>per-API backends]
        Types[wgpu-types<br/>shared types]
    end

    subgraph Drivers
        Vk[Vulkan driver]
        Mt[Metal driver]
        Dx[DX12 driver]
        Gl[GL / WebGL2]
        Browser[Browser WebGPU]
    end

    App --> Wgpu
    FF --> Core
    Deno --> DenoBindings
    DenoBindings --> Core
    Web --> Browser

    Wgpu -.wasm WebGPU backend.-> Browser
    Wgpu --> Core
    Core --> Naga
    Core --> Hal
    Hal --> Vk
    Hal --> Mt
    Hal --> Dx
    Hal --> Gl

    Wgpu --- Types
    Core --- Types
    Hal --- Types

The wgpu crate has two backends of its own (wgpu/src/backend/):

  • wgpu_core — calls into wgpu-core for native targets and WebGL2.
  • webgpu — calls into the browser's navigator.gpu via web-sys when compiled for the web with the webgpu feature.

There is also a custom backend that lets downstream embedders plug in their own dispatch (wgpu/src/backend/custom.rs), exposed through the custom crate feature.

Layer responsibilities

wgpu (wgpu/src/api/, wgpu/src/backend/)

The user-facing crate. Exposes idiomatic, refcounted Rust types: Instance, Adapter, Device, Queue, Buffer, Texture, CommandEncoder, render and compute passes, etc. Each type lives in its own file under wgpu/src/api/. The handle types are thin wrappers around Arc<dyn DispatchFoo> trait objects defined in wgpu/src/dispatch.rs. The dispatch trait routes calls to one of the three backends (wgpu_core, webgpu, custom).

This crate adds no validation of its own — it is a transport layer. Validation is the responsibility of wgpu-core (or the browser, on the WebGPU backend).

wgpu-core (wgpu-core/src/)

The portable, FFI-shaped implementation of WebGPU. This is what Firefox and Deno actually link against. Responsibilities:

  • Resource registry — every public resource (buffers, textures, bind groups, pipelines, ...) gets an Id from a slab-allocated registry (wgpu-core/src/registry.rs, wgpu-core/src/storage.rs, wgpu-core/src/hub.rs).
  • Validation — checks descriptors, usages, lifetimes, label limits, format compatibility (wgpu-core/src/validation.rs, plus per-resource validation in each module).
  • Resource state tracking — tracks buffer/texture usage states across passes and command buffers so it can insert correct barriers (wgpu-core/src/track/).
  • Command building — the CommandEncoder and pass APIs translate WebGPU commands into HAL commands (wgpu-core/src/command/, where mod.rs, render.rs, compute.rs, bundle.rs, transfer.rs, clear.rs, ray_tracing.rs live).
  • Submission and lifetime trackingwgpu-core/src/device/queue.rs and wgpu-core/src/device/life.rs manage submissions, fences, and resource cleanup.
  • Pipelines, bind groups, layoutswgpu-core/src/pipeline.rs, wgpu-core/src/binding_model.rs.
  • Swapchain gluewgpu-core/src/present.rs.
  • Tracing — optional API trace capture (wgpu-core/src/device/trace.rs, wgpu-core/src/device/trace/).
  • Indirect-draw validation — a separate compute-shader-based validator for indirect commands (wgpu-core/src/indirect_validation/).

wgpu-core calls wgpu-hal for everything that touches the GPU and naga for shader translation.

wgpu-hal (wgpu-hal/src/)

A thin, unsafe abstraction over native graphics APIs. The traits live in wgpu-hal/src/lib.rs; one module per backend implements them:

  • wgpu-hal/src/vulkan/ — Vulkan via the ash crate.
  • wgpu-hal/src/metal/ — Metal via objc2/objc2-metal (no third-party Metal crate; objc2 bindings directly).
  • wgpu-hal/src/dx12/ — Direct3D 12 via the windows crate.
  • wgpu-hal/src/gles/ — OpenGL ES, OpenGL, WebGL2, EGL/WGL, plus emscripten and web shims.
  • wgpu-hal/src/noop/ — A backend that does no work; used for trace tests and validation-only tests.

There is also wgpu-hal/src/dynamic/ providing DynInstance/DynDevice trait-object shims so wgpu-core can hold backends without monomorphizing over them, and wgpu-hal/src/auxil/ for shared helpers (DXC compiler glue, format conversions, renderdoc capture, etc.).

wgpu-hal does no validation and no state tracking. It is roughly a 1:1 mapping over the native API's command buffers, descriptor sets / argument buffers, and resources. Errors are limited to "things the user can't anticipate" like out-of-memory and device lost.

naga (naga/src/)

Shader translator. Reads WGSL, GLSL, or SPIR-V. Builds a Naga IR (naga/src/ir/). Validates the IR (naga/src/valid/) against the WGSL specification. Writes out SPIR-V, MSL, HLSL, GLSL, WGSL, or DOT.

graph LR
    WGSL[WGSL source] --> Front
    GLSL[GLSL source] --> Front
    SPV[SPIR-V binary] --> Front
    Front[front/<br/>parsers] --> IR[Naga IR<br/>arena-based]
    IR --> Compact[compact/<br/>dead-code elimination]
    IR --> Valid[valid/<br/>type/handle/function checking]
    Valid --> IR
    Compact --> IR
    IR --> Back[back/<br/>writers]
    Back --> SpvOut[SPIR-V]
    Back --> MSL[Metal Shading Language]
    Back --> HLSL[HLSL]
    Back --> GLSLOut[GLSL]
    Back --> WGSLOut[WGSL]
    Back --> DOT[GraphViz DOT]

naga is #![no_std] and #![forbid(unsafe_code)]. It can be used standalone (e.g. via the naga CLI) or inside wgpu-core. The wgpu-naga-bridge crate adapts naga's types to wgpu-core's data flow.

wgpu-types (wgpu-types/src/)

Plain-data structs and enums (Features, Limits, TextureFormat, BufferUsages, Color, ...) shared by all three layers and by downstream consumers. Has no platform code; runs on all targets including wasm.

Languages spoken across the boundary

graph LR
    Public["Public API:<br/>Rust handles or<br/>JS objects via deno_webgpu"] --> Ids
    Ids["wgpu-core: u64 Ids<br/>(FFI-friendly)"] --> Hal
    Hal["wgpu-hal: trait objects<br/>(DynInstance, DynDevice, ...)"] --> Native["Native API:<br/>VkDevice, MTLDevice,<br/>ID3D12Device, GL context"]
  • The public Rust API uses owned, refcounted handles (Buffer, Texture, ...) that internally hold Arc<dyn DispatchBuffer> etc.
  • wgpu-core's public surface is ID-based and extern "C"-friendly (wgpu-core/src/id.rs, wgpu-core/src/global.rs). This is what Firefox's gfx/wgpu_bindings/ calls.
  • wgpu-hal uses Rust trait objects but is unsafe. There is a static dispatch path (vulkan::Api, metal::Api, ...) and a dynamic dispatch path (DynInstance, DynDevice, ...) that lets wgpu-core carry a Vec<(Backend, Box<dyn DynInstance>)>.

Where data lives at each layer

Concern Layer Files
Refcounted handle types wgpu wgpu/src/api/*.rs
Backend dispatch wgpu wgpu/src/dispatch.rs, wgpu/src/backend/
Resource registry by ID wgpu-core wgpu-core/src/{hub,registry,storage,id}.rs
Validation wgpu-core wgpu-core/src/validation.rs and per-resource *.rs
State/usage tracking wgpu-core wgpu-core/src/track/
Lock ranking wgpu-core wgpu-core/src/lock/
Command translation wgpu-core wgpu-core/src/command/
HAL traits wgpu-hal wgpu-hal/src/lib.rs
Vulkan backend wgpu-hal wgpu-hal/src/vulkan/
Metal backend wgpu-hal wgpu-hal/src/metal/
DX12 backend wgpu-hal wgpu-hal/src/dx12/
GLES/WebGL backend wgpu-hal wgpu-hal/src/gles/
Shader IR naga naga/src/ir/
Shader frontends naga naga/src/front/{wgsl,glsl,spv}/
Shader backends naga naga/src/back/{spv,msl,hlsl,glsl,wgsl,dot}/
Shader validation naga naga/src/valid/
Constant evaluator naga naga/src/proc/constant_evaluator.rs

Lifetime of a draw call

sequenceDiagram
    participant U as User code
    participant W as wgpu (Rust API)
    participant C as wgpu-core
    participant H as wgpu-hal (Vulkan)
    participant V as VkDevice
    U->>W: render_pass.draw(0..3, 0..1)
    W->>W: dispatch.rs routes to wgpu_core backend
    W->>C: render_pass_draw(pass_id, 0, 3, 0, 1)
    C->>C: validate (pipeline set? bind groups bound? buffer bindings in range?)
    C->>C: track buffer/texture usages
    C->>H: encoder.draw(...)
    H->>V: vkCmdDraw(cmd_buf, 3, 1, 0, 0)

When the encoder is finished and the queue submits the command buffer, wgpu-core flushes its tracker, inserts pipeline barriers via wgpu-hal, and calls into the platform queue.

The naga integration

The wgpu-naga-bridge crate (wgpu-naga-bridge/src/) takes the parsed WGSL/SPIR-V module produced by naga, runs naga's validator with the right Capabilities for the device, and hands the validated module to whichever naga backend matches the active wgpu-hal backend (SPIR-V for Vulkan, MSL for Metal, HLSL for DX12, GLSL for GLES). On the WebGPU backend, the WGSL source is simply passed through to the browser unchanged.

Cross-cutting features

These are explored in features/:

  • Shader translation — the WGSL/GLSL/SPIR-V → IR → SPIR-V/MSL/HLSL/GLSL pipeline.
  • Cross-platform backends — how a single wgpu API maps onto five very different drivers.
  • Ray tracing — experimental BLAS/TLAS/@ray_query support.
  • Mesh shading — experimental task/mesh pipelines.
  • API tracing — capturing and replaying API calls via wgpu-core's Trace infrastructure and the player crate.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – wgpu wiki | Factory