diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/shader/prog_execute.c | 20 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 6 |
2 files changed, 20 insertions, 6 deletions
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 025665a06e5..56d174c6ce5 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -698,12 +698,26 @@ _mesa_execute_program(GLcontext * ctx, case OPCODE_ENDSUB: /* end subroutine */ break; case OPCODE_BRA: /* branch (conditional) */ - /* fall-through */ + if (eval_condition(machine, inst)) { + /* take branch */ + /* Subtract 1 here since we'll do pc++ below */ + pc = inst->BranchTarget - 1; + } + break; case OPCODE_BRK: /* break out of loop (conditional) */ - /* fall-through */ + ASSERT(program->Instructions[inst->BranchTarget].Opcode + == OPCODE_ENDLOOP); + if (eval_condition(machine, inst)) { + /* break out of loop */ + /* pc++ at end of for-loop will put us after the ENDLOOP inst */ + pc = inst->BranchTarget; + } + break; case OPCODE_CONT: /* continue loop (conditional) */ + ASSERT(program->Instructions[inst->BranchTarget].Opcode + == OPCODE_ENDLOOP); if (eval_condition(machine, inst)) { - /* take branch */ + /* continue at ENDLOOP */ /* Subtract 1 here since we'll do pc++ at end of for-loop */ pc = inst->BranchTarget - 1; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 99eb254cee0..e769d0d3ad4 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1814,7 +1814,7 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) /* Done emitting loop code. Now walk over the loop's linked list of * BREAK and CONT nodes, filling in their BranchTarget fields (which - * will point to the ENDLOOP+1 or BGNLOOP instructions, respectively). + * will point to the corresponding ENDLOOP instruction. */ for (ir = n->List; ir; ir = ir->List) { struct prog_instruction *inst = prog->Instructions + ir->InstLocation; @@ -1823,8 +1823,8 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) ir->Opcode == IR_BREAK_IF_TRUE) { assert(inst->Opcode == OPCODE_BRK || inst->Opcode == OPCODE_BRA); - /* go to instruction after end of loop */ - inst->BranchTarget = endInstLoc + 1; + /* go to instruction at end of loop */ + inst->BranchTarget = endInstLoc; } else { assert(ir->Opcode == IR_CONT || |