It’s been two weeks since I wrote anything here. First of all, thanks to the two people who took the time to actually write a message to me saying that they enjoy reading what I write here. Your feedback is the main reason I’m continuing to post here. Also thanks to the people who “liked” my previous posts, and to everyone who takes the time to read what I have to say!
If you’ve known me very well at any point in the past 5 months, or read my previous Tumblr posts, you’ve probably heard me talk nonstop about the “GLSL to TGSI translator” I’ve been working on for Mesa. I will try to explain what it is as well as I can, but there’s no way for me to explain it without using some software and 3D graphics terminology.
The GLSL to TGSI translator is part of a compiler. Most compilers are programs that parse code written by a programmer in a language like C++ or Java and convert it to a form called “assembly” that the CPU can execute. But the compiler in Mesa instead parses code in a language called GLSL and converts it to assembly that can be executed on graphics processors (GPUs). It makes sense, since Mesa is an interface for accessing the GPU from an application. Programs that run on GPUs have a special name - shaders.
The shader compiler in Mesa has multiple stages. As input, it takes a shader written by a programmer in a language called GLSL, which has syntax similar to the programming languages C, C++, and Java, among others. This is an example shader written in GLSL:
uniform vec2 args;
void main()
{
bvec2 argsb = bvec2(args);
bvec2 v_true = bvec2(argsb.xx);
bvec2 v_some = bvec2(argsb.xy);
bvec2 v_none = bvec2(argsb.yy);
bool true1 = any(v_true);
bool true2 = any(v_some);
bool false1 = any(v_none);
gl_FragColor = vec4(float(true1), float(true2), float(false1), 0.0);
}
It’s processed by the GLSL compiler, which is primarily developed by Intel employees. Here’s that shader printed out in GLSL IR form:
(
(declare (uniform ) vec2 args)
(declare (out ) vec4 gl_FragColor)
(function main
(signature void
(parameters
)
(
(declare (temporary ) bvec2 vec_ctor)
(assign (xy) (var_ref vec_ctor) (expression bvec2 f2b (var_ref args) ) )
(declare (temporary ) vec4 vec_ctor@5)
(assign (w) (var_ref vec_ctor@5) (constant float (0.000000)) )
(assign (x) (var_ref vec_ctor@5) (expression float b2f (expression bool any (swiz xx (var_ref vec_ctor) )) ) )
(assign (y) (var_ref vec_ctor@5) (expression float b2f (expression bool any (var_ref vec_ctor) ) ) )
(assign (z) (var_ref vec_ctor@5) (expression float b2f (expression bool any (swiz yy (var_ref vec_ctor) )) ) )
(assign (xyzw) (var_ref gl_FragColor) (var_ref vec_ctor@5) )
))
)
)
It’s much more difficult to read and understand, but if you look closely you can see the correlation between it and the shader above.
Now, before the GLSL to TGSI translator, GLSL IR was converted next to a form called Mesa IR, which was designed to be similar to GPU assembly. Or at least what GPU assembly languages were like 5 years ago. Here’s the same shader in Mesa IR:
Mesa IR for linked fragment program 3:
0: SNE TEMP[1].xy, UNIFORM[0].xyyy, CONST[1].xxxx;
1: MOV TEMP[3].w, CONST[1].xxxx;
2: DP2_SAT TEMP[3].x, TEMP[1].xxxx, TEMP[1].xxxx;
3: DP2_SAT TEMP[3].y, TEMP[1].xyyy, TEMP[1].xyyy;
4: DP2_SAT TEMP[3].z, TEMP[1].yyyy, TEMP[1].yyyy;
5: MOV OUTPUT[2], TEMP[3];
6: END
In most drivers, the Mesa IR is then converted to another form called TGSI, which was also designed to be like GPU assembly. The TGSI for our example shader looks like this:
FRAG
PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1
DCL OUT[0], COLOR
DCL CONST[0]
DCL TEMP[0..1]
IMM FLT32 { 0.0000, 0.0000, 0.0000, 0.0000}
0: SNE TEMP[0].xy, CONST[0].xyyy, IMM[0].xxxx
1: MOV TEMP[1].w, IMM[0].xxxx
2: DP2_SAT TEMP[1].x, TEMP[0].xxxx, TEMP[0].xxxx
3: DP2_SAT TEMP[1].y, TEMP[0].xyyy, TEMP[0].xyyy
4: DP2_SAT TEMP[1].z, TEMP[0].yyyy, TEMP[0].yyyy
5: MOV OUT[0], TEMP[1]
6: END
You don’t have to actually understand what it’s doing to notice that Mesa IR and TGSI are very, very similar. And as it turns out, there are features in newer GPUs that are supported by GLSL IR and TGSI but not Mesa IR. The purpose of the GLSL to TGSI translator is to translate GLSL IR directly to TGSI without going the extra step of Mesa IR.
I started by taking the GLSL IR to Mesa IR translator (called ir_to_mesa) and the Mesa IR to TGSI translator (called mesa_to_tgsi) and putting them together. Then I started removing the Mesa IR layer between the two. This was a very involved and gradual process, which happened over about 2 months from April to June. Then I added features that Mesa IR couldn’t support, and incorporated some feedback from Mesa developers. In August, my GLSL to TGSI translator was merged to the master branch of Mesa, making it officially part of Mesa. I still develop and maintain it when the need arises.
That’s all I have for today. Feedback is still appreciated. Also, if you’re curious about anything in this post (or want to make me happy), feel free to use “ask me anything” to ask questions.