diff options
author | Eric Anholt <[email protected]> | 2011-08-05 20:46:03 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-08-16 13:04:42 -0700 |
commit | 979072613139870f12e329e4b483c7f688b40560 (patch) | |
tree | 7cbe9a62261746826ef5baab3c5c39f096c7973e | |
parent | 930afd1774bdcd013bccbd7b5717ae0bb8e3dea3 (diff) |
i965/vs: Handle assignment of structures/arrays/matrices better.
This gets the right types on the instructions, as well as emitting
minimal swizzles/writemasks.
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 69 |
2 files changed, 51 insertions, 21 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 01058243f04..1619c2e1ef6 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -390,7 +390,8 @@ public: void emit_bool_comparison(unsigned int op, dst_reg dst, src_reg src0, src_reg src1); void emit_if_gen6(ir_if *ir); - void emit_block_move(ir_assignment *ir); + void emit_block_move(dst_reg *dst, src_reg *src, + const struct glsl_type *type, bool predicated); /** * 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 27620c47085..4f7763d61bb 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -1269,38 +1269,69 @@ get_assignment_lhs(ir_dereference *ir, vec4_visitor *v) } void -vec4_visitor::emit_block_move(ir_assignment *ir) +vec4_visitor::emit_block_move(dst_reg *dst, src_reg *src, + const struct glsl_type *type, bool predicated) { - ir->rhs->accept(this); - src_reg src = this->result; - - dst_reg dst = get_assignment_lhs(ir->lhs, this); + if (type->base_type == GLSL_TYPE_STRUCT) { + for (unsigned int i = 0; i < type->length; i++) { + emit_block_move(dst, src, type->fields.structure[i].type, predicated); + } + return; + } - if (ir->condition) { - emit_bool_to_cond_code(ir->condition); + if (type->is_array()) { + for (unsigned int i = 0; i < type->length; i++) { + emit_block_move(dst, src, type->fields.array, predicated); + } + return; } - /* FINISHME: This should really set to the correct maximal writemask for each - * FINISHME: component written (in the loops below). - */ - dst.writemask = WRITEMASK_XYZW; + if (type->is_matrix()) { + const struct glsl_type *vec_type; - for (int i = 0; i < type_size(ir->lhs->type); i++) { - vec4_instruction *inst = emit(BRW_OPCODE_MOV, dst, src); - if (ir->condition) - inst->predicate = BRW_PREDICATE_NORMAL; + vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, + type->vector_elements, 1); - dst.reg_offset++; - src.reg_offset++; + for (int i = 0; i < type->matrix_columns; i++) { + emit_block_move(dst, src, vec_type, predicated); + } + return; } + + assert(type->is_scalar() || type->is_vector()); + + dst->type = brw_type_for_base_type(type); + src->type = dst->type; + + dst->writemask = (1 << type->vector_elements) - 1; + + /* Do we need to worry about swizzling a swizzle? */ + assert(src->swizzle = BRW_SWIZZLE_NOOP); + src->swizzle = swizzle_for_size(type->vector_elements); + + vec4_instruction *inst = emit(BRW_OPCODE_MOV, *dst, *src); + if (predicated) + inst->predicate = BRW_PREDICATE_NORMAL; + + dst->reg_offset++; + src->reg_offset++; } void vec4_visitor::visit(ir_assignment *ir) { + dst_reg dst = get_assignment_lhs(ir->lhs, this); + if (!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()) { - emit_block_move(ir); + ir->rhs->accept(this); + src_reg src = this->result; + + if (ir->condition) { + emit_bool_to_cond_code(ir->condition); + } + + emit_block_move(&dst, &src, ir->rhs->type, ir->condition != NULL); return; } @@ -1310,8 +1341,6 @@ vec4_visitor::visit(ir_assignment *ir) ir->rhs->accept(this); src_reg src = this->result; - dst_reg dst = get_assignment_lhs(ir->lhs, this); - int swizzles[4]; int first_enabled_chan = 0; int src_chan = 0; |