*** empty log message ***
[mesa.git] / src / mesa / swrast / s_nvfragprog.c
index 127cc4f0b4de50d157916ffbb03de097d3c1d9f1..88a6593aff45fd5dd8f5304f3cd8990fc25a991d 100644 (file)
@@ -391,6 +391,7 @@ store_vector4( const struct fp_instruction *inst,
    const GLboolean clamp = inst->Saturate;
    const GLboolean updateCC = inst->UpdateCondRegister;
    GLfloat *dstReg;
+   GLfloat dummyReg[4];
    GLfloat clampedValue[4];
    const GLboolean *writeMask = dest->WriteMask;
    GLboolean condWriteMask[4];
@@ -402,6 +403,9 @@ store_vector4( const struct fp_instruction *inst,
       case PROGRAM_TEMPORARY:
          dstReg = machine->Temporaries[dest->Index];
          break;
+      case PROGRAM_WRITE_ONLY:
+         dstReg = dummyReg;
+         return;
       default:
          _mesa_problem(NULL, "bad register file in store_vector4(fp)");
          return;
@@ -478,9 +482,11 @@ init_machine_deriv( GLcontext *ctx,
    /* copy existing machine */
    _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine));
 
-   /* Clear temporary registers */
-   _mesa_bzero( (void*) machine->Temporaries,
-               MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+   if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
+      /* Clear temporary registers (undefined for ARB_f_p) */
+      _mesa_bzero( (void*) machine->Temporaries,
+                   MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+   }
 
    /* Add derivatives */
    if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) {
@@ -708,6 +714,10 @@ execute_program( GLcontext *ctx,
                result[0] = result[1] = result[2] = result[3] = 
                   a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
                store_vector4( inst, machine, result );
+#if DEBUG_FRAG
+               printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
+                      result[0], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+#endif
             }
             break;
          case FP_OPCODE_DPH:
@@ -763,7 +773,7 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, result );
             }
             break;
-         case FP_OPCODE_KIL:
+         case FP_OPCODE_KIL_NV: /* NV_f_p only */
             {
                const GLuint *swizzle = inst->DstReg.CondSwizzle;
                const GLuint condMask = inst->DstReg.CondMask;
@@ -775,6 +785,15 @@ execute_program( GLcontext *ctx,
                }
             }
             break;
+         case FP_OPCODE_KIL: /* ARB_f_p only */
+            {
+               GLfloat a[4];
+               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
+               if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
+                  return GL_FALSE;
+               }
+            }
+            break;
          case FP_OPCODE_LG2:  /* log base 2 */
             {
                GLfloat a[4], result[4];
@@ -835,6 +854,12 @@ execute_program( GLcontext *ctx,
                result[2] = MAX2(a[2], b[2]);
                result[3] = MAX2(a[3], b[3]);
                store_vector4( inst, machine, result );
+#if DEBUG_FRAG
+               printf("MAX (%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]);
+#endif
             }
             break;
          case FP_OPCODE_MIN:
@@ -854,6 +879,10 @@ execute_program( GLcontext *ctx,
                GLfloat result[4];
                fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result );
                store_vector4( inst, machine, result );
+#if DEBUG_FRAG
+               printf("MOV (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3]);
+#endif
             }
             break;
          case FP_OPCODE_MUL:
@@ -1131,19 +1160,19 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, result );
             }
             break;
-         case FP_OPCODE_TEX:
+         case FP_OPCODE_TEX: /* Both ARB and NV frag prog */
             /* Texel lookup */
             {
                GLfloat texcoord[4], color[4];
                fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
-               /* XXX: Undo perspective divide from interpolate_texcoords() */
-               fetch_texel( ctx, texcoord,
-                            span->array->lambda[inst->TexSrcUnit][column],
-                            inst->TexSrcUnit, color );
+               /* Note: we pass 0 for LOD.  The ARB extension requires it
+                * while the NV extension says it's implementation dependant.
+                */
+               fetch_texel( ctx, texcoord, 0.0F, inst->TexSrcUnit, color );
                store_vector4( inst, machine, color );
             }
             break;
