Skip to main content

Module shader

Module shader 

Source
Expand description

The converted-shader interface (Plan 0100 Phase 6): what a translated MilkDrop 2 warp/comp fragment shader may bind, the uniform block behind its ~40-name input surface, and the naga gate every bundle shader passes at load.

§This is the contract, in one place

milkconv emits a complete WGSL fragment module: fragment_prelude (the bindings and helper functions below) followed by the preset’s translated code. The engine builds the matching pipeline from the same constants — BINDINGS, the group indices, the varying locations — in render/scenes/warp_mesh/shader.rs. Keeping both halves keyed off this one module is what stops the converter and the engine drifting into two incompatible interfaces that fail only at pipeline creation.

No HLSL and no translator is here (ADR-0113): what this module knows is the WGSL surface, which is as much a runtime interface as the C ABI is.

§Why validation happens twice

validate_wgsl runs in milkconv the moment a shader is translated — so an emitter bug is a named conversion failure in Phase 5’s ranking — and again in the preset loader, because a bundle on disk is untrusted text and the boundary rule (validate at the boundary, trust inside) applies to it exactly as it applies to sample rates. A failed compile rejects that preset by name and loads the rest — the directory loader already skips a bad preset per file, so the second check needs no new machinery.

naga itself is not a new dependency: wgpu compiles every shader in this engine through it already, and wgpu::naga re-exports the same version.

Constants§

BINDINGS
The binding roster of the shader surface, in binding order. The names are the WGSL identifiers fragment_prelude declares; the engine’s bind-group layout mirrors this list positionally.
COMP_GROUP
The bind-group slot a converted comp fragment shader uses. The fullscreen vertex prelude binds nothing, so the shader surface is the only group.
QUANTIZE_WGSL
The feedback-field quantizer (ADR-0118), as WGSL — the one text, emitted into every converted module by fragment_prelude and concatenated onto the engine’s own built-in warp fragment by render/scenes/warp_mesh. A transfer function written out twice is a transfer function that drifts.
ROT_MATRICES
How many rot_* matrices the surface carries: the six families MilkDrop declares (s, d, f, vf, uf, rand), four of each. Stored as four vec4 rows per matrix — the shape float4x3 indexes as.
UNIFORM_WGSL
The uniform block, as WGSL. Field-for-field with MilkUniform in render/scenes/warp_mesh/shader.rs — every member is 16-byte data, so the Rust #[repr(C)] layout and the WGSL std140-ish layout agree by construction, and a test naga-parses this text so the two cannot drift silently.
WARP_GROUP
The bind-group slot a converted warp fragment shader uses. Group 0 is the warp pass’s own vertex-stage uniform (the mesh transform), so the shader surface sits beside it.

Functions§

fragment_prelude
The whole fixed half of a converted fragment module: the uniform block, the binding declarations at group, and MilkDrop’s own prelude helpers (lum, GetPixel, GetBlur1..3) under collision-proof rlx_ names.
validate_wgsl
Parse and validate one WGSL module through naga — the same frontend wgpu hands every shader in this engine to, so passing here is passing the real gate rather than a lookalike.