diff options
author | Eric Anholt <[email protected]> | 2011-06-24 12:08:56 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-06-29 15:09:47 -0700 |
commit | 8fad8637ef42ccd064a4f90b090d8096ab968e58 (patch) | |
tree | 9d64b0826572f63a6a1d6b213f4e72c7737339c8 /src/glsl | |
parent | 408377aed1dfae30605709fe1a134880a0386aa8 (diff) |
glsl: Make lower_mat_op_to_vec track derefs, not variables.
We were constrained to using temporaries because we were assuming
variables all over. This simplifies things a bit.
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/lower_mat_op_to_vec.cpp | 127 |
1 files changed, 56 insertions, 71 deletions
diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 6d2bc0100f8..fe89802b086 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -45,19 +45,19 @@ public: ir_visitor_status visit_leave(ir_assignment *); - ir_dereference *get_column(ir_variable *var, int col); - ir_rvalue *get_element(ir_variable *var, int col, int row); - - void do_mul_mat_mat(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_mat_vec(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_vec_mat(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_mat_scalar(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_equal_mat_mat(ir_variable *result, ir_variable *a, - ir_variable *b, bool test_equal); + ir_dereference *get_column(ir_dereference *val, int col); + ir_rvalue *get_element(ir_dereference *val, int col, int row); + + void do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, + ir_dereference *b, bool test_equal); void *mem_ctx; bool made_progress; @@ -97,42 +97,30 @@ do_mat_op_to_vec(exec_list *instructions) } ir_rvalue * -ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row) +ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) { - ir_dereference *deref; + val = get_column(val, col); - deref = new(mem_ctx) ir_dereference_variable(var); - - if (var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_array(var, - new(mem_ctx) ir_constant(col)); - } else { - assert(col == 0); - } - - return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1); + return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); } ir_dereference * -ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) +ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) { - ir_dereference *deref; - - if (!var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_variable(var); - } else { - deref = new(mem_ctx) ir_dereference_variable(var); - deref = new(mem_ctx) ir_dereference_array(deref, - new(mem_ctx) ir_constant(row)); + val = val->clone(mem_ctx, NULL); + + if (val->type->is_matrix()) { + val = new(mem_ctx) ir_dereference_array(val, + new(mem_ctx) ir_constant(row)); } - return deref; + return val; } void -ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int b_col, i; ir_assignment *assign; @@ -156,8 +144,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, mul_expr); } - ir_rvalue *result = get_column(result_var, b_col); - assign = new(mem_ctx) ir_assignment(result, + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr, NULL); base_ir->insert_before(assign); @@ -165,9 +152,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; ir_assignment *assign; @@ -188,7 +175,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } - ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); + result = result->clone(mem_ctx, NULL); assign = new(mem_ctx) ir_assignment(result, expr, NULL); @@ -196,9 +183,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; @@ -207,11 +194,11 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, ir_expression *column_expr; ir_assignment *column_assign; - column_result = new(mem_ctx) ir_dereference_variable(result); + column_result = result->clone(mem_ctx, NULL); column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - new(mem_ctx) ir_dereference_variable(a), + a->clone(mem_ctx, NULL), get_column(b, i)); column_assign = new(mem_ctx) ir_assignment(column_result, @@ -222,9 +209,9 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, } void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; @@ -234,7 +221,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, column_expr = new(mem_ctx) ir_expression(ir_binop_mul, get_column(a, i), - new(mem_ctx) ir_dereference_variable(b)); + b->clone(mem_ctx, NULL)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), column_expr, @@ -244,9 +231,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, } void -ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a, - ir_variable *b, +ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b, bool test_equal) { /* This essentially implements the following GLSL: @@ -297,11 +284,8 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, if (test_equal) any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); - ir_rvalue *const result = - new(this->mem_ctx) ir_dereference_variable(result_var); - ir_assignment *const assign = - new(mem_ctx) ir_assignment(result, any, NULL); + new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any, NULL); base_ir->insert_before(assign); } @@ -324,7 +308,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) { ir_expression *orig_expr = orig_assign->rhs->as_expression(); unsigned int i, matrix_columns = 1; - ir_variable *op[2]; + ir_dereference *op[2]; if (!orig_expr) return visit_continue; @@ -336,11 +320,9 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) mem_ctx = ralloc_parent(orig_assign); - ir_dereference_variable *lhs_deref = + ir_dereference_variable *result = orig_assign->lhs->as_dereference_variable(); - assert(lhs_deref); - - ir_variable *result = lhs_deref->var; + assert(result); /* Store the expression operands in temps so we can use them * multiple times. @@ -348,13 +330,16 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; - op[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op[i]); + ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, + "mat_op_to_vec", + ir_var_temporary); + base_ir->insert_before(var); - lhs_deref = new(mem_ctx) ir_dereference_variable(op[i]); - assign = new(mem_ctx) ir_assignment(lhs_deref, + /* Note that we use this dereference for the assignment. That means + * that others that want to use op[i] have to clone the deref. + */ + op[i] = new(mem_ctx) ir_dereference_variable(var); + assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i], NULL); base_ir->insert_before(assign); |