[Mesa-dev] GLSL IR to TGSI translator

Bryan Cain bryancain3 at gmail.com
Mon Apr 25 23:26:39 PDT 2011


Hi,

In the last week or so, I've been working on a direct translator from
GLSL IR to TGSI that does not go through Mesa IR.  Although it is still
a work in progress, it is now working and very usable.  So before I go
on, here is a link to the branch I've pushed to GitHub:

https://github.com/Plombo/mesa/tree/glsl-130

My main objective with this work is to make GLSL 1.30 support feasible
on Gallium drivers.  From what I understand, it would be difficult or
impossible to implement integer-specific opcodes such as shifting and
bit masking in Mesa IR, since it only supports floats.  TGSI, on the
other hand, doesn't have this problem, and already supports most or all
of the functionality required by GLSL 1.30.

The translator started as a modified version of ir_to_mesa, and that
origin is still obvious from reading the code.  Many parts of ir_to_mesa
are still untouched - glsl_to_tgsi is still a long way away from
eliminating all traces of Mesa IR.  It also contains a significant
amount of code adapted from st_mesa_to_tgsi, but modified to generate
TGSI code from the glsl_to_tgsi_instruction class instead of using Mesa
IR.  (It actually still generates Mesa IR instructions, but that could
be safely removed at some point since the generated Mesa IR instructions
are not actually used for anything.)  I'm planning to push more of the
conversion to TGSI higher up in the stack in the future, although the
remaining remnants of Mesa IR (such as the Mesa IR opcodes used by most
of glsl_to_tgsi) aren't doing any harm.

Since the _mesa_optimize_program function is vital to generating
optimized code with ir_to_mesa, and it is not available when not using
Mesa IR, I've written some new optimization passes for
glsl_to_tgsi_visitor that perform dead code elimination and
consolidation of the temporary register space.  Although they are rather
simple, they do make a huge difference in the quality of the output.  As
an example, here is what it generates for the vertex shader in the
Mandelbrot GLSL demo from the Mesa demos repository:

VERT
DCL IN[0]
DCL IN[1]
DCL IN[2]
DCL OUT[0], POSITION
DCL OUT[1], GENERIC[10]
DCL OUT[2], GENERIC[11]
DCL CONST[0..14]
DCL TEMP[0..4]
IMM FLT32 {    2.0000,     0.0000,    -0.5000,     5.0000}
  0: MUL TEMP[0], CONST[4], IN[0].xxxx
  1: MAD TEMP[0], CONST[5], IN[0].yyyy, TEMP[0]
  2: MAD TEMP[0], CONST[6], IN[0].zzzz, TEMP[0]
  3: MAD TEMP[0], CONST[7], IN[0].wwww, TEMP[0]
  4: MUL TEMP[1].xyz, CONST[12].xyzz, IN[1].xxxx
  5: MAD TEMP[1], CONST[13].xyzz, IN[1].yyyy, TEMP[1].xyzz
  6: MAD TEMP[1], CONST[14].xyzz, IN[1].zzzz, TEMP[1].xyzz
  7: DP3 TEMP[2].x, TEMP[1].xyzz, TEMP[1].xyzz
  8: RSQ TEMP[2].x, TEMP[2].xxxx
  9: MUL TEMP[1].xyz, TEMP[1].xyzz, TEMP[2].xxxx
 10: ADD TEMP[2].xyz, CONST[3].xyzz, -TEMP[0].xyzz
 11: DP3 TEMP[3].x, TEMP[2].xyzz, TEMP[2].xyzz
 12: RSQ TEMP[3].x, TEMP[3].xxxx
 13: MUL TEMP[2].xyz, TEMP[2].xyzz, TEMP[3].xxxx
 14: MOV TEMP[3].xyz, -TEMP[2].xyzx
 15: MOV TEMP[0].xyz, -TEMP[0].xyzx
 16: DP3 TEMP[4].x, TEMP[1].xyzz, TEMP[3].xyzz
 17: MUL TEMP[4].xyz, TEMP[4].xxxx, TEMP[1].xyzz
 18: MUL TEMP[4].xyz, IMM[0].xxxx, TEMP[4].xyzz
 19: ADD TEMP[3].xyz, TEMP[3].xyzz, -TEMP[4].xyzz
 20: DP3 TEMP[4].x, TEMP[0].xyzz, TEMP[0].xyzz
 21: RSQ TEMP[4].x, TEMP[4].xxxx
 22: MUL TEMP[0].xyz, TEMP[0].xyzz, TEMP[4].xxxx
 23: DP3 TEMP[0].x, TEMP[3].xyzz, TEMP[0].xyzz
 24: MAX TEMP[0].x, TEMP[0].xxxx, IMM[0].yyyy
 25: POW TEMP[0].x, TEMP[0].xxxx, CONST[0].xxxx
 26: DP3 TEMP[1].x, TEMP[2].xyzz, TEMP[1].xyzz
 27: MAX TEMP[1].x, TEMP[1].xxxx, IMM[0].yyyy
 28: MUL TEMP[1].x, CONST[1].xxxx, TEMP[1].xxxx
 29: MAD TEMP[0], CONST[2].xxxx, TEMP[0].xxxx, TEMP[1].xxxx
 30: MOV OUT[2], TEMP[0].xxxx
 31: ADD TEMP[0], IN[2], IMM[0].zzzz
 32: MUL TEMP[0].xyz, TEMP[0].xyzz, IMM[0].wwww
 33: MOV OUT[1].xyz, TEMP[0].xyzx
 34: MUL TEMP[0], CONST[8], IN[0].xxxx
 35: MAD TEMP[0], CONST[9], IN[0].yyyy, TEMP[0]
 36: MAD TEMP[0], CONST[10], IN[0].zzzz, TEMP[0]
 37: MAD TEMP[0], CONST[11], IN[0].wwww, TEMP[0]
 38: MOV OUT[0], TEMP[0]
 39: END

