Implement CONT statement.
authorBrian <brian.paul@tungstengraphics.com>
Tue, 2 Oct 2007 22:05:07 +0000 (16:05 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Tue, 2 Oct 2007 22:05:07 +0000 (16:05 -0600)
src/mesa/pipe/tgsi/exec/tgsi_exec.c
src/mesa/pipe/tgsi/exec/tgsi_exec.h

index 4a42238..03720d2 100644 (file)
@@ -57,7 +57,7 @@
 
 /** The execution mask depends on the conditional mask and the loop mask */
 #define UPDATE_EXEC_MASK(MACH) \
-      MACH->ExecMask = MACH->CondMask & MACH->LoopMask
+      MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask
 
 
 #define CHAN_X  0
@@ -2178,14 +2178,19 @@ exec_instruction(
    case TGSI_OPCODE_LOOP:
       /* fall-through (for now) */
    case TGSI_OPCODE_BGNLOOP2:
-      /* push LoopMask */
+      /* push LoopMask and ContMasks */
       assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
       mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
+      assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+      mach->ContStack[mach->ContStackTop++] = mach->ContMask;
       break;
 
    case TGSI_OPCODE_ENDLOOP:
       /* fall-through (for now at least) */
    case TGSI_OPCODE_ENDLOOP2:
+      /* Restore ContMask, but don't pop */
+      assert(mach->ContStackTop > 0);
+      mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
       if (mach->LoopMask) {
          /* repeat loop: jump to instruction just past BGNLOOP */
          *pc = inst->InstructionExtLabel.Label + 1;
@@ -2194,8 +2199,11 @@ exec_instruction(
          /* exit loop: pop LoopMask */
          assert(mach->LoopStackTop > 0);
          mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
-         UPDATE_EXEC_MASK(mach);
+         /* pop ContMask */
+         assert(mach->ContStackTop > 0);
+         mach->ContMask = mach->ContStack[--mach->ContStackTop];
       }
+      UPDATE_EXEC_MASK(mach);
       break;
 
    case TGSI_OPCODE_BRK:
@@ -2206,16 +2214,18 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_CONT:
-      assert (0);
+      /* turn off cont channels for each enabled exec channel */
+      mach->ContMask &= ~mach->ExecMask;
+      /* Todo: if mach->LoopMask == 0, jump to end of loop */
+      UPDATE_EXEC_MASK(mach);
       break;
 
-
    case TGSI_OPCODE_BGNSUB:
       /* no-op */
       break;
 
    case TGSI_OPCODE_ENDSUB:
-      assert( 0 );
+      /* no-op */
       break;
 
    case TGSI_OPCODE_NOISE1:
@@ -2255,9 +2265,12 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
 
    mach->CondMask = 0xf;
    mach->LoopMask = 0xf;
+   mach->ContMask = 0xf;
    mach->ExecMask = 0xf;
+
    assert(mach->CondStackTop == 0);
    assert(mach->LoopStackTop == 0);
+   assert(mach->ContStackTop == 0);
    assert(mach->CallStackTop == 0);
 
    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
index ae5ce8a..e7827ec 100644 (file)
@@ -138,8 +138,9 @@ struct tgsi_exec_machine
    const struct tgsi_interp_coef *InterpCoefs;
 
    /* Conditional execution masks */
-   uint CondMask;
-   uint LoopMask;
+   uint CondMask;  /**< For IF/ELSE/ENDIF */
+   uint LoopMask;  /**< For BGNLOOP/ENDLOOP */
+   uint ContMask;  /**< For loop CONT statements */
    uint ExecMask;  /**< = CondMask & LoopMask */
 
    /** Condition mask stack (for nested conditionals) */
@@ -150,6 +151,10 @@ struct tgsi_exec_machine
    uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
    int LoopStackTop;
 
+   /** Loop continue mask stack (see comments in tgsi_exec.c) */
+   uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
+   int ContStackTop;
+
    uint CallStack[TGSI_EXEC_MAX_CALL_NESTING];
    int CallStackTop;