iridia-naga
Lowers a program of iridia's shader IR to a stock naga module, validated, for naga's writers (WGSL).
Part of iridia, which turns compiled shaders into programs other tools can read and write. Readers lift into the IR, iridia-passes puts a program in the form naga takes, and this crate lowers it. The design is docs/design/ir.md. This crate is no_std with alloc and does no I/O; it depends on naga as published, with no fork.
What it does
module(program, plan)builds the module: the entry pointmainwith an argument per interface input and a member of the result structureOutper output (entry_iostates them), and each resource a global where theBindingPlanbinds it.BindingPlan::d3dputs Direct3D's register classes in bind groups 0 to 3 (cbN,tN,sN,uN), each register its binding.- Operations naga has whole map to one expression; the others expand in the lowering, each in one function: a zero-wins multiply,
minandmaxwith their NaN rule,saturateof NaN, a float-to-integer conversion that saturates, rounding with ties away from zero, a constant buffer row read outside the buffer. - A masked input load is a swizzle of the argument; a masked output store is composed with what the output held (zero before the first store).
validate(module, profile)runs naga's validator with the profile's capabilities;wgsl(program, profile)(thewgslfeature, on by default) preflights the program, lowers it with the D3D plan, validates and writes the WGSL.
Example
use ;
let entry = parse
.unwrap;
let varying = ;
let program = Program ;
validate.unwrap;
let wgsl = wgsl.unwrap;
assert!;
// WGSL leaves what a clamp makes of NaN to the implementation: the NaN-to-zero rule is spelled out
assert!;
Guarantees and limits
- A program is lowered for a target
Profile(Profile::BROWSERfor WebGPU's core WGSL,Profile::NAGAfor naga's own dialect, either widened withProfile::with):preflightrefuses a program that needs a capability the profile lacks, naming the value, varying or resource that needs it, and naga's validator runs with the profile's capabilities alone. A module naga rejects after the preflight accepted is reported as a lowering bug. - It lowers what the Direct3D 9 reader makes, and refuses the rest by name.
- naga's
breakandcontinuereach only the innermost construct: runiridia_passes::break_flagsfirst. ACfgbody must be structured first (iridia_passes::structurize). - Pipeline state is not lowered:
iridia_passes::specialiseit first. - WGSL text cannot say a varying has no interpolation, and naga's namer adds a
_to some names; a reader of the WGSL sees those, not the IR's.
Tests
cargo test -p iridia-naga needs no game files: tests/lower.rs pins the WGSL of masked loads and stores and checks that unspecialised state is refused. The Direct3D 9 reader's tests lower every Shaun White Skateboarding program they read.
Licence
GPL-3.0-or-later.