gfx-rs/wgpu
Naga backends
Backends consume a validated Module (plus its ModuleInfo) and emit text or bytes in a target shading language. They live under naga/src/back/.
Layout
naga/src/back/
├── mod.rs shared types (FunctionCtx, etc.) (~14 KB)
├── continue_forward.rs `continue` and forward-jump rewriting helper (~13 KB)
├── pipeline_constants.rs pipeline-constant override substitution (~42 KB)
├── spv/ SPIR-V binary writer
├── msl/ Metal Shading Language writer
├── hlsl/ HLSL writer (Shader Model 5.0+)
├── glsl/ GLSL writer (GLSL 330+, GLSL ES 300+)
├── wgsl/ WGSL writer
└── dot/ GraphViz DOT writerStatus
| Backend | Status | Notes |
|---|---|---|
SPIR-V (spv-out) |
Primary | Used by Vulkan. |
MSL (msl-out) |
Primary | Used by Metal. |
HLSL (hlsl-out) |
Primary | Used by DX12. Shader Model 5.0+. |
GLSL (glsl-out) |
Secondary | Used by GLES. GLSL 330+ / ES 300+. |
WGSL (wgsl-out) |
Secondary | Round-trips. Used for snapshot tests of GLSL/SPIR-V → WGSL. |
DOT (dot-out) |
Secondary | GraphViz dump for debugging. |
SPIR-V backend (spv/)
naga/src/back/spv/:
writer.rs(~163 KB) — SpvWriter implementation.block.rs(~183 KB) — control-flow emission.- Plus
instructions.rs,image.rs,helpers.rs, etc.
Builds SPIR-V via spirv and rspirv. Emits OpCapability declarations matching the IR's use of features (Float64, RayQueryKHR, ...). The spirv_capabilities test asserts the right ones come out.
The SPIR-V backend uses pipeline_constants.rs to substitute pipeline-override constants at the IR level before emission, so the resulting SPIR-V module is fully concrete.
Metal backend (msl/)
naga/src/back/msl/:
writer.rs(~349 KB) — the largest source file in the repo.- Plus support for argument buffers, raytracing intrinsics, mesh-shader entry points.
Emits MSL source text, which Metal compiles via MTLDevice::newLibraryWithSource:. The Metal backend handles a lot of fiddly details around argument-buffer encoding, autorelease behavior of intermediate types, and MSL's specific syntax for things like atomics and barycentric coordinates.
HLSL backend (hlsl/)
naga/src/back/hlsl/:
writer.rs(~214 KB).- Targets Shader Model 5.0+, i.e. DirectX 11 and DirectX 12.
- Output is passed to DXC (preferred), static-DXC, or FXC by the DX12 HAL backend.
HLSL has tricky shape-conversion rules; the backend goes to some lengths to emit correct cbuffer layouts, structured buffer member orderings, and root-signature-friendly bindings. The naga/hlsl-snapshots/ helper crate participates in HLSL-specific snapshot tests.
GLSL backend (glsl/)
naga/src/back/glsl/:
writer.rs(~198 KB).- Targets GLSL 330+ and GLSL ES 300+.
- Used by
wgpu-hal/src/gles/and by anyone who wants WGSL → GLSL conversion.
GLSL is the trickiest target because of the GLES feature ladder: storage buffers, compute shaders, and some sampling modes were added across GLES 3.0/3.1/3.2. The backend takes a Version parameter that gates emission.
WGSL backend (wgsl/)
naga/src/back/wgsl/ writes WGSL. Useful for:
- Round-trip testing — parse SPIR-V/GLSL, lower to IR, write WGSL, ensure semantics are preserved.
- Tooling that wants a canonical form (deno_webgpu and others may use this).
DOT backend (dot/)
GraphViz output. Use naga --flow-dir <dir> shader.spv to dump the SPIR-V control-flow graph as .dot files. Useful for understanding what the SPIR-V structurizer sees.
Pipeline constants
naga/src/back/pipeline_constants.rs performs override substitution: WGSL's @override constants and SPIR-V's specialization constants are replaced with concrete values before code emission. This happens once per pipeline, not once per shader module — wgpu-core calls it when constructing a RenderPipeline/ComputePipeline.
Bounds checks at the backend level
Backends respect BoundsCheckPolicies (from naga::proc). They emit either:
- a
min(idx, len-1)style clamp, - a guarded read that returns zero on out-of-bounds,
- or no check at all (
Unchecked),
depending on the policy and address space.
Modifying a backend
Common patterns:
- A new IR variant emitted differently — add the case to each backend's writer. Pay attention to the differences in target-language semantics (HLSL doesn't have
mat3x4, MSL has different array-of-array rules, GLSL has version-dependent atomics, etc.). - A new emission for an existing variant — usually a single-file change in the affected backend's
writer.rs. - A new pipeline-constant case —
naga/src/back/pipeline_constants.rsis centralized. - A new bounds-check policy — extend
BoundsCheckPolicy, then add the emission for each backend.
Always run cd naga && cargo xtask validate <backend> after regenerating snapshots so the output is checked by the actual external compiler.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.