Merge branch 'dri2'
[mesa.git] / src / mesa / shader / prog_execute.c
index 1b7ed4c5d0e3d6df5d70fc11141cb31ae2405c82..28d195d0ee95393db885dc8c4a0f73eeea7879fd 100644 (file)
@@ -43,7 +43,7 @@
 #include "prog_instruction.h"
 #include "prog_parameter.h"
 #include "prog_print.h"
-#include "slang_library_noise.h"
+#include "shader/slang/slang_library_noise.h"
 
 
 /* See comments below for info about this */
@@ -74,66 +74,30 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
 
 
 
-#if FEATURE_MESA_program_debug
-static struct gl_program_machine *CurrentMachine = NULL;
-
-/**
- * For GL_MESA_program_debug.
- * Return current value (4*GLfloat) of a program register.
- * Called via ctx->Driver.GetFragmentProgramRegister().
- */
-void
-_mesa_get_program_register(GLcontext *ctx, enum register_file file,
-                           GLuint index, GLfloat val[4])
-{
-   if (CurrentMachine) {
-      switch (file) {
-      case PROGRAM_INPUT:
-         if (CurrentMachine->CurProgram->Target == GL_VERTEX_PROGRAM_ARB) {
-            COPY_4V(val, CurrentMachine->VertAttribs[index]);
-         }
-         else {
-            COPY_4V(val,
-                   CurrentMachine->Attribs[index][CurrentMachine->CurElement]);
-         }
-         break;
-      case PROGRAM_OUTPUT:
-         COPY_4V(val, CurrentMachine->Outputs[index]);
-         break;
-      case PROGRAM_TEMPORARY:
-         COPY_4V(val, CurrentMachine->Temporaries[index]);
-         break;
-      default:
-         _mesa_problem(NULL,
-                       "bad register file in _swrast_get_program_register");
-      }
-   }
-}
-#endif /* FEATURE_MESA_program_debug */
-
-
-
 /**
  * Return a pointer to the 4-element float vector specified by the given
  * source register.
  */
 static INLINE const GLfloat *
