summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/shader/prog_execute.c20
-rw-r--r--src/mesa/shader/slang/slang_emit.c6
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 ||