From 2755c798f3cb89fcd4ece16cd740af1cd86a6b99 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 18:01:02 -0700 Subject: BRK instruction's BranchTarget field now used for efficiently breaking out of loops. BRK's BranchTarget field actually points to the top of the loop, not the bottom, since we don't know the later's location yet. In the interpreter, basically do an indirect jump to update the PC. --- src/mesa/swrast/s_fragprog.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index fbd25c0fbf..12c8aee6ea 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -625,7 +625,7 @@ execute_program( GLcontext *ctx, GLuint column ) { const GLuint MAX_EXEC = 10000; - GLint pc, total = 0, loopDepth = 0; + GLint pc, total = 0; if (DEBUG_FRAG) { printf("execute fragment program --------------------\n"); @@ -676,11 +676,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BGNLOOP: /* begin loop */ - loopDepth++; break; case OPCODE_ENDLOOP: /* end loop */ - loopDepth--; - assert(loopDepth >= 0); /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -706,19 +703,18 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BRK: /* break out of loop */ - if (loopDepth == 0) { - _mesa_problem(ctx, "BRK not inside a loop"); - } - /* search for OPCODE_ENDLOOP */ - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_ENDLOOP) { - loopDepth--; - assert(loopDepth >= 0); - break; - } - } while (pc < maxInst); + { + /* The location of the ENDLOOP instruction is saved in the + * BGNLOOP instruction. Get that instruction and jump to + * its BranchTarget + 1. + */ + const struct prog_instruction *loopBeginInst + = program->Base.Instructions + inst->BranchTarget; + ASSERT(loopBeginInst->Opcode == OPCODE_BGNLOOP); + ASSERT(loopBeginInst->BranchTarget >= 0); + /* we'll add one at bottom of for-loop */ + pc = loopBeginInst->BranchTarget; + } break; case OPCODE_CAL: /* Call subroutine */ { -- cgit v1.2.3