Open-Source Wikis

/

wgpu

/

Crates

/

wgpu-hal

gfx-rs/wgpu

wgpu-hal

Active contributors: Inner Daemons, teoxoy, Connor Fitzgerald, Andy Leiserson, Erich Gubler

wgpu-hal (wgpu-hal/) is the unsafe hardware abstraction layer. It defines a set of traits modeled on a "WebGPU shaped" command buffer + resource API, and ships one backend per platform graphics API.

Purpose

  • Provide a portable trait surface (Instance, Adapter, Device, Queue, CommandEncoder, Buffer, Texture, ...) that's a thin shim over real graphics APIs.
  • Move the cost of validation and state tracking to the layer above (wgpu-core). HAL backends do as little as possible.
  • Use static dispatch by default (each backend has its own marker type implementing the Api trait); offer dynamic dispatch wrappers for wgpu-core to use.
  • Map buffer contents persistently. Require explicit barriers between resource usages.

The wgpu-hal/README.md enumerates the design choices in detail and is required reading before modifying this crate.

Sub-pages by backend

  • Vulkan — the primary backend. Linux, Android, Windows; macOS via MoltenVK.
  • Metal — macOS, iOS, tvOS.
  • DX12 — Windows.
  • GLES — OpenGL ES, OpenGL, WebGL2, EGL/WGL/web.
  • Noop — does nothing; used by validation tests.

Directory layout

wgpu-hal/
├── Cargo.toml
├── README.md
├── build.rs
├── examples/
└── src/
    ├── lib.rs                       trait surface (~108 KB)
    ├── auxil/                       shared helpers (DXC compiler, format conversions, renderdoc)
    ├── dx12/                        D3D12 backend
    ├── dynamic/                     trait-object wrappers
    ├── gles/                        GL/GLES/WebGL2 backend
    ├── metal/                       Metal backend
    ├── noop/                        no-op backend
    ├── validation_canary.rs         shared canary file for validation-layer warnings
    └── vulkan/                      Vulkan backend

The trait surface is one of the largest files in the workspace (wgpu-hal/src/lib.rs, ~108 KB). It defines the Api associated-types trait and every type alias that backends implement.

Key abstractions

Trait / type File Purpose
Api wgpu-hal/src/lib.rs Marker trait whose associated types name every other HAL type. One impl per backend.
Instance, Adapter, Device, Queue, CommandEncoder wgpu-hal/src/lib.rs The main lifecycle traits.
Buffer, Texture, TextureView, Sampler, BindGroup, BindGroupLayout, PipelineLayout, RenderPipeline, ComputePipeline, ShaderModule wgpu-hal/src/lib.rs Resource types (the per-backend impls are concrete types).
DynInstance, DynDevice, etc. wgpu-hal/src/dynamic/ Object-safe trait-object wrappers used by wgpu-core.
auxil::dxc_shader_compiler wgpu-hal/src/auxil/dxc_shader_compiler.rs DXC integration shared by DX12 (and indirectly tests).
auxil::renderdoc wgpu-hal/src/auxil/renderdoc.rs RenderDoc capture API integration.

Backend selection

Backends are enabled at compile time via cfg flags (build.rs defines vulkan, metal, dx12, gles, noop). At runtime, wgpu-core constructs the Instance for each enabled backend that succeeds — see wgpu-core/src/instance.rs::Instance::try_add_hal. The WGPU_BACKEND environment variable filters which ones are tried.

Static vs dynamic dispatch

wgpu-hal is static-dispatch first. Each backend exposes a marker type:

// in wgpu-hal/src/vulkan/mod.rs
pub struct Api;
impl crate::Api for Api {
    type Instance = vulkan::Instance;
    type Device = vulkan::Device;
    type Queue = vulkan::Queue;
    // ...
}

wgpu-core would otherwise have to be parameterized over A: hal::Api, which complicates its public surface. Instead, wgpu-hal/src/dynamic/ provides object-safe DynInstance/DynDevice/DynBuffer/... traits and blanket impls that let wgpu-core carry a Vec<(Backend, Box<dyn DynInstance>)>.

Safety contract

The wgpu-hal traits are unsafe. From the README:

  • Implementations perform minimal validation. Incorrect use causes undefined behavior.
  • Returned errors only cover cases the user can't anticipate (OOM, lost device).
  • Pipeline layouts are explicitly specified when binding bind groups; a mismatched layout silently corrupts higher-indexed bindings.
  • Barriers are explicit. The caller must call transition_buffers / transition_textures between conflicting usages.
  • Buffer maps are persistent. Coherency between CPU and GPU is the caller's responsibility unless the implementation reports the mapping as coherent.
  • Iterators passed to HAL methods aren't guaranteed to be drained, so they shouldn't have side effects.

These rules are why wgpu-core exists: layering safety on top of wgpu-hal is a substantial amount of work, done once.

Integration points

  • Above: wgpu-core is the only intended consumer. The wgpu-hal crate is published independently for the rare downstream that wants to skip wgpu-core and roll its own validation, but that path is not actively supported.
  • Below: each backend wraps a specific external crate or system API. See the per-backend pages.
  • Sideways: shared helpers in wgpu-hal/src/auxil/ (DXC compiler glue, format helpers, renderdoc, validation_canary).

Entry points for modification

  • Adding a HAL method — add it to the trait in wgpu-hal/src/lib.rs, then implement it in every backend (vulkan/, metal/, dx12/, gles/, noop/). Add the matching DynFoo method in wgpu-hal/src/dynamic/. Then call it from wgpu-core.
  • Adding a backend-specific extension — see the backend's page; some are exposed via Adapter-level capability bits and a method that's only available when the bit is set.
  • Improving a backend — most work happens in the per-backend mod.rs, device.rs, command.rs, and adapter.rs files. Hot paths in command encoding live in command.rs for each backend.

For each backend's specifics, follow the sub-page links above.

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

wgpu-hal – wgpu wiki | Factory