diff options
author | Brian <[email protected]> | 2007-03-08 09:38:35 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2007-03-08 09:38:35 -0700 |
commit | de8172673e23bad1186553b91a7c22e65d93692a (patch) | |
tree | 98d34048bba510acc26f3e420e1bf52942cdde03 /src/mesa/shader/slang/slang_builtin.c | |
parent | 6ff0a04f7ccc6a7049bccedb3dc52382e854848b (diff) |
Rework matrix-related code.
GLSL matrices are stored in column-major order while GL_ARB_vertex/fragment_program
use row-major. So, need to use STATE_MATRIX_TRANSPOSE for built-in matrices.
Unfortunately, this means that the expression M * V isn't very efficient since we
need to extract the rows out of M. And that's the typical expression for vertex
transformation: gl_ModelViewProjectionMatrix * gl_Position.
Solve this inefficiency by looking for M*V expressions and replacing them
with V*Transpose(M).
Also, add support for GLSL 1.20's MatrixTranspose, Inverse and InverseTranspose
matrices.
Diffstat (limited to 'src/mesa/shader/slang/slang_builtin.c')
-rw-r--r-- | src/mesa/shader/slang/slang_builtin.c | 73 |
1 files changed, 53 insertions, 20 deletions
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index 8ff54c0e569..cba11b472be 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -49,6 +49,42 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, GLuint *swizzleOut, struct gl_program_parameter_list *paramList) { + /* + * NOTE: The ARB_vertex_program extension specified that matrices get + * loaded in registers in row-major order. With GLSL, we want column- + * major order. So, we need to transpose all matrices here... + */ + static const struct { + const char *name; + gl_state_index matrix; + gl_state_index modifier; + } matrices[] = { + { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, + { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ProjectionMatrixTranpose", STATE_PROJECTION_MATRIX, 0 }, + { "gl_ProjectionMatrixInverseTranpose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, + { "gl_ModelViewProjectionMatrixInverseTranpose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_TextureMatrixTranpose", STATE_TEXTURE_MATRIX, 0 }, + { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, + + /* XXX verify these!!! */ + { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "__NormalMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, + + { NULL, 0, 0 } + }; gl_state_index tokens[STATE_LENGTH]; GLuint i; GLboolean isMatrix = GL_FALSE; @@ -58,27 +94,24 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, } *swizzleOut = SWIZZLE_NOOP; - if (strcmp(var, "gl_ModelViewMatrix") == 0) { - tokens[0] = STATE_MODELVIEW_MATRIX; - isMatrix = GL_TRUE; - } - else if (strcmp(var, "gl_ProjectionMatrix") == 0) { - tokens[0] = STATE_PROJECTION_MATRIX; - isMatrix = GL_TRUE; - } - else if (strcmp(var, "gl_ModelViewProjectionMatrix") == 0) { - tokens[0] = STATE_MVP_MATRIX; - isMatrix = GL_TRUE; - } - else if (strcmp(var, "gl_NormalMatrix") == 0) { - tokens[0] = STATE_MODELVIEW_MATRIX; - isMatrix = GL_TRUE; + /* first, look if var is a pre-defined matrix */ + for (i = 0; matrices[i].name; i++) { + if (strcmp(var, matrices[i].name) == 0) { + tokens[0] = matrices[i].matrix; + /* tokens[1], [2] and [3] filled below */ + tokens[4] = matrices[i].modifier; + isMatrix = GL_TRUE; + break; + } } - else if (strcmp(var, "gl_TextureMatrix") == 0) { - tokens[0] = STATE_TEXTURE_MATRIX; - if (index1 >= 0) - tokens[1] = index1; - isMatrix = GL_TRUE; + + if (isMatrix) { + if (tokens[0] == STATE_TEXTURE_MATRIX) { + if (index1 >= 0) { + tokens[1] = index1; + index1 = 0; /* prevent extra addition at end of function */ + } + } } else if (strcmp(var, "gl_DepthRange") == 0) { tokens[0] = STATE_DEPTH_RANGE; |