Proposed fragment assembly syntax

While the syntax flatmush created for fragment shader assembly works well for disassembling, it doesn't work well for assembling due to a couple factors:

  • It's difficult to parse.
  • It doesn't use the standard assembly syntax (i.e. add a, b, c instead of a = b + c).
  • It's difficult to determine which operations are performed in each unit.

In the proposed syntax, an instruction is represented on a single line, except when that line ends with a comma; the new-line character separates instructions. An instruction consists of a series of comma-seperated opcodes, of the form

opcode.unit output input1 input2

The ordering of the opcodes is based upon the positions in the bitfield in the control word, and should be enforced by the assembler to prevent programmer mistakes (since the order is significant).

The units are:

.v - varying fetch
.u - uniform fetch
.t - temporary fetch/store
.v0 - vec4 multiply/other
.s0 - scalar multiply/other
.v1 - vec4 add/other
.s1 - scalar add/other
.s2 - complex scalar & scalar-vec4 multiply

Special opcodes

These are opcodes which don't need a unit specified:

stop (control bit 5)
sync (control bit 6)


The registers are pretty much the same as before. $0 through $5 are general-purpose registers, and the pipeline registers are:

^s0 (note: these have changed to reflect the unit name)
^u (same idea as ^v0 and ^s0)

and any others I forgot.


These should be based on the Direct3D notation - see here and here

In particular, there are 3 instruction modifiers, which are appended to an opcode:

_sat - saturate
_pos - max(0.0, output)
_int - round result to integer

Furthermore, write-masks, swizzling, and input modifiers (negate, absolute value) should use the same syntax as linked to above.


Comments start with a # and go to the end of the line.


Labels consist of an identifier followed by a colon and a newline. The identifier is then used as the target for the branch opcode.

Example shader

This is the same as test.s:

load.u 1, load.v 1 $0

gl_FragColor = texture2D(tex, varying_1.xy);

compiles to:

stop, sync, load.v 0 ^tex_coord, texld_2d 0, mov.v0 ^tex_sampler $0


gl_FragColor = vec4(0, 0, 0, 1);

compiles to:

stop, mov.v0 ^const0.yyyx $0, const0 1.0 0.0 0.0 0.0