summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-07-12 14:14:53 -0700
committerEric Anholt <[email protected]>2010-07-12 16:07:02 -0700
commit8258a6a2c36c9769428f4525415d6c0d565e588c (patch)
treeeb1c288a2beef46182d9970656058c0020f50aab /src/mesa
parent506880bc32e7bb98fd1896a9b2fe3614abab904f (diff)
ir_to_mesa: Add support for dereferencing matrices from arrays.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
index 8945e9b3b4d..467e335fc4b 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,