diff options
author | Eric Anholt <[email protected]> | 2011-08-05 21:22:36 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-08-16 13:04:42 -0700 |
commit | 31ef2e3ec2f5837eea0899b4bda5ea15e335a6a2 (patch) | |
tree | 091ce6649602649851267eb6f54dd1e84647e247 | |
parent | aba9801996f2f524a765df378c234a7645b3a5d1 (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.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 77 |
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 |