-get_register_pointer(GLcontext * ctx,
-                     const struct prog_src_register *source,
+get_register_pointer(const struct prog_src_register *source,
                      const struct gl_program_machine *machine)
 {
    if (source->RelAddr) {
       const GLint reg = source->Index + machine->AddressReg[0][0];
-      ASSERT( (source->File == PROGRAM_ENV_PARAM) || 
-        (source->File == PROGRAM_STATE_VAR) );
-      if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
-         return ZeroVec;
-      else if (source->File == PROGRAM_ENV_PARAM)
-         return ctx->VertexProgram.Parameters[reg];
+      if (source->File == PROGRAM_ENV_PARAM)
+         if (reg < 0 || reg >= MAX_PROGRAM_ENV_PARAMS)
+            return ZeroVec;
+         else
+            return machine->EnvParams[reg];
       else {
+         const struct gl_program_parameter_list *params;
          ASSERT(source->File == PROGRAM_LOCAL_PARAM ||
                 source->File == PROGRAM_STATE_VAR);
-         return machine->CurProgram->Parameters->ParameterValues[reg];
+         params = machine->CurProgram->Parameters;
+         if (reg < 0 || reg >= params->NumParameters)
+            return ZeroVec;
+         else
+            return params->ParameterValues[reg];
       }
    }
 
@@ -162,10 +126,7 @@ get_register_pointer(GLcontext * ctx,
 
    case PROGRAM_ENV_PARAM:
       ASSERT(source->Index < MAX_PROGRAM_ENV_PARAMS);
-      if (machine->CurProgram->Target == GL_VERTEX_PROGRAM_ARB)
-         return ctx->VertexProgram.Parameters[source->Index];
-      else
-         return ctx->FragmentProgram.Parameters[source->Index];
+      return machine->EnvParams[source->Index];
 
    case PROGRAM_STATE_VAR:
       /* Fallthrough */
@@ -179,7 +140,7 @@ get_register_pointer(GLcontext * ctx,
       return machine->CurProgram->Parameters->ParameterValues[source->Index];
 
    default:
-      _mesa_problem(ctx,
+      _mesa_problem(NULL,
                     "Invalid input register file %d in get_register_pointer()",
                     source->File);
       return NULL;
@@ -187,16 +148,39 @@ get_register_pointer(GLcontext * ctx,
 }
 
 
+#if FEATURE_MESA_program_debug
+static struct gl_program_machine *CurrentMachine = NULL;
+
+/**
+ * For GL_MESA_program_debug.
+ * Return current value (4*GLfloat) of a program register.
+ * Called via ctx->Driver.GetProgramRegister().
+ */
+void
+_mesa_get_program_register(GLcontext *ctx, enum register_file file,
+                           GLuint index, GLfloat val[4])
+{
+   if (CurrentMachine) {
+      struct prog_src_register src;
+      const GLfloat *reg;
+      src.File = file;
+      src.Index = index;
+      reg = get_register_pointer(&src, CurrentMachine);
+      COPY_4V(val, reg);
+   }
+}
+#endif /* FEATURE_MESA_program_debug */
+
+
 /**
  * Fetch a 4-element float vector from the given source register.
  * Apply swizzling and negating as needed.
  */
 static void
-fetch_vector4(GLcontext * ctx,
-              const struct prog_src_register *source,
+fetch_vector4(const struct prog_src_register *source,
               const struct gl_program_machine *machine, GLfloat result[4])
 {
-   const GLfloat *src = get_register_pointer(ctx, source, machine);
+   const GLfloat *src = get_register_pointer(source, machine);
    ASSERT(src);
 
    if (source->Swizzle == SWIZZLE_NOOP) {
@@ -234,131 +218,74 @@ fetch_vector4(GLcontext * ctx,
    }
 }
 
-#if 0
+
 /**
- * Fetch the derivative with respect to X for the given register.
- * \return GL_TRUE if it was easily computed or GL_FALSE if we
- * need to execute another instance of the program (ugh)!
+ * Fetch the derivative with respect to X or Y for the given register.
+ * XXX this currently only works for fragment program input attribs.
  */
-static GLboolean
+static void
 fetch_vector4_deriv(GLcontext * ctx,
                     const struct prog_src_register *source,
-                    const SWspan * span,
-                    char xOrY, GLint column, GLfloat result[4])
+                    const struct gl_program_machine *machine,
+                    char xOrY, GLfloat result[4])
 {
-   GLfloat src[4];
+   if (source->File == PROGRAM_INPUT && source->Index < machine->NumDeriv) {
+      const GLint col = machine->CurElement;
+      const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3];
+      const GLfloat invQ = 1.0f / w;
+      GLfloat deriv[4];
 
-   ASSERT(xOrY == 'X' || xOrY == 'Y');
-
-   switch (source->Index) {
-   case FRAG_ATTRIB_WPOS:
       if (xOrY == 'X') {
-         src[0] = 1.0;
-         src[1] = 0.0;
-         src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2]
-            / ctx->DrawBuffer->_DepthMaxF;
-         src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+         deriv[0] = machine->DerivX[source->Index][0] * invQ;
+         deriv[1] = machine->DerivX[source->Index][1] * invQ;
+         deriv[2] = machine->DerivX[source->Index][2] * invQ;
+         deriv[3] = machine->DerivX[source->Index][3] * invQ;
       }
       else {
-         src[0] = 0.0;
-         src[1] = 1.0;
-         src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2]
-            / ctx->DrawBuffer->_DepthMaxF;
-         src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3];
-      }
-      break;
-   case FRAG_ATTRIB_COL0:
-   case FRAG_ATTRIB_COL1:
-      if (xOrY == 'X') {
-         src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF);
-         src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF);
-         src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF);
-         src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF);
+         deriv[0] = machine->DerivY[source->Index][0] * invQ;
+         deriv[1] = machine->DerivY[source->Index][1] * invQ;
+         deriv[2] = machine->DerivY[source->Index][2] * invQ;
+         deriv[3] = machine->DerivY[source->Index][3] * invQ;
       }
-      else {
-         src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF);
-         src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF);
-         src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF);
-         src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF);
+
+      result[0] = deriv[GET_SWZ(source->Swizzle, 0)];
+      result[1] = deriv[GET_SWZ(source->Swizzle, 1)];
+      result[2] = deriv[GET_SWZ(source->Swizzle, 2)];
+      result[3] = deriv[GET_SWZ(source->Swizzle, 3)];
+      
+      if (source->NegateBase) {
+         result[0] = -result[0];
+         result[1] = -result[1];
+         result[2] = -result[2];
+         result[3] = -result[3];
       }
