diff options
author | Ian Romanick <[email protected]> | 2010-08-26 15:49:33 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-09-03 11:55:21 -0700 |
commit | 0f4f8c73644a9cc436500d605413207c44cfb4ee (patch) | |
tree | 73cf01cc929bb23102931f55045401a3909444f1 /src/mesa/program/ir_to_mesa.cpp | |
parent | 53acbd87d712555f9e7a1c304843be7b39641413 (diff) |
ir_to_mesa: Handle loops with loop controls set
The downside of our talloc usage is that we can't really make static
(i.e., not created with new) instances of our IR types. This leads to
a lot of unnecessary dynamic allocation in this patch.
Diffstat (limited to 'src/mesa/program/ir_to_mesa.cpp')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index f0e14b8ece3..839d6f04673 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -882,13 +882,53 @@ ir_to_mesa_visitor::visit(ir_variable *ir) void ir_to_mesa_visitor::visit(ir_loop *ir) { - assert(!ir->from); - assert(!ir->to); - assert(!ir->increment); - assert(!ir->counter); + ir_dereference_variable *counter = NULL; + + if (ir->counter != NULL) + counter = new(ir) ir_dereference_variable(ir->counter); + + if (ir->from != NULL) { + assert(ir->counter != NULL); + + ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); + + a->accept(this); + delete a; + } ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); + + if (ir->to) { + ir_expression *e = + new(ir) ir_expression(ir->cmp, glsl_type::bool_type, + counter, ir->to); + ir_if *if_stmt = new(ir) ir_if(e); + + ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); + + if_stmt->then_instructions.push_tail(brk); + + if_stmt->accept(this); + + delete if_stmt; + delete e; + delete brk; + } + visit_exec_list(&ir->body_instructions, this); + + if (ir->increment) { + ir_expression *e = + new(ir) ir_expression(ir_binop_add, counter->type, + counter, ir->increment); + + ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); + + a->accept(this); + delete a; + delete e; + } + ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); } |