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_codegen.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_codegen.c')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index fc000dbf7be..1c037d4304b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2178,6 +2178,48 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) } +/** + * Look for expressions such as: gl_ModelviewMatrix * gl_Vertex + * and replace with this: gl_Vertex * gl_ModelviewMatrixTranpose + * Since matrices are stored in column-major order, the second form of + * multiplication is much more efficient (just 4 dot products). + */ +static void +_slang_check_matmul_optimization(slang_assemble_ctx *A, slang_operation *oper) +{ + static const struct { + const char *orig; + const char *tranpose; + } matrices[] = { + {"gl_ModelViewMatrix", "gl_ModelViewMatrixTranspose"}, + {"gl_ProjectionMatrix", "gl_ProjectionMatrixTranspose"}, + {"gl_ModelViewProjectionMatrix", "gl_ModelViewProjectionMatrixTranspose"}, + {"gl_TextureMatrix", "gl_TextureMatrixTranspose"}, + {"gl_NormalMatrix", "__NormalMatrixTranspose"}, + { NULL, NULL } + }; + + assert(oper->type == SLANG_OPER_MULTIPLY); + if (oper->children[0].type == SLANG_OPER_IDENTIFIER) { + GLuint i; + for (i = 0; matrices[i].orig; i++) { + if (oper->children[0].a_id + == slang_atom_pool_atom(A->atoms, matrices[i].orig)) { + /* + _mesa_printf("Replace %s with %s\n", + matrices[i].orig, matrices[i].tranpose); + */ + assert(oper->children[0].type == SLANG_OPER_IDENTIFIER); + oper->children[0].a_id + = slang_atom_pool_atom(A->atoms, matrices[i].tranpose); + /* finally, swap the operands */ + _slang_operation_swap(&oper->children[0], &oper->children[1]); + return; + } + } + } +} + /** * Generate IR tree for a slang_operation (AST node) @@ -2309,6 +2351,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) { slang_ir_node *n; assert(oper->num_children == 2); + _slang_check_matmul_optimization(A, oper); n = _slang_gen_function_call_name(A, "*", oper, NULL); return n; } |