diff options
author | Dave Airlie <[email protected]> | 2012-12-10 17:20:05 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2012-12-12 06:57:38 +1000 |
commit | 5cdcd7251a213a448f2bfaf0e7527213c8afa3f5 (patch) | |
tree | f1f46a2efb2129b9e7f4ac13c14ac248a514d715 | |
parent | 2ee0b442528c7d0d0207504e8d315dfb5666afcd (diff) |
glsl_to_tgsi: emit multi-level structs and arrays properly.
This follow the code from the i965 driver, and emits the structs
and arrays recursively.
This fixes an assert in the two UBO tests
fs-struct-copy-complicated and
vs-struct-copy-complicated
These tests now pass on softpipe, with no regressions.
Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index a4df4e5faef..1d96e905c1e 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -442,6 +442,9 @@ public: void merge_registers(void); void renumber_registers(void); + void emit_block_mov(ir_assignment *ir, const struct glsl_type *type, + st_dst_reg *l, st_src_reg *r); + void *mem_ctx; }; @@ -2244,6 +2247,44 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) } void +glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type *type, + st_dst_reg *l, st_src_reg *r) +{ + if (type->base_type == GLSL_TYPE_STRUCT) { + for (unsigned int i = 0; i < type->length; i++) { + emit_block_mov(ir, type->fields.structure[i].type, l, r); + } + return; + } + + if (type->is_array()) { + for (unsigned int i = 0; i < type->length; i++) { + emit_block_mov(ir, type->fields.array, l, r); + } + return; + } + + if (type->is_matrix()) { + const struct glsl_type *vec_type; + + vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, + type->vector_elements, 1); + + for (int i = 0; i < type->matrix_columns; i++) { + emit_block_mov(ir, vec_type, l, r); + } + return; + } + + assert(type->is_scalar() || type->is_vector()); + + r->type = type->base_type; + emit(ir, TGSI_OPCODE_MOV, *l, *r); + l->index++; + r->index++; +} + +void glsl_to_tgsi_visitor::visit(ir_assignment *ir) { st_dst_reg l; @@ -2347,15 +2388,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) new_inst->saturate = inst->saturate; inst->dead_mask = inst->dst.writemask; } else { - for (i = 0; i < type_size(ir->lhs->type); i++) { - if (ir->rhs->type->is_array()) - r.type = ir->rhs->type->element_type()->base_type; - else if (ir->rhs->type->is_record()) - r.type = ir->rhs->type->fields.structure[i].type->base_type; - emit(ir, TGSI_OPCODE_MOV, l, r); - l.index++; - r.index++; - } + emit_block_mov(ir, ir->rhs->type, &l, &r); } } |