diff options
author | Eric Anholt <[email protected]> | 2011-08-09 14:35:38 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-08-16 13:04:43 -0700 |
commit | 0b359e3ea015576d0e75bf5ec19aceef337311a3 (patch) | |
tree | 3adf247a0558bce981a6b1651f0a607903d0c2c5 /src/mesa | |
parent | abf843a797876b5e3c5c91dbec25b6553d2cc281 (diff) |
i965/vs: Add support for loops.
This is copied from brw_fs.cpp, instead of doing the temporary IR
generation that ir_to_mesa does. Fixes glsl-vs-loop and friends.
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 53 |
1 files changed, 21 insertions, 32 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index f9447d7c391..e11ec40cc7b 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -700,58 +700,47 @@ vec4_visitor::visit(ir_variable *ir) void vec4_visitor::visit(ir_loop *ir) { - ir_dereference_variable *counter = NULL; - - fail("not yet\n"); + dst_reg counter; /* We don't want debugging output to print the whole body of the * loop as the annotation. */ this->base_ir = NULL; - if (ir->counter != NULL) - counter = new(ir) ir_dereference_variable(ir->counter); - - if (ir->from != NULL) { - assert(ir->counter != NULL); + if (ir->counter != NULL) { + this->base_ir = ir->counter; + ir->counter->accept(this); + counter = *(variable_storage(ir->counter)); - ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); + if (ir->from != NULL) { + this->base_ir = ir->from; + ir->from->accept(this); - a->accept(this); - delete a; + emit(BRW_OPCODE_MOV, counter, this->result); + } } emit(BRW_OPCODE_DO); 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); + this->base_ir = ir->to; + ir->to->accept(this); - if_stmt->accept(this); + vec4_instruction *inst = emit(BRW_OPCODE_CMP, dst_null_d(), + src_reg(counter), this->result); + inst->conditional_mod = brw_conditional_for_comparison(ir->cmp); - delete if_stmt; - delete e; - delete brk; + inst = emit(BRW_OPCODE_BREAK); + inst->predicate = BRW_PREDICATE_NORMAL; } visit_instructions(&ir->body_instructions); - 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; + if (ir->increment) { + this->base_ir = ir->increment; + ir->increment->accept(this); + emit(BRW_OPCODE_ADD, counter, src_reg(counter), this->result); } emit(BRW_OPCODE_WHILE); |