-      break;
-   case FRAG_ATTRIB_FOGC:
-      if (xOrY == 'X') {
-         src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF);
-         src[1] = 0.0;
-         src[2] = 0.0;
-         src[3] = 0.0;
+      if (source->Abs) {
+         result[0] = FABSF(result[0]);
+         result[1] = FABSF(result[1]);
+         result[2] = FABSF(result[2]);
+         result[3] = FABSF(result[3]);
       }
-      else {
-         src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF);
-         src[1] = 0.0;
-         src[2] = 0.0;
-         src[3] = 0.0;
+      if (source->NegateAbs) {
+         result[0] = -result[0];
+         result[1] = -result[1];
+         result[2] = -result[2];
+         result[3] = -result[3];
       }
-      break;
-   default:
-      assert(source->Index < FRAG_ATTRIB_MAX);
-      /* texcoord or varying */
-      if (xOrY == 'X') {
-         /* this is a little tricky - I think I've got it right */
-         const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3]
-                                      +
-                                      span->attrStepX[source->Index][3] *
-                                      column);
-         src[0] = span->attrStepX[source->Index][0] * invQ;
-         src[1] = span->attrStepX[source->Index][1] * invQ;
-         src[2] = span->attrStepX[source->Index][2] * invQ;
-         src[3] = span->attrStepX[source->Index][3] * invQ;
-      }
-      else {
-         /* Tricky, as above, but in Y direction */
-         const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3]
-                                      + span->attrStepY[source->Index][3]);
-         src[0] = span->attrStepY[source->Index][0] * invQ;
-         src[1] = span->attrStepY[source->Index][1] * invQ;
-         src[2] = span->attrStepY[source->Index][2] * invQ;
-         src[3] = span->attrStepY[source->Index][3] * invQ;
-      }
-      break;
    }
-
-   result[0] = src[GET_SWZ(source->Swizzle, 0)];
-   result[1] = src[GET_SWZ(source->Swizzle, 1)];
-   result[2] = src[GET_SWZ(source->Swizzle, 2)];
-   result[3] = src[GET_SWZ(source->Swizzle, 3)];
-
-   if (source->NegateBase) {
-      result[0] = -result[0];
-      result[1] = -result[1];
-      result[2] = -result[2];
-      result[3] = -result[3];
-   }
-   if (source->Abs) {
-      result[0] = FABSF(result[0]);
-      result[1] = FABSF(result[1]);
-      result[2] = FABSF(result[2]);
-      result[3] = FABSF(result[3]);
-   }
-   if (source->NegateAbs) {
-      result[0] = -result[0];
-      result[1] = -result[1];
-      result[2] = -result[2];
-      result[3] = -result[3];
+   else {
+      ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);
    }
-   return GL_TRUE;
 }
-#endif
 
 
 /**
  * As above, but only return result[0] element.
  */
 static void
