iridia-mojo
Lifts the GLSL dialect that MojoShader writes when it translates Shader Model 2 and 3 programs for OpenGL into iridia::Program, a naga module with its interface.
Part of iridia, which turns compiled Direct3D shaders into naga modules. Some engines ship effects compiled to this GLSL (MonoGame's, for one); this crate reads that text back. It is not a GLSL front end: it reads exactly what the translation writes and refuses anything else by name (Error, an iridia::Refusal naming the line). It was written against the effects of an XNA/MonoGame game.
The dialect
#ifdef GL_ESprecision blocks (skipped),#extension GL_OES_standard_derivatives, and#definealiases of registers (expanded);uniform vec4 <stage>_uniforms_vec4[N](the constants: a uniform buffer ofvec4<u32>rows read as floats; an index past the array reads zero),uniform sampler2D,attribute vec4(vertex),varying vec4(vFrontColor,vBackColor,vFogFactor,vTexCoord<n>),const vec4andconst ivec4constants, andvec4andivec4registers;main: assignments to swizzled registers,if/else,reploops of constant count,discard,?:, relative addressing through anivec4register,texture2D,dFdx/dFdy,any,lessThan, constructors and the math functions the translation emits.
A vertex program reads its attributes and writes gl_Position (SystemValue::ClipPosition) and its varyings; a pixel program reads varyings and writes gl_FragColor or gl_FragData[n] (targets 0 to 3). Constants are the constant buffer cb0; a sampler is a texture t<slot> and a sampler s<slot>.
What the caller states
The text does not say what its constants are called, which texture a sampler is bound to or which semantic an attribute carries. Hints names them: the target (opengl effect v12, kept in the program's provenance), the constants' layout, each sampler's slot and the name of what is bound to it, each attribute's semantic and index. Constants that lie past the uniform rows the program declares are left out and the ones that reach past them are cut; the program's notes count both.
What is dropped, and what is refused
MojoShader ends every vertex program with three statements that fix the clip space for OpenGL (posFixup: flip y, half-pixel offset, depth 0..1 to -1..1). They are the API's, not the program's: they are dropped when they are exactly those three, the program keeps Direct3D's clip space (Conventions::D3D), and a note says so. posFixup anywhere else is refused.
Refused by name, with the line: a name declared twice, a number that is not finite, an operation on vectors of different widths (vec2 + vec3, the branches of ?:, the arguments of a function), and anything else the dialect does not have.
Example
use Stage;
use ;
const SOURCE: &str = "uniform vec4 ps_uniforms_vec4[1];
vec4 ps_r0;
#define ps_c0 ps_uniforms_vec4[0]
uniform sampler2D ps_s0;
varying vec4 vTexCoord0;
#define ps_v0 vTexCoord0
#define ps_oC0 gl_FragColor
void main()
{
ps_r0 = texture2D(ps_s0, ps_v0.xy);
ps_oC0 = ps_r0 * ps_c0.xxxx;
}
";
Tests
cargo test -p iridia-mojo needs no game files. tests/lift.rs lifts programs written as MojoShader writes them (a gamma pixel program, a vertex program with the posFixup tail, one with relative addressing, a rep loop, if/else and discard), validates and writes them as WGSL, checks that each damaged program is refused by name, and compares a table of the lifted fixtures against the committed tests/lifted.hashes (the version gate). This crate declares no real-data inputs beyond the scratch folder (tests/inputs/README.md).
Check the examples
From the repository root, cargo test -p iridia-mojo --doc checks the crate documentation, and
cargo build -p iridia-mojo --examples builds its example programs. Examples that read paths need the caller's files; the repository ships no game assets.
Licence
GPL-3.0-or-later.