gfx-rs/wgpu
naga
Active contributors: Andy Leiserson, teoxoy, Jim Blandy, Inner Daemons
naga (naga/) is the shader translator that powers wgpu. It reads WGSL, GLSL, or SPIR-V; builds an internal IR; validates the IR against the WGSL specification's static rules; and writes back out to SPIR-V, MSL, HLSL, GLSL, WGSL, or GraphViz DOT. It is #![no_std] and #![forbid(unsafe_code)].
Purpose
- Be the shader-translation surface for
wgpu-core(and indirectly the entirewgpuecosystem). - Validate WGSL programs against the spec, with consistent error messages that the WGSL frontend uses to provide source-location diagnostics.
- Convert between every shading language
wgpucares about, so that wgpu can accept user shaders in any supported source language and produce shaders in whatever language the active backend needs. - Stay independent enough that it can be used standalone (via
naga-cli) or by other Rust projects that want shader translation.
Sub-pages
- Frontends — WGSL, GLSL, SPIR-V parsers.
- IR — the Naga IR data model.
- Processing passes — constant evaluator, type inference, namers, layouter, indexer.
- Validation —
naga::validandCapabilities. - Backends — SPIR-V, MSL, HLSL, GLSL, WGSL, DOT writers.
Directory layout
naga/
├── Cargo.toml
├── README.md
├── CHANGELOG.md naga-specific changelog (separate from wgpu's)
├── build.rs
├── fuzz/ cargo-fuzz targets
├── hlsl-snapshots/ helper crate
├── xtask/ `cargo xtask validate <backend>`
├── src/
│ ├── lib.rs crate root: re-exports + glue types
│ ├── arena.rs Arena<T>, Handle<T>, UniqueArena<T>
│ ├── span.rs SourceLocation, Span, WithSpan
│ ├── error.rs
│ ├── non_max_u32.rs NonZero-based handle helper
│ ├── racy_lock.rs
│ ├── ir/ the IR data model
│ ├── front/ wgsl/, glsl/, spv/
│ ├── back/ spv/, msl/, hlsl/, glsl/, wgsl/, dot/
│ ├── valid/ validator
│ ├── proc/ processing passes
│ ├── compact/ dead-code elimination
│ ├── common/ shared helpers
│ ├── keywords/ per-language keyword sets
│ └── diagnostic_filter.rs
├── tests/ snapshot, error, validation tests
└── ...Key abstractions
| Type | File | Purpose |
|---|---|---|
Module |
naga/src/ir/mod.rs |
Top-level shader IR. Owns arenas of types, constants, expressions, functions, entry points. |
Arena<T> |
naga/src/arena.rs |
Index-based container; items addressed by Handle<T>. |
Handle<T> |
naga/src/arena.rs |
NonZeroU32 index. Copy + Eq + Hash. No lifetime. |
Span |
naga/src/span.rs |
Source-position for IR items. |
Validator |
naga/src/valid/mod.rs |
Validates a Module, producing ModuleInfo. |
ModuleInfo |
naga/src/valid/mod.rs |
Per-expression type info, used by backends. |
Capabilities |
naga/src/valid/mod.rs |
Bitflags gating optional language features. |
BoundsCheckPolicies |
naga/src/proc/mod.rs |
Per-target out-of-bounds policy. |
How it works
graph LR
Source[Source text or SPIR-V binary] --> Front
Front[Frontend<br/>front/wgsl, glsl, spv] --> Mod[Module]
Mod --> Compact[compact<br/>optional]
Compact --> Mod
Mod --> Valid[Validator]
Valid --> Info[ModuleInfo]
Info --> Back[Backend<br/>back/spv, msl, hlsl, glsl, wgsl, dot]
Back --> Out[Target source / binary]The same Module flows through the whole pipeline. Frontends are responsible for converting source-level constructs into IR; processing passes (naga/src/proc/) prepare and analyze the IR; the validator checks it; backends emit text or bytes.
The README's small example shows the validator/backend invocation pattern explicitly:
let module = naga::front::wgsl::parse_str(wgsl)?;
let info = naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
naga::valid::Capabilities::all(),
).validate(&module)?;
naga::back::glsl::Writer::new(...).write()?;Test infrastructure
Naga's tests are extensive and rely on snapshot files:
naga/tests/in/— input shaders in WGSL, GLSL, SPIR-V.naga/tests/out/— expected outputs in every backend's language.naga/tests/naga/— the integration test harnesses (snapshot.rs,wgsl_errors.rs,validation.rs,spirv_capabilities.rs,example_wgsl.rs).
The "butterfly" pattern (WGSL → all backends, GLSL/SPIR-V → WGSL) is documented in docs/testing.md. After regenerating snapshots, run cargo xtask validate <backend> from naga/ to validate outputs against external compilers.
Capabilities and configuration
The validator is parameterized by ValidationFlags and Capabilities. Every WGSL feature beyond the spec's baseline (subgroup ops, float16/64, mesh-shader-shaped entry points, ray queries, ...) is gated by a Capabilities bit. The active set is computed from the device's Features by wgpu-naga-bridge.
Integration points
- Above:
wgpu-naga-bridgeis the canonical caller. The publishednagacrate is also used bynaga-cliand (in some cases) by user code that wants offline shader translation. - Below:
bit-set,hashbrown,indexmap,petgraph,rspirv,spirv,pp-rs(GLSL preprocessor),codespan-reporting(error formatting),unicode-ident. No platform-graphics dependencies.
Entry points for modification
- A new IR variant — see ir. Touches every frontend and backend.
- A new validation rule — see validation.
- A new constant evaluator op —
naga/src/proc/constant_evaluator.rs. AGENTS.md has notes on the borrow-checker patterns to use. - A frontend or backend feature — see the dedicated sub-pages.
Cross-references
- features/shader-translation describes the end-to-end shader pipeline through the wgpu stack.
- wgpu-naga-bridge is the bridge crate connecting naga to
wgpu-core. - naga-cli is the command-line tool that drives naga directly.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.