-fetch_vector1(GLcontext * ctx,
-              const struct prog_src_register *source,
+fetch_vector1(const struct prog_src_register *source,
               const struct gl_program_machine *machine, GLfloat result[4])
 {
-   const GLfloat *src = get_register_pointer(ctx, source, machine);
+   const GLfloat *src = get_register_pointer(source, machine);
    ASSERT(src);
 
    result[0] = src[GET_SWZ(source->Swizzle, 0)];
@@ -525,116 +452,23 @@ store_vector4(const struct prog_instruction *inst,
          machine->CondCodes[2] = generate_cc(value[2]);
       if (writeMask & WRITEMASK_W)
          machine->CondCodes[3] = generate_cc(value[3]);
+#if DEBUG_PROG
+      printf("CondCodes=(%s,%s,%s,%s) for:\n",
+             _mesa_condcode_string(machine->CondCodes[0]),
+             _mesa_condcode_string(machine->CondCodes[1]),
+             _mesa_condcode_string(machine->CondCodes[2]),
+             _mesa_condcode_string(machine->CondCodes[3]));
+#endif
    }
 }
 
 
-#if 0
-/**
- * Initialize a new machine state instance from an existing one, adding
- * the partial derivatives onto the input registers.
- * Used to implement DDX and DDY instructions in non-trivial cases.
- */
-static void
-init_machine_deriv(GLcontext * ctx,
-                   const struct gl_program_machine *machine,
-                   const struct gl_fragment_program *program,
-                   const SWspan * span, char xOrY,
-                   struct gl_program_machine *dMachine)
-{
-   GLuint attr;
-
-   ASSERT(xOrY == 'X' || xOrY == 'Y');
-
-   /* copy existing machine */
-   _mesa_memcpy(dMachine, machine, sizeof(struct gl_program_machine));
-
-   if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
-      /* XXX also need to do this when using valgrind */
-      /* Clear temporary registers (undefined for ARB_f_p) */
-      _mesa_bzero((void *) machine->Temporaries,
-                  MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
-   }
-
-   /* Add derivatives */
-   if (program->Base.InputsRead & FRAG_BIT_WPOS) {
-      GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurElement];
-      if (xOrY == 'X') {
-         wpos[0] += 1.0F;
-         wpos[1] += 0.0F;
-         wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2];
-         wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3];
-      }
-      else {
-         wpos[0] += 0.0F;
-         wpos[1] += 1.0F;
-         wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2];
-         wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3];
-      }
-   }
-
-   /* primary, secondary colors */
-   for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) {
-      if (program->Base.InputsRead & (1 << attr)) {
-         GLfloat *col = machine->Attribs[attr][machine->CurElement];
-         if (xOrY == 'X') {
-            col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF);
-            col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF);
-            col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF);
-            col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF);
-         }
-         else {
-            col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF);
-            col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF);
-            col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF);
-            col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF);
-         }
-      }
-   }
-   if (program->Base.InputsRead & FRAG_BIT_FOGC) {
-      GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurElement];
-      if (xOrY == 'X') {
-         fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0];
-      }
-      else {
-         fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0];
-      }
-   }
-   /* texcoord and varying vars */
-   for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) {
-      if (program->Base.InputsRead & (1 << attr)) {
-         GLfloat *val = machine->Attribs[attr][machine->CurElement];
-         /* XXX perspective-correct interpolation */
-         if (xOrY == 'X') {
-            val[0] += span->attrStepX[attr][0];
-            val[1] += span->attrStepX[attr][1];
-            val[2] += span->attrStepX[attr][2];
-            val[3] += span->attrStepX[attr][3];
-         }
-         else {
-            val[0] += span->attrStepY[attr][0];
-            val[1] += span->attrStepY[attr][1];
-            val[2] += span->attrStepY[attr][2];
-            val[3] += span->attrStepY[attr][3];
-         }
-      }
-   }
-
-   /* init condition codes */
-   dMachine->CondCodes[0] = COND_EQ;
-   dMachine->CondCodes[1] = COND_EQ;
-   dMachine->CondCodes[2] = COND_EQ;
-   dMachine->CondCodes[3] = COND_EQ;
-}
-#endif
-
-
 /**
  * Execute the given vertex/fragment program.
  *
- * \param ctx - rendering context
- * \param program - the fragment program to execute
- * \param machine - machine state (register file)
+ * \param ctx  rendering context
+ * \param program  the program to execute
+ * \param machine  machine state (must be initialized)
  * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
  */
 GLboolean
@@ -656,6 +490,13 @@ _mesa_execute_program(GLcontext * ctx,
    CurrentMachine = machine;
 #endif
 
+   if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+      machine->EnvParams = ctx->VertexProgram.Parameters;
+   }
+   else {
+      machine->EnvParams = ctx->FragmentProgram.Parameters;
+   }
+
    for (pc = 0; pc < numInst; pc++) {
       const struct prog_instruction *inst = program->Instructions + pc;
 
@@ -676,7 +517,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_ABS:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] = FABSF(a[0]);
             result[1] = FABSF(a[1]);
             result[2] = FABSF(a[2]);
@@ -687,8 +528,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_ADD:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = a[0] + b[0];
             result[1] = a[1] + b[1];
             result[2] = a[2] + b[2];
@@ -704,7 +545,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_ARL:
          {
             GLfloat t[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, t);
+            fetch_vector4(&inst->SrcReg[0], machine, t);
             machine->AddressReg[0][0] = (GLint) FLOORF(t[0]);
          }
          break;
