From 8258a6a2c36c9769428f4525415d6c0d565e588c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 12 Jul 2010 14:14:53 -0700 Subject: ir_to_mesa: Add support for dereferencing matrices from arrays. --- src/mesa/shader/ir_to_mesa.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 8945e9b3b4..467e335fc4 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1099,6 +1099,7 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) ir_constant *index; ir_to_mesa_src_reg src_reg; ir_dereference_variable *deref_var = ir->array->as_dereference_variable(); + int element_size = type_size(ir->type); index = ir->array_index->constant_expression_value(); @@ -1125,7 +1126,7 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) ir->array_index->accept(this); ir_to_mesa_emit_op2(ir, OPCODE_MUL, ir_to_mesa_dst_reg_from_src(index_reg), - this->result, src_reg_for_float(4.0)); + this->result, src_reg_for_float(element_size)); src_reg.reladdr = true; ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, @@ -1136,11 +1137,6 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) return; } - /* By the time we make it to this stage, matrices should be broken down - * to vectors. - */ - assert(!ir->type->is_matrix()); - ir->array->accept(this); src_reg = this->result; @@ -1151,7 +1147,7 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) src_reg.index += index->value.i[0]; } else { if (index) { - src_reg.index += index->value.i[0]; + src_reg.index += index->value.i[0] * element_size; } else { ir_to_mesa_src_reg array_base = this->result; /* Variable index array dereference. It eats the "vec4" of the @@ -1160,12 +1156,24 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) */ ir->array_index->accept(this); + ir_to_mesa_src_reg index_reg; + + if (element_size == 1) { + index_reg = this->result; + } else { + index_reg = get_temp(glsl_type::float_type); + + ir_to_mesa_emit_op2(ir, OPCODE_MUL, + ir_to_mesa_dst_reg_from_src(index_reg), + this->result, src_reg_for_float(element_size)); + } + /* FINISHME: This doesn't work when we're trying to do the LHS * of an assignment. */ src_reg.reladdr = true; ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, - this->result); + index_reg); this->result = get_temp(ir->type); ir_to_mesa_emit_op1(ir, OPCODE_MOV, -- cgit v1.2.3