-         case FP_OPCODE_TXB:
+         case FP_OPCODE_TXB: /* GL_ARB_fragment_program only */
             /* Texel lookup with LOD bias */
             {
                GLfloat texcoord[4], color[4], bias, lambda;
@@ -1159,7 +1188,7 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, color );
             }
             break;
-         case FP_OPCODE_TXD:
+         case FP_OPCODE_TXD: /* GL_NV_fragment_program only */
             /* Texture lookup w/ partial derivatives for LOD */
             {
                GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
@@ -1171,12 +1200,29 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, color );
             }
             break;
-         case FP_OPCODE_TXP:
-            /* Texture lookup w/ perspective divide */
+         case FP_OPCODE_TXP: /* GL_ARB_fragment_program only */
+            /* Texture lookup w/ projective divide */
             {
                GLfloat texcoord[4], color[4];
                fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
-               /* Already did perspective divide in interpolate_texcoords() */
+               texcoord[0] /= texcoord[3];
+               texcoord[1] /= texcoord[3];
+               texcoord[2] /= texcoord[3];
+               /* Note: LOD=0 */
+               fetch_texel( ctx, texcoord, 0.0F, inst->TexSrcUnit, color );
+               store_vector4( inst, machine, color );
+            }
+            break;
+         case FP_OPCODE_TXP_NV: /* GL_NV_fragment_program only */
+            /* Texture lookup w/ projective divide */
+            {
+               GLfloat texcoord[4], color[4];
+               fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
+               if (inst->TexSrcBit != TEXTURE_CUBE_BIT) {
+                  texcoord[0] /= texcoord[3];
+                  texcoord[1] /= texcoord[3];
+                  texcoord[2] /= texcoord[3];
+               }
                fetch_texel( ctx, texcoord,
                             span->array->lambda[inst->TexSrcUnit][column],
                             inst->TexSrcUnit, color );
@@ -1215,9 +1261,9 @@ execute_program( GLcontext *ctx,
                const GLuint *rawBits = (const GLuint *) a;
                fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
                result[0] = (((rawBits[0] >>  0) & 0xff) - 128) / 127.0F;
-               result[0] = (((rawBits[0] >>  8) & 0xff) - 128) / 127.0F;
-               result[0] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
-               result[0] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F;
+               result[1] = (((rawBits[0] >>  8) & 0xff) - 128) / 127.0F;
+               result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
+               result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F;
                store_vector4( inst, machine, result );
             }
             break;
@@ -1227,9 +1273,9 @@ execute_program( GLcontext *ctx,
                const GLuint *rawBits = (const GLuint *) a;
                fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
                result[0] = ((rawBits[0] >>  0) & 0xff) / 255.0F;
-               result[0] = ((rawBits[0] >>  8) & 0xff) / 255.0F;
-               result[0] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
-               result[0] = ((rawBits[0] >> 24) & 0xff) / 255.0F;
+               result[1] = ((rawBits[0] >>  8) & 0xff) / 255.0F;
+               result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
+               result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F;
                store_vector4( inst, machine, result );
             }
             break;
@@ -1281,9 +1327,11 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
    if (ctx->FragmentProgram.CallbackEnabled)
       inputsRead = ~0;
 
-   /* Clear temporary registers */
-   _mesa_bzero(machine->Temporaries,
-               MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+   if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
+      /* Clear temporary registers (undefined for ARB_f_p) */
+      _mesa_bzero(machine->Temporaries,
+                  MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+   }
 
    /* Load input registers */
    if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) {
@@ -1348,10 +1396,18 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
          init_machine(ctx, &ctx->FragmentProgram.Machine,
                       ctx->FragmentProgram.Current, span, i);
 
+#ifdef USE_TCC
+         if (!_swrast_execute_codegen_program(ctx, program, ~0,
+                                             &ctx->FragmentProgram.Machine,
+                                             span, i)) {
+            span->array->mask[i] = GL_FALSE;  /* killed fragment */
+         }
+#else
          if (!execute_program(ctx, program, ~0,
                               &ctx->FragmentProgram.Machine, span, i)) {
             span->array->mask[i] = GL_FALSE;  /* killed fragment */
          }
+#endif
 
          /* Store output registers */
          {