Open-Source Wikis

/

wgpu

/

Crates

/

Naga validation

gfx-rs/wgpu

Naga validation

naga/src/valid/ is the IR validator. It checks that a Module satisfies the WGSL specification's static rules and produces a ModuleInfo that backends consume.

Modules

naga/src/valid/
├── mod.rs           Validator, Capabilities, ValidationFlags (~35 KB)
├── analyzer.rs      analyzer (~66 KB)
├── compose.rs       struct/array composition checks
├── expression.rs    expression rules (~70 KB)
├── function.rs      function rules (~93 KB)
├── handles.rs       cross-arena handle integrity (~44 KB)
├── immediates.rs    push-constant / immediate-data layout
├── interface.rs     entry-point I/O rules (~72 KB)
└── type.rs          type rules (~42 KB)

The largest files are function.rs, interface.rs, and expression.rs — they cover the rules with the most spec language.

How it works

graph LR
    Mod[Module] --> Validator
    Cap[Capabilities] --> Validator
    Flags[ValidationFlags] --> Validator
    Validator -->|per-pass checks| AnalyzerOut[GlobalUse + analyzer state]
    AnalyzerOut --> Info[ModuleInfo]
    Info --> Back[Back-ends]

Validator::new(flags, caps) then .validate(&module) produces either a ModuleInfo or a WithSpan<ValidationError>. A successful ModuleInfo carries:

  • per-expression TypeResolution — the inferred type of every expression in the module.
  • GlobalUse — which entry points use which globals, and how (read/write/atomic).
  • per-function summaries — call graph, control-flow bookkeeping.

ValidationFlags

Bitflags toggling which checks run. ValidationFlags::all() runs every check and is the default. Use ValidationFlags::empty() to skip validation entirely (e.g. for trusted, pre-validated input).

Capabilities

Capabilities declares which optional language features are allowed. Examples:

  • FLOAT64, FLOAT16, FLOAT32_ATOMIC
  • RAY_QUERY, RAY_HIT_VERTEX_POSITION, EXT_RAY_TRACING_NV
  • SUBGROUP, SUBGROUP_BARRIER, SUBGROUP_VERTEX_STAGE
  • MULTIVIEW
  • STORAGE_TEXTURE_16BIT_NORM_FORMATS, MULTISAMPLED_SHADING
  • MESH_SHADER, TASK_SHADER
  • SAMPLER_NON_UNIFORM_INDEXING, STORAGE_RESOURCE_BINDING_ARRAY
  • ... and many more

The bridge in wgpu-naga-bridge maps wgt::Features to Capabilities. If the user enables Features::SHADER_F64, the bridge passes Capabilities::FLOAT64 to the validator.

Pass structure

Validator::validate runs through the module in roughly this order:

  1. Type validation (type.rs) — each Type is well-formed (sizes, alignments, image classes match capabilities).
  2. Constant validation — constants and overrides have valid types and values.
  3. Global variable validation — address-space rules, binding decoration consistency.
  4. Function body validation (function.rs, expression.rs, compose.rs, analyzer.rs) — control flow is structured; every expression's operands have the expected types; built-in calls have matching overloads; bind groups referenced by the function are well-formed.
  5. Entry-point validation (interface.rs) — fragment outputs, vertex inputs, compute workgroup sizes, mesh/task shader I/O, builtin variable usage.
  6. Handles cross-check (handles.rs) — every Handle<T> references a real arena slot. Catches IR construction bugs in frontends and processing passes.

If any pass fails, the validator returns immediately with a WithSpan<ValidationError> carrying source-position info that the WGSL frontend can use to render diagnostics.

ModuleInfo for backends

Backends are not allowed to re-derive types: they must use the ModuleInfo produced by the validator. This guarantees that the validator's view and the backend's view of an expression's type agree exactly. The Module + ModuleInfo pair is what wgpu-naga-bridge hands off to whichever backend is active.

Tests

  • naga/tests/naga/wgsl_errors/ — most validation rules show up in user diagnostics. This is the broadest test surface.
  • naga/tests/naga/validation/ — handcrafted IR that the WGSL frontend can't easily produce. Lower volume.
  • naga/tests/naga/spirv_capabilities/ — checks that the output of a SPIR-V backend run includes the expected SPIR-V capabilities (e.g., that using f64 produces OpCapability Float64).

Modifying validation

  • A new validation rule — add to the appropriate module (most rules go in expression.rs, function.rs, or interface.rs). Add a ValidationError variant if needed. Add a wgsl-error test that triggers it.
  • A new capability — declare in valid/mod.rs::Capabilities. Map from wgt::Features in wgpu-naga-bridge. Update validator passes that should consume it.
  • A frontend bug that the validator should catch — file the test under wgsl_errors first; if it can't trigger via WGSL, build it as a hand-rolled test in validation/.

The contract is simple: nothing should ever reach a backend that the validator doesn't endorse, and the validator should reject everything the spec rejects.

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

Naga validation – wgpu wiki | Factory