gfx-rs/wgpu
wgpu
Active contributors: Connor Fitzgerald, Andy Leiserson, Erich Gubler, Kevin Reid, teoxoy
The wgpu crate (wgpu/) is the user-facing Rust API. It is what application authors and game engines depend on. It is not used by Firefox or Deno — those bind directly to wgpu-core. The wgpu crate's job is to be ergonomic Rust over the underlying implementation.
Purpose
- Idiomatic Rust types for WebGPU concepts:
Instance,Adapter,Device,Queue,Buffer,Texture,CommandEncoder,RenderPass,ComputePass, etc. The full list lives inwgpu/src/api/. - Refcounted, cloneable handles. Dropping the last reference schedules cleanup; the GPU's view of the resource lives on until the device polls.
- A backend dispatch layer that picks between the native (
wgpu_core) backend, the browser (webgpu) backend, and a user-pluggablecustombackend at runtime. - Re-exports of
wgpu-typesso users can nameBufferUsages,Features,Limits, etc. directly off the crate root. - Re-exports of
naga,raw-window-handle, and (on web)web-sysso users can integrate with the broader ecosystem.
Directory layout
wgpu/
├── Cargo.toml
├── build.rs cfg_aliases + build-time feature wiring
└── src/
├── lib.rs crate root: re-exports, doc, modules
├── api/ one file per public type
│ ├── adapter.rs
│ ├── bind_group.rs
│ ├── buffer.rs
│ ├── command_encoder.rs
│ ├── compute_pass.rs
│ ├── device.rs
│ ├── instance.rs
│ ├── queue.rs
│ ├── render_bundle.rs
│ ├── render_bundle_encoder.rs
│ ├── render_pass.rs
│ ├── render_pipeline.rs
│ ├── compute_pipeline.rs
│ ├── shader_module.rs
│ ├── surface.rs
│ ├── texture.rs
│ ├── tlas.rs / blas.rs / external_texture.rs
│ └── ... 30+ files in total
├── backend/
│ ├── mod.rs
│ ├── custom.rs user-pluggable backend hooks
│ ├── webgpu.rs browser WebGPU backend (~150 KB)
│ ├── webgpu/ support submodules
│ ├── wgpu_core.rs native backend via wgpu-core (~125 KB)
│ └── wgpu_core/
├── cmp.rs handle equality
├── dispatch.rs the backend trait dispatch layer
├── lib.rs crate root
├── macros.rs / macros/
└── util/ vertex layout helpers, encase helpers, etc.The api/mod.rs module convention is described in its own header comment: each public type gets its own file, descriptors live next to the type they describe, and crate::* is imported at the top so docs read naturally.
Key abstractions
| Type | File | Purpose |
|---|---|---|
Instance |
wgpu/src/api/instance.rs |
Entry point. Owns the per-backend instance handles. |
Adapter |
wgpu/src/api/adapter.rs |
A specific GPU exposed by a specific backend. |
Device |
wgpu/src/api/device.rs |
Logical GPU. Source of all resource creation. |
Queue |
wgpu/src/api/queue.rs |
Submission queue. |
CommandEncoder |
wgpu/src/api/command_encoder.rs |
Builds a command buffer. |
RenderPass / ComputePass |
wgpu/src/api/{render,compute}_pass.rs |
Encoding inside a pass. |
Buffer, Texture, TextureView, Sampler |
one file each in wgpu/src/api/ |
Refcounted resource handles. |
Surface, SurfaceTexture |
wgpu/src/api/surface*.rs |
Swapchain integration. |
Blas, Tlas |
wgpu/src/api/blas.rs, wgpu/src/api/tlas.rs |
Ray tracing acceleration structures. |
DispatchInstance and friends |
wgpu/src/dispatch.rs |
Trait-based dispatch over backends. |
Every public type is a pub struct with a few fields including an Arc<dyn DispatchFoo>. The trait objects live in wgpu/src/dispatch.rs (~37 KB). They're implemented by the backends in wgpu/src/backend/wgpu_core.rs and wgpu/src/backend/webgpu.rs. There is no monomorphization across backends — the cost is one virtual call per API entry point, paid in exchange for a single binary supporting both native and web.
How it works
graph TD
User[User code] -->|wgpu::Buffer::map_async| Buffer
Buffer -->|inner: Arc dyn DispatchBuffer| Dispatch[dispatch.rs traits]
Dispatch -->|wgpu_core backend| WgpuCoreBackend[backend/wgpu_core.rs]
Dispatch -->|webgpu backend| WebGpuBackend[backend/webgpu.rs]
Dispatch -->|custom backend| Custom[backend/custom.rs]
WgpuCoreBackend -->|GlobalReport, Id| WgpuCore[wgpu-core::Global]
WebGpuBackend -->|web-sys + js-sys| Browser[navigator.gpu]
Custom --> UserImpl[user-supplied impl]When a user calls instance.request_adapter(...).await, the Instance figures out which backends are available (compiled in plus runtime-supported), constructs a single wgpu_core instance, then asks each enabled backend for adapters. The returned Adapter carries an Arc<dyn DispatchAdapter> whose concrete type depends on the backend.
Refcounted handles use Arc directly. The Drop implementations on most types do nothing — cleanup is the responsibility of the owning device's lifetime tracker (wgpu-core/src/device/life.rs). This is what makes "you can clone any handle" cheap.
Features that are unique to this crate
The user-facing crate has a set of crate features that gate functionality:
| Feature | Purpose |
|---|---|
wgsl, glsl, spirv |
Shader frontends. wgsl is on by default. |
vulkan, metal, dx12, gles, webgpu, noop |
Backends. |
vulkan-portability, angle, static-dxc |
Backend variants. |
serde, arbitrary |
Optional integrations. |
trace, replay |
Re-export wgpu-core's tracing. |
fragile-send-sync-non-atomic-wasm |
Wasm without atomics. |
custom |
Expose backend::custom for user-supplied backends. |
web |
Build for the web with the webgpu backend. |
naga-ir |
Accept naga IR modules directly without re-parsing. |
The list, with the doc comments that ship in the API docs, lives in wgpu/Cargo.toml and is rendered into wgpu/src/lib.rs by document_features.
Integration points
- Reads from:
wgpu-types(re-exports),wgpu-core(whenwgpu_corecfg is set),wgpu-hal(re-exportshal::api::*and constants),naga(re-exports).web-sysandjs-sysfor the browser backend. - Provides to user: idiomatic Rust API.
- Custom backends:
wgpu/src/backend/custom.rsgives downstream embedders a way to plug in their own dispatch implementations without forking the crate. Used, for example, when an application wants to wrap wgpu in remoting glue.
Entry points for modification
- Adding a method to a public type — find the type's file under
wgpu/src/api/, add the method on theimplblock, declare the matching trait method inwgpu/src/dispatch.rs, then implement it in bothwgpu/src/backend/wgpu_core.rsandwgpu/src/backend/webgpu.rs. If the method changes user-visible API, updateCHANGELOG.md. - Adding a new resource type — start by adding a new module in
wgpu/src/api/, including a descriptor type and the handle. Add corresponding dispatch traits and backend implementations. The reference shape isBuffer(wgpu/src/api/buffer.rs) for a refcounted handle, orSurface(wgpu/src/api/surface.rs) for a less-common shape. - A new shader frontend — usually goes in
nagafirst; thewgpucrate exposes it via thewgsl/glsl/spirvfeatures and throughShaderModuleDescriptor::sourceinwgpu/src/api/shader_module.rs.
The crate intentionally does no validation. If you find yourself writing if foo > limit { return Err(...); } in wgpu/, the validation belongs in wgpu-core instead. See patterns-and-conventions.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.