http://mesa3d.org/shading.html
Shading Language
Support
This page describes the features and status of Mesa's support for the
OpenGL
Shading Language.
Last updated on 15 December 2008.
Contents
GLSL version
1.20 is supported in Mesa 7.3.
Among the features/differences of GLSL 1.20 are:
The
following features of the shading language are not yet supported
in Mesa:
All other
major features of the shading language should function.
These
issues will be addressed/resolved in the future.
- Declare
in function parameters as const whenever
possible. This improves the efficiency of function inlining.
- To
reduce register usage, declare variables within smaller scopes. For
example, the following code:
void main()
{
vec4 a1, a2, b1, b2;
gl_Position = _expression_ using a1, a2.
gl_Color = _expression_ using b1, b2;
}
Can
be rewritten as follows to use half as many registers:
void main()
{
{
vec4 a1, a2;
gl_Position = _expression_ using a1, a2.
}
{
vec4 b1, b2;
gl_Color = _expression_ using b1, b2;
}
}
Alternately, rather than using several float variables, use a vec4
instead. Use swizzling and writemasks to access the components of the
vec4 as floats.
- Use
the built-in library functions whenever possible. For example, instead
of writing this:
float x = 1.0 / sqrt(y);
Write
this:
float x = inversesqrt(y);
- Use
++i when possible as it's more efficient than i++
A
unique stand-alone GLSL compiler driver has been added to Mesa.
The
stand-alone compiler (like a conventional command-line compiler)
is a tool that accepts Shading Language programs and emits low-level
GPU programs.
This
tool is useful for:
After
building Mesa, the glslcompiler can be built by manually running:
cd src/mesa/drivers/glslcompiler
make
Here's
an example of using the compiler to compile a vertex shader and
emit GL_ARB_vertex_program-style instructions:
bin/glslcompiler --debug --numbers --fs progs/glsl/CH06-brick.frag.txt
results
in:
# Fragment Program/Shader
0: RCP TEMP[4].x, UNIFORM[2].xxxx;
1: RCP TEMP[4].y, UNIFORM[2].yyyy;
2: MUL TEMP[3].xy, VARYING[0], TEMP[4];
3: MOV TEMP[1], TEMP[3];
4: MUL TEMP[0].w, TEMP[1].yyyy, CONST[4].xxxx;
5: FRC TEMP[1].z, TEMP[0].wwww;
6: SGT.C TEMP[0].w, TEMP[1].zzzz, CONST[4].xxxx;
7: IF (NE.wwww); # (if false, goto 9);
8: ADD TEMP[1].x, TEMP[1].xxxx, CONST[4].xxxx;
9: ENDIF;
10: FRC TEMP[1].xy, TEMP[1];
11: SGT TEMP[2].xy, UNIFORM[3], TEMP[1];
12: MUL TEMP[1].z, TEMP[2].xxxx, TEMP[2].yyyy;
13: LRP TEMP[0], TEMP[1].zzzz, UNIFORM[0], UNIFORM[1];
14: MUL TEMP[0].xyz, TEMP[0], VARYING[1].xxxx;
15: MOV OUTPUT[0].xyz, TEMP[0];
16: MOV OUTPUT[0].w, CONST[4].yyyy;
17: END
Note
that some shading language constructs (such as uniform and varying
variables) aren't expressible in ARB or NV-style programs.
Therefore, the resulting output is not always legal by definition of
those program languages.
Also
note that this compiler driver is still under development.
Over time, the correctness of the GPU programs, with respect to the ARB
and NV languagues, should improve.
The
source code for Mesa's shading language compiler is in the
src/mesa/shader/slang/ directory.
The
compiler follows a fairly standard design and basically works as
follows:
- The input string is tokenized (see grammar.c)
and parsed
(see slang_compiler_*.c) to produce an Abstract Syntax Tree (AST).
The nodes in this tree are slang_operation structures
(see slang_compile_operation.h).
The nodes are decorated with symbol table, scoping and datatype
information.
- The AST is converted into an Intermediate
representation (IR) tree
(see the slang_codegen.c file).
The IR nodes represent basic GPU instructions, like add, dot product,
move, etc. The IR tree is mostly a binary tree, but a few nodes have
three or four
children.
In principle, the IR tree could be executed by doing an in-order
traversal.
- The IR tree is traversed in-order to emit code
(see slang_emit.c).
This is also when registers are allocated to store variables and temps.
- In the future, a pattern-matching code
generator-generator may be
used for code generation.
Programs such as L-BURG (Bottom-Up Rewrite Generator) and Twig look for
patterns in IR trees, compute weights for subtrees and use the weights
to select the best instructions to represent the sub-tree.
- The emitted GPU instructions (see
prog_instruction.h) are stored in a
gl_program object (see mtypes.h).
- When a fragment shader and vertex shader are
linked (see slang_link.c)
the varying vars are matched up, uniforms are merged, and vertex
attributes are resolved (rewriting instructions as needed).
The
final vertex and fragment programs may be interpreted in software
(see prog_execute.c) or translated into a specific hardware
architecture
(see drivers/dri/i915/i915_fragprog.c for example).
Internally,
there are several options that control the compiler's code
generation and instruction selection.
These options are seen in the gl_shader_state struct and may be set
by the device driver to indicate its preferences:
struct gl_shader_state
{
...
/** Driver-selectable options: */
GLboolean EmitHighLevelInstructions;
GLboolean EmitCondCodes;
GLboolean EmitComments;
};
A Glean test has
been create to exercise the GLSL compiler.
The glsl1 test runs over 170 sub-tests to check that the
language
features and built-in functions work properly.
This test should be run frequently while working on the compiler to
catch
regressions.
The test coverage is reasonably broad and complete but additional tests
should be added.