X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Flower_mat_op_to_vec.cpp;h=08cae29fa5d85bca560ca8f33a7d6821502a10af;hb=614944b8975ce9827b26b92f42ad8b48493eb7f0;hp=6d2bc0100f8fefbae77f4331b8eae36d4c36d784;hpb=408377aed1dfae30605709fe1a134880a0386aa8;p=mesa.git diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 6d2bc0100f8..08cae29fa5d 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,44 +97,32 @@ 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; + unsigned b_col, i; ir_assignment *assign; ir_expression *expr; @@ -156,20 +144,17 @@ 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, - expr, - NULL); + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); base_ir->insert_before(assign); } } 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; + unsigned i; ir_assignment *assign; ir_expression *expr; @@ -188,45 +173,42 @@ 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); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + result = result->clone(mem_ctx, NULL); + assign = new(mem_ctx) ir_assignment(result, expr); base_ir->insert_before(assign); } 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; + unsigned i; for (i = 0; i < b->type->matrix_columns; i++) { ir_rvalue *column_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, - column_expr, - NULL); + column_expr); base_ir->insert_before(column_assign); } } 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; + unsigned i; for (i = 0; i < a->type->matrix_columns; i++) { ir_expression *column_expr; @@ -234,19 +216,18 @@ 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, - NULL); + column_expr); base_ir->insert_before(column_assign); } } 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 +278,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); base_ir->insert_before(assign); } @@ -324,7 +302,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,35 +314,43 @@ 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. */ for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; + ir_dereference *deref = orig_expr->operands[i]->as_dereference(); - 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]); + /* Avoid making a temporary if we don't need to to avoid aliasing. */ + if (deref && + deref->variable_referenced() != result->variable_referenced()) { + op[i] = deref; + continue; + } + + /* Otherwise, store the operand in a temporary generally if it's + * not a dereference. + */ + 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, - orig_expr->operands[i], - NULL); + /* 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]); base_ir->insert_before(assign); } /* OK, time to break down this matrix operation. */ switch (orig_expr->operation) { case ir_unop_neg: { - const unsigned mask = (1U << result->type->vector_elements) - 1; - /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { ir_expression *column_expr; @@ -374,9 +360,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) get_column(op[0], i)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), - column_expr, - NULL, - mask); + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } @@ -386,8 +370,6 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) case ir_binop_sub: case ir_binop_div: case ir_binop_mod: { - const unsigned mask = (1U << result->type->vector_elements) - 1; - /* For most operations, the matrix version is just going * column-wise through and applying the operation to each column * if available. @@ -401,9 +383,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) get_column(op[1], i)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), - column_expr, - NULL, - mask); + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); }