@@ -736,16 +577,17 @@ _mesa_execute_program(GLcontext * ctx,
             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;    /* XXX - 1 ??? */
+            machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */
+            /* Subtract 1 here since we'll do pc++ at end of for-loop */
+            pc = inst->BranchTarget - 1;
          }
          break;
       case OPCODE_CMP:
          {
             GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
-            fetch_vector4(ctx, &inst->SrcReg[2], machine, c);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
             result[0] = a[0] < 0.0F ? b[0] : c[0];
             result[1] = a[1] < 0.0F ? b[1] : c[1];
             result[2] = a[2] < 0.0F ? b[2] : c[2];
@@ -756,7 +598,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_COS:
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = result[1] = result[2] = result[3]
                = (GLfloat) _mesa_cos(a[0]);
             store_vector4(inst, machine, result);
@@ -764,64 +606,25 @@ _mesa_execute_program(GLcontext * ctx,
          break;
       case OPCODE_DDX:         /* Partial derivative with respect to X */
          {
-#if 0
-            GLfloat a[4], aNext[4], result[4];
-            struct gl_program_machine dMachine;
-            if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X',
-                                     column, result)) {
-               /* This is tricky.  Make a copy of the current machine state,
-                * increment the input registers by the dx or dy partial
-                * derivatives, then re-execute the program up to the
-                * preceeding instruction, then fetch the source register.
-                * Finally, find the difference in the register values for
-                * the original and derivative runs.
-                */
-               fetch_vector4(ctx, &inst->SrcReg[0], machine, program, a);
-               init_machine_deriv(ctx, machine, program, span,
-                                  'X', &dMachine);
-               execute_program(ctx, program, pc, &dMachine, span, column);
-               fetch_vector4(ctx, &inst->SrcReg[0], &dMachine, program,
-                             aNext);
-               result[0] = aNext[0] - a[0];
-               result[1] = aNext[1] - a[1];
-               result[2] = aNext[2] - a[2];
-               result[3] = aNext[3] - a[3];
-            }
+            GLfloat result[4];
+            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+                                'X', result);
             store_vector4(inst, machine, result);
-#else
-            store_vector4(inst, machine, ZeroVec);
-#endif
          }
          break;
       case OPCODE_DDY:         /* Partial derivative with respect to Y */
          {
-#if 0
-            GLfloat a[4], aNext[4], result[4];
-            struct gl_program_machine dMachine;
-            if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y',
-                                     column, result)) {
-               init_machine_deriv(ctx, machine, program, span,
-                                  'Y', &dMachine);
-               fetch_vector4(ctx, &inst->SrcReg[0], machine, program, a);
-               execute_program(ctx, program, pc, &dMachine, span, column);
-               fetch_vector4(ctx, &inst->SrcReg[0], &dMachine, program,
-                             aNext);
-               result[0] = aNext[0] - a[0];
-               result[1] = aNext[1] - a[1];
-               result[2] = aNext[2] - a[2];
-               result[3] = aNext[3] - a[3];
-            }
+            GLfloat result[4];
+            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+                                'Y', result);
             store_vector4(inst, machine, result);
-#else
-            store_vector4(inst, machine, ZeroVec);
-#endif
          }
          break;
       case OPCODE_DP3:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
             store_vector4(inst, machine, result);
             if (DEBUG_PROG) {
@@ -833,8 +636,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_DP4:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
             store_vector4(inst, machine, result);
             if (DEBUG_PROG) {
@@ -847,8 +650,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_DPH:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = result[1] = result[2] = result[3] =
                a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3];
             store_vector4(inst, machine, result);
@@ -857,8 +660,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_DST:         /* Distance vector */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = 1.0F;
             result[1] = a[1] * b[1];
             result[2] = a[2];
@@ -869,7 +672,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_EXP:
          {
             GLfloat t[4], q[4], floor_t0;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, t);
+            fetch_vector1(&inst->SrcReg[0], machine, t);
             floor_t0 = FLOORF(t[0]);
             if (floor_t0 > FLT_MAX_EXP) {
                SET_POS_INFINITY(q[0]);
@@ -895,7 +698,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_EX2:         /* Exponential base 2 */
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = result[1] = result[2] = result[3] =
                (GLfloat) _mesa_pow(2.0, a[0]);
             store_vector4(inst, machine, result);
@@ -904,7 +707,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_FLR:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] = FLOORF(a[0]);
             result[1] = FLOORF(a[1]);
             result[2] = FLOORF(a[2]);
@@ -915,7 +718,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_FRC:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] = a[0] - FLOORF(a[0]);
             result[1] = a[1] - FLOORF(a[1]);
             result[2] = a[2] - FLOORF(a[2]);
