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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev