[Mesa-dev] [PATCH] glsl: Expand matrix flip optimization pass to cover more cases.
Iago Toral Quiroga
itoral at igalia.com
Mon Apr 21 04:38:27 PDT 2014
Currently it only considers the cases of gl_ModelViewProjectionMatrix and
gl_TextureMatrix. The same optimization can be done also for
gl_ModelViewMatrix, gl_ProjectionMatrix and the corresponding inverses.
---
src/glsl/opt_flip_matrices.cpp | 118 +++++++++++++++++++++++++++++++----------
1 file changed, 91 insertions(+), 27 deletions(-)
diff --git a/src/glsl/opt_flip_matrices.cpp b/src/glsl/opt_flip_matrices.cpp
index 9044fd6..bf09b78 100644
--- a/src/glsl/opt_flip_matrices.cpp
+++ b/src/glsl/opt_flip_matrices.cpp
@@ -29,8 +29,9 @@
* On some hardware, this is more efficient.
*
* This currently only does the conversion for built-in matrices which
- * already have transposed equivalents. Namely, gl_ModelViewProjectionMatrix
- * and gl_TextureMatrix.
+ * already have transposed equivalents. Namely, gl_ModelViewMatrix,
+ * gl_ProjectionMatrix, gl_ModelViewProjectionMatrix, gl_TextureMatrix and
+ * their inverses.
*/
#include "ir.h"
#include "ir_optimization.h"
@@ -42,18 +43,39 @@ public:
matrix_flipper(exec_list *instructions)
{
progress = false;
+ p_transpose = NULL;
+ p_inv_transpose = NULL;
+ mv_transpose = NULL;
+ mv_inv_transpose = NULL;
mvp_transpose = NULL;
+ mvp_inv_transpose = NULL;
texmat_transpose = NULL;
+ texmat_inv_transpose = NULL;
foreach_list(n, instructions) {
ir_instruction *ir = (ir_instruction *) n;
ir_variable *var = ir->as_variable();
if (!var)
continue;
- if (strcmp(var->name, "gl_ModelViewProjectionMatrixTranspose") == 0)
+
+ if (strcmp(var->name, "gl_ProjectionMatrixTranspose") == 0)
+ p_transpose = var;
+ else if (strcmp(var->name, "gl_ProjectionMatrixInverseTranspose") == 0)
+ p_inv_transpose = var;
+ else if (strcmp(var->name, "gl_ModelViewMatrixTranspose") == 0)
+ mv_transpose = var;
+ else if (strcmp(var->name, "gl_ModelViewMatrixInverseTranspose") == 0)
+ mv_inv_transpose = var;
+ else if (strcmp(var->name,
+ "gl_ModelViewProjectionMatrixTranspose") == 0)
mvp_transpose = var;
- if (strcmp(var->name, "gl_TextureMatrixTranspose") == 0)
+ else if (strcmp(var->name,
+ "gl_ModelViewProjectionMatrixInverseTranspose") == 0)
+ mvp_inv_transpose = var;
+ else if (strcmp(var->name, "gl_TextureMatrixTranspose") == 0)
texmat_transpose = var;
+ else if (strcmp(var->name, "gl_TextureMatrixInverseTranspose") == 0)
+ texmat_inv_transpose = var;
}
}
@@ -62,11 +84,49 @@ public:
bool progress;
private:
+ ir_variable *p_transpose;
+ ir_variable *p_inv_transpose;
+ ir_variable *mv_transpose;
+ ir_variable *mv_inv_transpose;
ir_variable *mvp_transpose;
+ ir_variable *mvp_inv_transpose;
ir_variable *texmat_transpose;
+ ir_variable *texmat_inv_transpose;
};
}
+static void
+transform_operands(ir_expression *ir,
+ ir_variable *mat_var, ir_variable *mat_transpose)
+{
+#ifndef NDEBUG
+ ir_dereference_variable *deref = ir->operands[0]->as_dereference_variable();
+ assert(deref && deref->var == mat_var);
+#endif
+
+ void *mem_ctx = ralloc_parent(ir);
+ ir->operands[0] = ir->operands[1];
+ ir->operands[1] = new(mem_ctx) ir_dereference_variable(mat_transpose);
+}
+
+static void
+transform_operands_texmat(ir_expression *ir,
+ ir_variable *mat_var, ir_variable *mat_transpose)
+{
+ ir_dereference_array *array_ref = ir->operands[0]->as_dereference_array();
+ assert(array_ref != NULL);
+ ir_dereference_variable *var_ref = array_ref->array->as_dereference_variable();
+ assert(var_ref && var_ref->var == mat_var);
+
+ ir->operands[0] = ir->operands[1];
+ ir->operands[1] = array_ref;
+
+ var_ref->var = mat_transpose;
+
+ mat_transpose->data.max_array_access =
+ MAX2(mat_transpose->data.max_array_access, mat_var->data.max_array_access);
+}
+
ir_visitor_status
matrix_flipper::visit_enter(ir_expression *ir)
{
@@ -81,32 +141,36 @@ matrix_flipper::visit_enter(ir_expression *ir)
if (mvp_transpose &&
strcmp(mat_var->name, "gl_ModelViewProjectionMatrix") == 0) {
-#ifndef NDEBUG
- ir_dereference_variable *deref = ir->operands[0]->as_dereference_variable();
- assert(deref && deref->var == mat_var);
-#endif
-
- void *mem_ctx = ralloc_parent(ir);
-
- ir->operands[0] = ir->operands[1];
- ir->operands[1] = new(mem_ctx) ir_dereference_variable(mvp_transpose);
-
+ transform_operands(ir, mat_var, mvp_transpose);
+ progress = true;
+ } else if (mvp_inv_transpose &&
+ strcmp(mat_var->name,
+ "gl_ModelViewProjectionMatrixInverse") == 0) {
+ transform_operands(ir, mat_var, mvp_inv_transpose);
+ progress = true;
+ } else if (p_transpose &&
+ strcmp(mat_var->name, "gl_ProjectionMatrix") == 0) {
+ transform_operands(ir, mat_var, p_transpose);
+ progress = true;
+ } else if (p_inv_transpose &&
+ strcmp(mat_var->name, "gl_ProjectionMatrixInverse") == 0) {
+ transform_operands(ir, mat_var, p_inv_transpose);
+ progress = true;
+ } else if (mv_transpose &&
+ strcmp(mat_var->name, "gl_ModelViewMatrix") == 0) {
+ transform_operands(ir, mat_var, mv_transpose);
+ progress = true;
+ } else if (mv_inv_transpose &&
+ strcmp(mat_var->name, "gl_ModelViewMatrixInverse") == 0) {
+ transform_operands(ir, mat_var, mv_inv_transpose);
progress = true;
} else if (texmat_transpose &&
strcmp(mat_var->name, "gl_TextureMatrix") == 0) {
- ir_dereference_array *array_ref = ir->operands[0]->as_dereference_array();
- assert(array_ref != NULL);
- ir_dereference_variable *var_ref = array_ref->array->as_dereference_variable();
- assert(var_ref && var_ref->var == mat_var);
-
- ir->operands[0] = ir->operands[1];
- ir->operands[1] = array_ref;
-
- var_ref->var = texmat_transpose;
-
- texmat_transpose->data.max_array_access =
- MAX2(texmat_transpose->data.max_array_access, mat_var->data.max_array_access);
-
+ transform_operands_texmat(ir, mat_var, texmat_transpose);
+ progress = true;
+ } else if (texmat_inv_transpose &&
+ strcmp(mat_var->name, "gl_TextureMatrixInverse") == 0) {
+ transform_operands_texmat(ir, mat_var, texmat_inv_transpose);
progress = true;
}
--
1.8.3.2
More information about the mesa-dev
mailing list