Here is the same shader as generated by ir_to_mesa and st_mesa_to_tgsi
in Mesa master:

VERT
DCL IN[0]
DCL IN[1]
DCL IN[2]
DCL OUT[0], POSITION
DCL OUT[1], GENERIC[10]
DCL OUT[2], GENERIC[11]
DCL CONST[0..14]
DCL TEMP[0..4]
IMM FLT32 {    2.0000,     0.0000,    -0.5000,     5.0000}
  0: MUL TEMP[0], CONST[4], IN[0].xxxx
  1: MAD TEMP[0], CONST[5], IN[0].yyyy, TEMP[0]
  2: MAD TEMP[0], CONST[6], IN[0].zzzz, TEMP[0]
  3: MAD TEMP[0], CONST[7], IN[0].wwww, TEMP[0]
  4: MUL TEMP[1].xyz, CONST[12].xyzz, IN[1].xxxx
  5: MAD TEMP[1].xyz, CONST[13].xyzz, IN[1].yyyy, TEMP[1].xyzz
  6: MAD TEMP[1].xyz, CONST[14].xyzz, IN[1].zzzz, TEMP[1].xyzz
  7: DP3 TEMP[2].x, TEMP[1].xyzz, TEMP[1].xyzz
  8: RSQ TEMP[2].x, TEMP[2].xxxx
  9: MUL TEMP[1].xyz, TEMP[1].xyzz, TEMP[2].xxxx
 10: ADD TEMP[2].xyz, CONST[3].xyzz, -TEMP[0].xyzz
 11: DP3 TEMP[3].x, TEMP[2].xyzz, TEMP[2].xyzz
 12: RSQ TEMP[3].x, TEMP[3].xxxx
 13: MUL TEMP[2].xyz, TEMP[2].xyzz, TEMP[3].xxxx
 14: MOV TEMP[3].xyz, -TEMP[2].xyzx
 15: MOV TEMP[0].xyz, -TEMP[0].xyzx
 16: DP3 TEMP[4].x, TEMP[1].xyzz, TEMP[3].xyzz
 17: MUL TEMP[4].xyz, TEMP[4].xxxx, TEMP[1].xyzz
 18: MUL TEMP[4].xyz, IMM[0].xxxx, TEMP[4].xyzz
 19: ADD TEMP[3].xyz, TEMP[3].xyzz, -TEMP[4].xyzz
 20: DP3 TEMP[4].x, TEMP[0].xyzz, TEMP[0].xyzz
 21: RSQ TEMP[4].x, TEMP[4].xxxx
 22: MUL TEMP[0].xyz, TEMP[0].xyzz, TEMP[4].xxxx
 23: DP3 TEMP[0].x, TEMP[3].xyzz, TEMP[0].xyzz
 24: MAX TEMP[0].x, TEMP[0].xxxx, IMM[0].yyyy
 25: POW TEMP[0].x, TEMP[0].xxxx, CONST[0].xxxx
 26: DP3 TEMP[1].x, TEMP[2].xyzz, TEMP[1].xyzz
 27: MAX TEMP[1].x, TEMP[1].xxxx, IMM[0].yyyy
 28: MUL TEMP[1].x, CONST[1].xxxx, TEMP[1].xxxx
 29: MAD OUT[2], CONST[2].xxxx, TEMP[0].xxxx, TEMP[1].xxxx
 30: ADD TEMP[0], IN[2], IMM[0].zzzz
 31: MUL OUT[1].xyz, TEMP[0].xyzx, IMM[0].wwwx
 32: MUL TEMP[0], CONST[8], IN[0].xxxx
 33: MAD TEMP[0], CONST[9], IN[0].yyyy, TEMP[0]
 34: MAD TEMP[0], CONST[10], IN[0].zzzz, TEMP[0]
 35: MAD OUT[0], CONST[11], IN[0].wwww, TEMP[0]
 36: END

With neither the new optimization passes nor _mesa_optimize_program, the
shader has 44 instructions and 40 temporaries.  Both optimized shaders
have only 5 temporaries declared.  For every shader I've tried, in fact,
my register consolidation passes result in exactly the same number of
temporaries being used as when _mesa_optimize_program is used.  In terms
of instruction count, the only optimization visible that is implemented
in Mesa master but not in the GLSL IR to TGSI converter is copy
propagation to output registers, which accounts for 2 of the 3 extra
instructions in the st_glsl_to_tgsi version of the shader.

One current weakness of my new optimization passes is that they don't
optimize code inside of loops as well as they should, although at least
they don't break code that uses loops to the best of my knowledge and
testing.

I'd very much appreciate any comments, feedback, patches, or testing.

Regards,
Bryan



More information about the mesa-dev mailing list