@@ -924,13 +727,29 @@ _mesa_execute_program(GLcontext * ctx,
          }
          break;
       case OPCODE_IF:
-         if (eval_condition(machine, inst)) {
-            /* do if-clause (just continue execution) */
-         }
-         else {
-            /* go to the instruction after ELSE or ENDIF */
-            assert(inst->BranchTarget >= 0);
-            pc = inst->BranchTarget - 1;
+         {
+            GLboolean cond;
+            /* eval condition */
+            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+               GLfloat a[4];
+               fetch_vector1(&inst->SrcReg[0], machine, a);
+               cond = (a[0] != 0.0);
+            }
+            else {
+               cond = eval_condition(machine, inst);
+            }
+            if (DEBUG_PROG) {
+               printf("IF: %d\n", cond);
+            }
+            /* do if/else */
+            if (cond) {
+               /* do if-clause (just continue execution) */
+            }
+            else {
+               /* go to the instruction after ELSE or ENDIF */
+               assert(inst->BranchTarget >= 0);
+               pc = inst->BranchTarget - 1;
+            }
          }
          break;
       case OPCODE_ELSE:
@@ -944,7 +763,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_INT:         /* float to int */
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] = (GLfloat) (GLint) a[0];
             result[1] = (GLfloat) (GLint) a[1];
             result[2] = (GLfloat) (GLint) a[2];
@@ -960,7 +779,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_KIL:         /* ARB_f_p only */
          {
             GLfloat a[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
                return GL_FALSE;
             }
@@ -969,7 +788,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_LG2:         /* log base 2 */
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = result[1] = result[2] = result[3] = LOG2(a[0]);
             store_vector4(inst, machine, result);
          }
@@ -978,7 +797,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             const GLfloat epsilon = 1.0F / 256.0F;      /* from NV VP spec */
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             a[0] = MAX2(a[0], 0.0F);
             a[1] = MAX2(a[1], 0.0F);
             /* XXX ARB version clamps a[3], NV version doesn't */
@@ -1007,7 +826,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_LOG:
          {
             GLfloat t[4], q[4], abs_t0;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, t);
