16d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt/* 26d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Copyright © 2010 Intel Corporation 36d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * 46d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 56d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * copy of this software and associated documentation files (the "Software"), 66d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * to deal in the Software without restriction, including without limitation 76d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 96d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Software is furnished to do so, subject to the following conditions: 106d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * 116d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * The above copyright notice and this permission notice (including the next 126d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * paragraph) shall be included in all copies or substantial portions of the 136d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Software. 146d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * 156d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * DEALINGS IN THE SOFTWARE. 226d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */ 236d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 246d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt/** 25df883eb1575a740bf91e01cbe2eaa4dbc1f9f154Chad Versace * \file lower_mat_op_to_vec.cpp 266d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * 276d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Breaks matrix operation expressions down to a series of vector operations. 286d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * 296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Generally this is how we have to codegen matrix operations for a 306d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * GPU, so this gives us the chance to constant fold operations on a 316d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * column or row. 326d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */ 336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 346d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt#include "ir.h" 356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt#include "ir_expression_flattening.h" 3624f984f64ae58c274f79eaf9148aea37df67131cEmil Velikov#include "compiler/glsl_types.h" 376d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 3810ef949424809d51c627008bb2feab5a067f8e08Eric Anholtnamespace { 3910ef949424809d51c627008bb2feab5a067f8e08Eric Anholt 406d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtclass ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor { 416d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtpublic: 426d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_mat_op_to_vec_visitor() 436d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt { 446d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt this->made_progress = false; 453c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt this->mem_ctx = NULL; 466d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 476d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 486d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_visitor_status visit_leave(ir_assignment *); 496d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 508fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *get_column(ir_dereference *val, int col); 518fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_rvalue *get_element(ir_dereference *val, int col, int row); 528fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt 538fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt void do_mul_mat_mat(ir_dereference *result, 548fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, ir_dereference *b); 558fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt void do_mul_mat_vec(ir_dereference *result, 568fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, ir_dereference *b); 578fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt void do_mul_vec_mat(ir_dereference *result, 588fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, ir_dereference *b); 598fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt void do_mul_mat_scalar(ir_dereference *result, 608fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, ir_dereference *b); 618fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, 628fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b, bool test_equal); 636d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 643c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt void *mem_ctx; 656d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt bool made_progress; 666d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt}; 676d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 6810ef949424809d51c627008bb2feab5a067f8e08Eric Anholt} /* anonymous namespace */ 6910ef949424809d51c627008bb2feab5a067f8e08Eric Anholt 706d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtstatic bool 716d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtmat_op_to_vec_predicate(ir_instruction *ir) 726d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{ 736d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_expression *expr = ir->as_expression(); 746d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt unsigned int i; 756d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 766d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt if (!expr) 776d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return false; 786d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 796d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt for (i = 0; i < expr->get_num_operands(); i++) { 806d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt if (expr->operands[i]->type->is_matrix()) 816d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return true; 826d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 836d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 846d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return false; 856d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt} 866d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 876d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtbool 886d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtdo_mat_op_to_vec(exec_list *instructions) 896d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{ 906d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_mat_op_to_vec_visitor v; 916d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 926d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt /* Pull out any matrix expression to a separate assignment to a 936d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * temp. This will make our handling of the breakdown to 946d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * operations on the matrix's vector components much easier. 956d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */ 966d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt do_expression_flattening(instructions, mat_op_to_vec_predicate); 976d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 986d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt visit_list_elements(&v, instructions); 996d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 1006d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return v.made_progress; 1016d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt} 1026d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 1036d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtir_rvalue * 1048fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) 10515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{ 1068fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt val = get_column(val, col); 10715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1088fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); 10915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt} 11015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 11183cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanickir_dereference * 1128fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) 1136d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{ 1148fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt val = val->clone(mem_ctx, NULL); 1158fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt 1168fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt if (val->type->is_matrix()) { 1178fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt val = new(mem_ctx) ir_dereference_array(val, 1188fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt new(mem_ctx) ir_constant(row)); 1196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 1206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 1218fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt return val; 1226d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt} 1236d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 12415ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid 1258fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, 1268fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, 1278fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b) 12815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{ 129ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul unsigned b_col, i; 13015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_assignment *assign; 13115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *expr; 13215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 133408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt for (b_col = 0; b_col < b->type->matrix_columns; b_col++) { 13415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt /* first column */ 1353c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt expr = new(mem_ctx) ir_expression(ir_binop_mul, 136408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, 0), 137408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_element(b, b_col, 0)); 13815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 13915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt /* following columns */ 140408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt for (i = 1; i < a->type->matrix_columns; i++) { 14115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *mul_expr; 14215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1433c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, 144408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, i), 145408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_element(b, b_col, i)); 1463c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt expr = new(mem_ctx) ir_expression(ir_binop_add, 14715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt expr, 14815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt mul_expr); 14915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 15015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1514f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); 15215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt base_ir->insert_before(assign); 15315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 15415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt} 15515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 15615ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid 1578fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, 1588fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, 1598fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b) 16015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{ 161ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul unsigned i; 16215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_assignment *assign; 16315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *expr; 16415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 16515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt /* first column */ 1663c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt expr = new(mem_ctx) ir_expression(ir_binop_mul, 167408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, 0), 168408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_element(b, 0, 0)); 16915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 17015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt /* following columns */ 171408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt for (i = 1; i < a->type->matrix_columns; i++) { 17215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *mul_expr; 17315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1743c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, 175408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, i), 176408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_element(b, 0, i)); 177e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); 17815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 17915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1808fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt result = result->clone(mem_ctx, NULL); 1814f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt assign = new(mem_ctx) ir_assignment(result, expr); 18215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt base_ir->insert_before(assign); 18315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt} 18415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 18515ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid 1868fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, 1878fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, 1888fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b) 18915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{ 190ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul unsigned i; 19115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 192408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt for (i = 0; i < b->type->matrix_columns; i++) { 193408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt ir_rvalue *column_result; 19415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *column_expr; 19515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_assignment *column_assign; 19615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 1978fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt column_result = result->clone(mem_ctx, NULL); 198408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); 19915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 2003c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt column_expr = new(mem_ctx) ir_expression(ir_binop_dot, 2018fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt a->clone(mem_ctx, NULL), 202408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(b, i)); 20315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 204408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt column_assign = new(mem_ctx) ir_assignment(column_result, 2054f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt column_expr); 20615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt base_ir->insert_before(column_assign); 20715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 20815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt} 20915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 21015ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid 2118fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, 2128fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, 2138fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b) 21415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{ 215ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul unsigned i; 21615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 217408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt for (i = 0; i < a->type->matrix_columns; i++) { 21815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_expression *column_expr; 21915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt ir_assignment *column_assign; 22015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 2213c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt column_expr = new(mem_ctx) ir_expression(ir_binop_mul, 222408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, i), 2238fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt b->clone(mem_ctx, NULL)); 22415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 225408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt column_assign = new(mem_ctx) ir_assignment(get_column(result, i), 2264f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt column_expr); 22715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt base_ir->insert_before(column_assign); 22815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 22915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt} 23015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt 231120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickvoid 2328fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, 2338fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *a, 2348fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *b, 235120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick bool test_equal) 236120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick{ 237120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick /* This essentially implements the following GLSL: 238120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * 239120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * bool equal(mat4 a, mat4 b) 240120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * { 241120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * return !any(bvec4(a[0] != b[0], 242120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[1] != b[1], 243120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[2] != b[2], 244120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[3] != b[3]); 245120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * } 246120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * 247120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * bool nequal(mat4 a, mat4 b) 248120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * { 249120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * return any(bvec4(a[0] != b[0], 250120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[1] != b[1], 251120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[2] != b[2], 252120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * a[3] != b[3]); 253120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick * } 254120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick */ 255408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt const unsigned columns = a->type->matrix_columns; 256120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick const glsl_type *const bvec_type = 257120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); 258120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 259120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_variable *const tmp_bvec = 260120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec", 261120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_var_temporary); 262120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick this->base_ir->insert_before(tmp_bvec); 263120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 264120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick for (unsigned i = 0; i < columns; i++) { 265120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_expression *const cmp = 266a47fd5c27de2b2d61776faa524f9b7ab1c915cdeEric Anholt new(this->mem_ctx) ir_expression(ir_binop_any_nequal, 267408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(a, i), 268408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(b, i)); 269120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 270120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_dereference *const lhs = 271120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick new(this->mem_ctx) ir_dereference_variable(tmp_bvec); 272120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 273120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_assignment *const assign = 274b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt new(this->mem_ctx) ir_assignment(lhs, cmp, NULL, (1U << i)); 275120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 276120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick this->base_ir->insert_before(assign); 277120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick } 278120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 279e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); 2802268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner uint8_t vec_elems = val->type->vector_elements; 2812268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner ir_expression *any = 2822268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner new(this->mem_ctx) ir_expression(ir_binop_any_nequal, val, 2832268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner new(this->mem_ctx) ir_constant(false, 2842268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner vec_elems)); 285120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 286120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick if (test_equal) 287e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); 288120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 289120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick ir_assignment *const assign = 2904f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any); 291120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick base_ir->insert_before(assign); 292120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick} 293120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 294120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickstatic bool 295120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickhas_matrix_operand(const ir_expression *expr, unsigned &columns) 296120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick{ 297120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick for (unsigned i = 0; i < expr->get_num_operands(); i++) { 298120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick if (expr->operands[i]->type->is_matrix()) { 299120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick columns = expr->operands[i]->type->matrix_columns; 300120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick return true; 301120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick } 302120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick } 303120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 304120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick return false; 305120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick} 306120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 307120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 3086d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtir_visitor_status 309c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholtir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) 3106d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{ 311c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt ir_expression *orig_expr = orig_assign->rhs->as_expression(); 3126d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt unsigned int i, matrix_columns = 1; 3138fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference *op[2]; 3146d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 315c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt if (!orig_expr) 3166d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return visit_continue; 3176d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 318120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick if (!has_matrix_operand(orig_expr, matrix_columns)) 3196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return visit_continue; 3206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 321fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick assert(orig_expr->get_num_operands() <= 2); 322fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick 323d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke mem_ctx = ralloc_parent(orig_assign); 3243c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt 3258fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_dereference_variable *result = 326c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt orig_assign->lhs->as_dereference_variable(); 3278fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt assert(result); 3286d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 3296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt /* Store the expression operands in temps so we can use them 3306d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * multiple times. 3316d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */ 332c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt for (i = 0; i < orig_expr->get_num_operands(); i++) { 3336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_assignment *assign; 334487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt ir_dereference *deref = orig_expr->operands[i]->as_dereference(); 3356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 336487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt /* Avoid making a temporary if we don't need to to avoid aliasing. */ 337487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt if (deref && 338487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt deref->variable_referenced() != result->variable_referenced()) { 339487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt op[i] = deref; 340487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt continue; 341487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt } 342487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt 343487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt /* Otherwise, store the operand in a temporary generally if it's 344487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt * not a dereference. 345487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt */ 3468fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, 3478fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt "mat_op_to_vec", 3488fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt ir_var_temporary); 3498fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt base_ir->insert_before(var); 3506d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 3518fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt /* Note that we use this dereference for the assignment. That means 3528fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt * that others that want to use op[i] have to clone the deref. 3538fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt */ 3548fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt op[i] = new(mem_ctx) ir_dereference_variable(var); 3554f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]); 3566d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt base_ir->insert_before(assign); 3576d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 3586d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 3596d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt /* OK, time to break down this matrix operation. */ 360c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt switch (orig_expr->operation) { 36194f9ed701abe33b854f22577adffc4c7ad45cf18Dave Airlie case ir_unop_d2f: 36294f9ed701abe33b854f22577adffc4c7ad45cf18Dave Airlie case ir_unop_f2d: 363013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt case ir_unop_neg: { 364013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt /* Apply the operation to each column.*/ 365013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt for (i = 0; i < matrix_columns; i++) { 366013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt ir_expression *column_expr; 367013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt ir_assignment *column_assign; 368013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt 369a47fd5c27de2b2d61776faa524f9b7ab1c915cdeEric Anholt column_expr = new(mem_ctx) ir_expression(orig_expr->operation, 370408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(op[0], i)); 371013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt 372408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt column_assign = new(mem_ctx) ir_assignment(get_column(result, i), 3734f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt column_expr); 374013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt assert(column_assign->write_mask != 0); 375013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt base_ir->insert_before(column_assign); 376013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt } 377013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt break; 378013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt } 3796d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt case ir_binop_add: 3806d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt case ir_binop_sub: 3816d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt case ir_binop_div: 38283cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick case ir_binop_mod: { 3836d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt /* For most operations, the matrix version is just going 3846d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * column-wise through and applying the operation to each column 3856d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * if available. 3866d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */ 3876d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt for (i = 0; i < matrix_columns; i++) { 3886d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_expression *column_expr; 3896d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt ir_assignment *column_assign; 3906d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 391c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt column_expr = new(mem_ctx) ir_expression(orig_expr->operation, 392408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(op[0], i), 393408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt get_column(op[1], i)); 3946d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 395408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt column_assign = new(mem_ctx) ir_assignment(get_column(result, i), 3964f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt column_expr); 39783cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick assert(column_assign->write_mask != 0); 3986d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt base_ir->insert_before(column_assign); 3996d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 4006d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt break; 40183cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick } 4026d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt case ir_binop_mul: 403408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt if (op[0]->type->is_matrix()) { 404408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt if (op[1]->type->is_matrix()) { 405408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_mul_mat_mat(result, op[0], op[1]); 406408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt } else if (op[1]->type->is_vector()) { 407408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_mul_mat_vec(result, op[0], op[1]); 40815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } else { 409408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt assert(op[1]->type->is_scalar()); 410408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_mul_mat_scalar(result, op[0], op[1]); 41115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 41215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } else { 413408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt assert(op[1]->type->is_matrix()); 414408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt if (op[0]->type->is_vector()) { 415408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_mul_vec_mat(result, op[0], op[1]); 41615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } else { 417408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt assert(op[0]->type->is_scalar()); 418408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_mul_mat_scalar(result, op[1], op[0]); 41915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 42015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt } 4216d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt break; 422120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 4234dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_all_equal: 4244dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri case ir_binop_any_nequal: 425408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt do_equal_mat_mat(result, op[1], op[0], 4264dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri (orig_expr->operation == ir_binop_all_equal)); 427120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick break; 428120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick 4296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt default: 430c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt printf("FINISHME: Handle matrix operation for %s\n", 431c6e8fd82ea118c66e69e4ad7967faec0715741aaIan Romanick ir_expression_operation_strings[orig_expr->operation]); 4326d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt abort(); 4336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt } 434c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt orig_assign->remove(); 4356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt this->made_progress = true; 4366d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt 4376d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt return visit_continue; 4386d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt} 439