summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-08-05 21:22:36 -0700
committerEric Anholt <[email protected]>2011-08-16 13:04:42 -0700
commit31ef2e3ec2f5837eea0899b4bda5ea15e335a6a2 (patch)
tree091ce6649602649851267eb6f54dd1e84647e247
parentaba9801996f2f524a765df378c234a7645b3a5d1 (diff)
i965/vs: Avoid generating extra moves when setting up large ir_constants.
We were also screwing up the types in the process, and just not emitting moves was easier.
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp77
2 files changed, 28 insertions, 51 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 1619c2e1ef6..3e457fc61aa 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -393,6 +393,8 @@ public:
void emit_block_move(dst_reg *dst, src_reg *src,
const struct glsl_type *type, bool predicated);
+ void emit_constant_values(dst_reg *dst, ir_constant *value);
+
/**
* Emit the correct dot-product instruction for the type of arguments
*/
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 5e2b3e5a5fe..3562779413f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1387,96 +1387,71 @@ vec4_visitor::visit(ir_assignment *ir)
}
}
-
void
-vec4_visitor::visit(ir_constant *ir)
+vec4_visitor::emit_constant_values(dst_reg *dst, ir_constant *ir)
{
if (ir->type->base_type == GLSL_TYPE_STRUCT) {
- src_reg temp_base = src_reg(this, ir->type);
- dst_reg temp = dst_reg(temp_base);
-
- foreach_iter(exec_list_iterator, iter, ir->components) {
- ir_constant *field_value = (ir_constant *)iter.get();
- int size = type_size(field_value->type);
-
- assert(size > 0);
-
- field_value->accept(this);
- src_reg src = this->result;
-
- for (int i = 0; i < (unsigned int)size; i++) {
- emit(BRW_OPCODE_MOV, temp, src);
+ foreach_list(node, &ir->components) {
+ ir_constant *field_value = (ir_constant *)node;
- src.reg_offset++;
- temp.reg_offset++;
- }
+ emit_constant_values(dst, field_value);
}
- this->result = temp_base;
return;
}
if (ir->type->is_array()) {
- src_reg temp_base = src_reg(this, ir->type);
- dst_reg temp = dst_reg(temp_base);
- int size = type_size(ir->type->fields.array);
-
- assert(size > 0);
-
for (unsigned int i = 0; i < ir->type->length; i++) {
- ir->array_elements[i]->accept(this);
- src_reg src = this->result;
- for (int j = 0; j < size; j++) {
- emit(BRW_OPCODE_MOV, temp, src);
-
- src.reg_offset++;
- temp.reg_offset++;
- }
+ emit_constant_values(dst, ir->array_elements[i]);
}
- this->result = temp_base;
return;
}
if (ir->type->is_matrix()) {
- this->result = src_reg(this, ir->type);
- dst_reg dst = dst_reg(this->result);
-
- assert(ir->type->base_type == GLSL_TYPE_FLOAT);
-
for (int i = 0; i < ir->type->matrix_columns; i++) {
for (int j = 0; j < ir->type->vector_elements; j++) {
- dst.writemask = 1 << j;
- emit(BRW_OPCODE_MOV, dst,
+ dst->writemask = 1 << j;
+ dst->type = BRW_REGISTER_TYPE_F;
+
+ emit(BRW_OPCODE_MOV, *dst,
src_reg(ir->value.f[i * ir->type->vector_elements + j]));
}
- dst.reg_offset++;
+ dst->reg_offset++;
}
return;
}
- this->result = src_reg(this, ir->type);
- dst_reg dst = dst_reg(this->result);
-
for (int i = 0; i < ir->type->vector_elements; i++) {
- dst.writemask = 1 << i;
+ dst->writemask = 1 << i;
+ dst->type = brw_type_for_base_type(ir->type);
switch (ir->type->base_type) {
case GLSL_TYPE_FLOAT:
- emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.f[i]));
+ emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.f[i]));
break;
case GLSL_TYPE_INT:
- emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.i[i]));
+ emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.i[i]));
break;
case GLSL_TYPE_UINT:
- emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.u[i]));
+ emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.u[i]));
break;
case GLSL_TYPE_BOOL:
- emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.b[i]));
+ emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.b[i]));
break;
default:
assert(!"Non-float/uint/int/bool constant");
break;
}
}
+ dst->reg_offset++;
+}
+
+void
+vec4_visitor::visit(ir_constant *ir)
+{
+ dst_reg dst = dst_reg(this, ir->type);
+ this->result = src_reg(dst);
+
+ emit_constant_values(&dst, ir);
}
void