+            fetch_vector1(&inst->SrcReg[0], machine, t);
             abs_t0 = FABSF(t[0]);
             if (abs_t0 != 0.0F) {
                /* Since we really can't handle infinite values on VMS
@@ -1044,9 +863,9 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_LRP:
          {
             GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
-            fetch_vector4(ctx, &inst->SrcReg[2], machine, c);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
             result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
             result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
             result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
@@ -1064,9 +883,9 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_MAD:
          {
             GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
-            fetch_vector4(ctx, &inst->SrcReg[2], machine, c);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
             result[0] = a[0] * b[0] + c[0];
             result[1] = a[1] * b[1] + c[1];
             result[2] = a[2] * b[2] + c[2];
@@ -1084,8 +903,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_MAX:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = MAX2(a[0], b[0]);
             result[1] = MAX2(a[1], b[1]);
             result[2] = MAX2(a[2], b[2]);
@@ -1101,8 +920,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_MIN:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = MIN2(a[0], b[0]);
             result[1] = MIN2(a[1], b[1]);
             result[2] = MIN2(a[2], b[2]);
@@ -1113,7 +932,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_MOV:
          {
             GLfloat result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, result);
+            fetch_vector4(&inst->SrcReg[0], machine, result);
             store_vector4(inst, machine, result);
             if (DEBUG_PROG) {
                printf("MOV (%g %g %g %g)\n",
@@ -1124,8 +943,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_MUL:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = a[0] * b[0];
             result[1] = a[1] * b[1];
             result[2] = a[2] * b[2];
@@ -1141,7 +960,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_NOISE1:
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] =
                result[1] =
                result[2] = result[3] = _slang_library_noise1(a[0]);
@@ -1151,7 +970,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_NOISE2:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] =
                result[1] =
                result[2] = result[3] = _slang_library_noise2(a[0], a[1]);
@@ -1161,7 +980,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_NOISE3:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] =
                result[1] =
                result[2] =
@@ -1172,7 +991,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_NOISE4:
          {
             GLfloat a[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             result[0] =
                result[1] =
                result[2] =
@@ -1188,7 +1007,7 @@ _mesa_execute_program(GLcontext * ctx,
             GLhalfNV hx, hy;
             GLuint *rawResult = (GLuint *) result;
             GLuint twoHalves;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             hx = _mesa_float_to_half(a[0]);
             hy = _mesa_float_to_half(a[1]);
             twoHalves = hx | (hy << 16);
@@ -1201,7 +1020,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             GLfloat a[4], result[4];
             GLuint usx, usy, *rawResult = (GLuint *) result;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             a[0] = CLAMP(a[0], 0.0F, 1.0F);
             a[1] = CLAMP(a[1], 0.0F, 1.0F);
             usx = IROUND(a[0] * 65535.0F);
@@ -1215,7 +1034,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             GLfloat a[4], result[4];
             GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
             a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
             a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
@@ -1233,7 +1052,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             GLfloat a[4], result[4];
             GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
             a[0] = CLAMP(a[0], 0.0F, 1.0F);
             a[1] = CLAMP(a[1], 0.0F, 1.0F);
             a[2] = CLAMP(a[2], 0.0F, 1.0F);
@@ -1250,8 +1069,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_POW:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector1(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[1], machine, b);
             result[0] = result[1] = result[2] = result[3]
                = (GLfloat) _mesa_pow(a[0], b[0]);
             store_vector4(inst, machine, result);
@@ -1260,7 +1079,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_RCP:
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             if (DEBUG_PROG) {
                if (a[0] == 0)
                   printf("RCP(0)\n");
@@ -1276,14 +1095,15 @@ _mesa_execute_program(GLcontext * ctx,
             if (machine->StackDepth == 0) {
                return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
             }
-            pc = machine->CallStack[--machine->StackDepth];
+            /* subtract one because of pc++ in the for loop */
+            pc = machine->CallStack[--machine->StackDepth] - 1;
          }
          break;
       case OPCODE_RFL:         /* reflection vector */
          {
             GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, axis);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, dir);
+            fetch_vector4(&inst->SrcReg[0], machine, axis);
+            fetch_vector4(&inst->SrcReg[1], machine, dir);
             tmpW = DOT3(axis, axis);
             tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
             result[0] = tmpX * axis[0] - dir[0];
@@ -1296,7 +1116,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_RSQ:         /* 1 / sqrt() */
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             a[0] = FABSF(a[0]);
             result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
             store_vector4(inst, machine, result);
@@ -1308,7 +1128,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SCS:         /* sine and cos */
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = (GLfloat) _mesa_cos(a[0]);
             result[1] = (GLfloat) _mesa_sin(a[0]);
             result[2] = 0.0;    /* undefined! */
@@ -1319,13 +1139,19 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SEQ:         /* set on equal */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
          }
          break;
       case OPCODE_SFL:         /* set false, operands ignored */
@@ -1337,35 +1163,43 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SGE:         /* set on greater or equal */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
          }
          break;
       case OPCODE_SGT:         /* set on greater */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
             if (DEBUG_PROG) {
-               printf("SGT %g %g %g %g\n",
-                      result[0], result[1], result[2], result[3]);
+               printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
             }
          }
          break;
       case OPCODE_SIN:
          {
             GLfloat a[4], result[4];
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = result[1] = result[2] = result[3]
                = (GLfloat) _mesa_sin(a[0]);
             store_vector4(inst, machine, result);
@@ -1374,37 +1208,55 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SLE:         /* set on less or equal */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
          }
          break;
       case OPCODE_SLT:         /* set on less */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
          }
          break;
       case OPCODE_SNE:         /* set on not equal */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
             result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
             result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
             result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
          }
          break;
       case OPCODE_STR:         /* set true, operands ignored */
@@ -1416,8 +1268,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SUB:
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = a[0] - b[0];
             result[1] = a[1] - b[1];
             result[2] = a[2] - b[2];
