diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-11-16 21:28:35 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-11-16 21:28:35 +0000 | 
| commit | 3dedeaa0557f17770f6ab7f163dcdde8e93609b8 (patch) | |
| tree | 7dde0c80c2592aa9091d2ab2249c7e3be7d6452b /src | |
| parent | fa941e4267385427c27b5a35c29156b342cc3868 (diff) | |
Initial implementation work for CAL, RET, and BRA instructions for fragment
programs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/main/config.h | 1 | ||||
| -rw-r--r-- | src/mesa/shader/program_instruction.h | 7 | ||||
| -rw-r--r-- | src/mesa/swrast/s_nvfragprog.c | 53 | 
3 files changed, 60 insertions, 1 deletions
| diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 5a0481328f..13c6281f07 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -198,6 +198,7 @@  #define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */  #define MAX_PROGRAM_MATRICES 8  #define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 +#define MAX_PROGRAM_CALL_DEPTH 8  /*@}*/  /** For GL_ARB_fragment_shader */ diff --git a/src/mesa/shader/program_instruction.h b/src/mesa/shader/program_instruction.h index cdec0ceb2a..ad3a6d4dd4 100644 --- a/src/mesa/shader/program_instruction.h +++ b/src/mesa/shader/program_instruction.h @@ -286,7 +286,7 @@ struct prog_instruction     GLuint CondUpdate:1;     /** -    * If prog_instruction::cc_update is \c GL_TRUE, this value selects the +    * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the      * condition code register that is to be updated.      *      * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition @@ -339,6 +339,11 @@ struct prog_instruction      */     GLuint TexSrcTarget:3;     /*@}*/ + +   /** +    * For BRA and CAL instructions, the location to jump to. +    */ +   GLuint BranchTarget;  }; diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 7a6785b1d2..028ddc0090 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -57,6 +57,9 @@ struct fp_machine     GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4];     GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4];     GLuint CondCodes[4];  /**< COND_* value for x/y/z/w */ + +   GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ +   GLuint StackDepth; /**< Index/ptr to top of CallStack[] */  }; @@ -697,6 +700,37 @@ execute_program( GLcontext *ctx,                 }              }              break; +         case OPCODE_BRA: /* conditional branch */ +            { +               /* NOTE: The return is conditional! */ +               const GLuint swizzle = inst->DstReg.CondSwizzle; +               const GLuint condMask = inst->DstReg.CondMask; +               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { +                  /* take branch */ +                  pc = inst->BranchTarget; +               } +            } +            break; +         case OPCODE_CAL: /* Call subroutine */ +            { +               /* NOTE: The call is conditional! */ +               const GLuint swizzle = inst->DstReg.CondSwizzle; +               const GLuint condMask = inst->DstReg.CondMask; +               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { +                  if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { +                     return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ +                  } +                  machine->CallStack[machine->StackDepth++] = pc + 1; +                  pc = inst->BranchTarget; +               } +            } +            break;           case OPCODE_CMP:              {                 GLfloat a[4], b[4], c[4], result[4]; @@ -1093,6 +1127,22 @@ execute_program( GLcontext *ctx,                 store_vector4( inst, machine, result );              }              break; +         case OPCODE_RET: /* return from subroutine */ +            { +               /* NOTE: The return is conditional! */ +               const GLuint swizzle = inst->DstReg.CondSwizzle; +               const GLuint condMask = inst->DstReg.CondMask; +               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || +                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { +                  if (machine->StackDepth == 0) { +                     return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ +                  } +                  pc = machine->CallStack[--machine->StackDepth]; +               } +            } +            break;           case OPCODE_RFL: /* reflection vector */              {                 GLfloat axis[4], dir[4], result[4], tmpX, tmpW; @@ -1539,6 +1589,9 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,     machine->CondCodes[1] = COND_EQ;     machine->CondCodes[2] = COND_EQ;     machine->CondCodes[3] = COND_EQ; + +   /* init call stack */ +   machine->StackDepth = 0;  } | 
