[Mesa-dev] [PATCH RFC 0/3] glsl: Rewrite builtin_variables.cpp.
Paul Berry
stereotype441 at gmail.com
Mon Jul 8 10:40:05 PDT 2013
While hunting down some geometry shader bugs last week, I became
concerned about the organization of src/glsl/builtin_variables.cpp,
which is responsible for setting up all the GLSL built-in variables
accessible by a shader, based on the shader type (VS or FS), GLSL
version, desktop/GLES flag, and what extensions are enabled. I was
concerned about the following things:
- The code contains a separate function to handle each GLSL version
and shader type (e.g. generate_130_vs_variables to generate the
vertex shader variables for GLSL 1.30). Since most GLSL versions
contain a superset of the variables from the previous version, these
functions mostly call each other but not always (for example
generate_130_vs_variables calls generate_120_vs_variables, but
generate_140_fs_variables doesn't call generate_130_fs_variables).
As a result, it can be difficult to tell at a glance which set of
GLSL versions a given function applies to. Also, it isn't obvious
which set of functions need to be called to establish the right set
of variables for a given shader type. As a result, until very
recently on my geometry shader branch, uniforms and constants were
missing from geometry shaders.
- Several variables are declared in multiple places. For example
gl_PointCoord (which appears in the fragment shader for every
version of GLSL except desktop GLSL 1.10) has to be declared in
three places: builtin_100ES_fs_variables (which applies only to GLSL
1.00 ES), builtin_300ES_fs_variables (which applies only to GLSL
3.00 ES), and builtin_120_fs_variables (which applies to all desktop
GLSL versions 1.20 and onward).
- With the advent of geometry shaders, the level of code duplication
is going to get a lot worse, because each "varying" variable has to
be declared once for vertex shaders, twice for geometry shaders (as
input and as output), and once for fragment shaders. That's going
to get worse again in the future when we add tessellation control
and tessellation evaluation shaders.
This patch series reworks builtin_variables.cpp so that:
- Each built-in variable is declared in exactly one place, and it is
clear from the surrounding context when each variable is available.
For example, here's the new declaration of gl_PointCoord:
if (state->is_version(120, 100))
add_input(VARYING_SLOT_PNTC, vec2_t, "gl_PointCoord");
- Each varying is declared exactly once. For example here is the
declaration of gl_ClipDistance (this covers the VS output, the GS
input and output, and the FS input):
if (state->is_version(130, 0)) {
ADD_VARYING(VARYING_SLOT_CLIP_DIST0, array(float_t, 0),
"gl_ClipDistance");
}
- The code paths are nearly identical for all shader types and GLSL
versions.
I also made a number of minor changes to improve the readability of
the file. For example I created a class, builtin_variable_generator,
to keep track of the exec_list of instructions and the
_mesa_glsl_parse_state, so that we don't have to pass those explicitly
around with each function call.
In the process of doing the rewrite, I discovered bugs in gl_TexCoord
and gl_MaxUniformVectors. I've made separate patches to fix those
bugs, so that they can be cherry-picked to stable branches if
necessary.
This series is avaiable at branch "builtin-variables-rework" of
https://github.com/stereotype441/mesa.git.
[PATCH RFC 1/3] glsl ES: Fix magnitude of gl_MaxVertexUniformVectors.
[PATCH RFC 2/3] glsl: Make gl_TexCoord compatibility-only
[PATCH RFC 3/3] glsl: Rework builtin_variables.cpp to reduce code duplication.
More information about the mesa-dev
mailing list