@@ -1433,7 +1285,7 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_SWZ:         /* extended swizzle */
          {
             const struct prog_src_register *source = &inst->SrcReg[0];
-            const GLfloat *src = get_register_pointer(ctx, source, machine);
+            const GLfloat *src = get_register_pointer(source, machine);
             GLfloat result[4];
             GLuint i;
             for (i = 0; i < 4; i++) {
@@ -1472,7 +1324,7 @@ _mesa_execute_program(GLcontext * ctx,
             else
 #endif
                lambda = 0.0;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, coord);
+            fetch_vector4(&inst->SrcReg[0], machine, coord);
             machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit,
                                    color);
             if (DEBUG_PROG) {
@@ -1498,7 +1350,7 @@ _mesa_execute_program(GLcontext * ctx,
             else
 #endif
                lambda = 0.0;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, coord);
+            fetch_vector4(&inst->SrcReg[0], machine, coord);
             /* coord[3] is the bias to add to lambda */
             bias = texUnit->LodBias + coord[3];
             if (texUnit->_Current)
@@ -1512,9 +1364,9 @@ _mesa_execute_program(GLcontext * ctx,
          /* Texture lookup w/ partial derivatives for LOD */
          {
             GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, texcoord);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, dtdx);
-            fetch_vector4(ctx, &inst->SrcReg[2], machine, dtdy);
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+            fetch_vector4(&inst->SrcReg[1], machine, dtdx);
+            fetch_vector4(&inst->SrcReg[2], machine, dtdy);
             machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
                                      inst->TexSrcUnit, color);
             store_vector4(inst, machine, color);
@@ -1531,7 +1383,7 @@ _mesa_execute_program(GLcontext * ctx,
             else
 #endif
                lambda = 0.0;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, texcoord);
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
             /* Not so sure about this test - if texcoord[3] is
              * zero, we'd probably be fine except for an ASSERT in
              * IROUND_POS() which gets triggered by the inf values created.
@@ -1557,7 +1409,7 @@ _mesa_execute_program(GLcontext * ctx,
             else
 #endif
                lambda = 0.0;
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, texcoord);
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
             if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
                 texcoord[3] != 0.0) {
                texcoord[0] /= texcoord[3];
@@ -1574,7 +1426,7 @@ _mesa_execute_program(GLcontext * ctx,
             GLfloat a[4], result[4];
             const GLuint *rawBits = (const GLuint *) a;
             GLhalfNV hx, hy;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             hx = rawBits[0] & 0xffff;
             hy = rawBits[0] >> 16;
             result[0] = result[2] = _mesa_half_to_float(hx);
@@ -1587,7 +1439,7 @@ _mesa_execute_program(GLcontext * ctx,
             GLfloat a[4], result[4];
             const GLuint *rawBits = (const GLuint *) a;
             GLushort usx, usy;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             usx = rawBits[0] & 0xffff;
             usy = rawBits[0] >> 16;
             result[0] = result[2] = usx * (1.0f / 65535.0f);
@@ -1599,7 +1451,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             GLfloat a[4], result[4];
             const GLuint *rawBits = (const GLuint *) a;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F;
             result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F;
             result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
@@ -1611,7 +1463,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             GLfloat a[4], result[4];
             const GLuint *rawBits = (const GLuint *) a;
-            fetch_vector1(ctx, &inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[0], machine, a);
             result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F;
             result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F;
             result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
@@ -1622,21 +1474,26 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_XPD:         /* cross product */
          {
             GLfloat a[4], b[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
             result[0] = a[1] * b[2] - a[2] * b[1];
             result[1] = a[2] * b[0] - a[0] * b[2];
             result[2] = a[0] * b[1] - a[1] * b[0];
             result[3] = 1.0;
             store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], b[0], b[1], b[2]);
+            }
          }
          break;
       case OPCODE_X2D:         /* 2-D matrix transform */
          {
             GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
-            fetch_vector4(ctx, &inst->SrcReg[1], machine, b);
-            fetch_vector4(ctx, &inst->SrcReg[2], machine, c);
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
             result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
             result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
             result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
@@ -1648,7 +1505,7 @@ _mesa_execute_program(GLcontext * ctx,
          {
             if (inst->SrcReg[0].File != -1) {
                GLfloat a[4];
-               fetch_vector4(ctx, &inst->SrcReg[0], machine, a);
+               fetch_vector4(&inst->SrcReg[0], machine, a);
                _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
                             a[0], a[1], a[2], a[3]);
             }