summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-01-20 09:27:40 -0700
committerBrian <[email protected]>2007-01-20 09:27:40 -0700
commit5ae49cf3ed53fda6a904d7e90feef78495ae6903 (patch)
tree9314ccc16363edd6a4863788d864a60927dda6da /src/mesa/swrast
parenta3e938b8da07e656775e88bb4b078429723689a2 (diff)
Initial implementation of OPCODE_IF/ELSE/ENDIF instructions.
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_fragprog.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index b842b49616c..813345f4cd1 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -888,6 +888,73 @@ execute_program( GLcontext *ctx,
store_vector4( inst, machine, result );
}
break;
+ case OPCODE_IF:
+ {
+ 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)) {
+ /* do if-clause (just continue execution) */
+ }
+ else {
+ /* do else-clause, or go to endif */
+ GLint ifDepth = 1;
+ do {
+ pc++;
+ inst = program->Base.Instructions + pc;
+ if (inst->Opcode == OPCODE_END) {
+ /* mal-formed program! */
+ abort();
+ }
+ else if (inst->Opcode == OPCODE_IF) {
+ ifDepth++;
+ }
+ else if (inst->Opcode == OPCODE_ELSE) {
+ if (ifDepth == 0) {
+ /* ok, continue normal execution */
+ break;
+ }
+ }
+ else if (inst->Opcode == OPCODE_ENDIF) {
+ ifDepth--;
+ if (ifDepth == 0) {
+ /* ok, continue normal execution */
+ break;
+ }
+ }
+ assert(ifDepth >= 0);
+ } while (pc < maxInst);
+ }
+ }
+ break;
+ case OPCODE_ELSE:
+ {
+ /* find/goto ENDIF */
+ GLint ifDepth = 1;
+ do {
+ pc++;
+ inst = program->Base.Instructions + pc;
+ if (inst->Opcode == OPCODE_END) {
+ /* mal-formed program! */
+ abort();
+ }
+ else if (inst->Opcode == OPCODE_IF) {
+ ifDepth++;
+ }
+ else if (inst->Opcode == OPCODE_ENDIF) {
+ ifDepth--;
+ if (ifDepth == 0)
+ break;
+ }
+ assert(ifDepth >= 0);
+ } while (pc < maxInst);
+ }
+ break;
+ case OPCODE_ENDIF:
+ /* nothing */
+ break;
case OPCODE_INT: /* float to int */
{
GLfloat a[4], result[4];