diff options
Diffstat (limited to 'src')
| -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 f0e14b8ece..839d6f0467 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);  } | 
