summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader/slang/slang_codegen.c
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-03-08 09:38:35 -0700
committerBrian <[email protected]>2007-03-08 09:38:35 -0700
commitde8172673e23bad1186553b91a7c22e65d93692a (patch)
tree98d34048bba510acc26f3e420e1bf52942cdde03 /src/mesa/shader/slang/slang_codegen.c
parent6ff0a04f7ccc6a7049bccedb3dc52382e854848b (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.c43
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;
}