fix some bugs in computation of DDX, DDY commands
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 21 Nov 2003 20:48:16 +0000 (20:48 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 21 Nov 2003 20:48:16 +0000 (20:48 +0000)
src/mesa/swrast/s_nvfragprog.c

index 9445823..919ffbe 100644 (file)
@@ -183,26 +183,24 @@ fetch_vector4( GLcontext *ctx,
 static GLboolean
 fetch_vector4_deriv( const struct fp_src_register *source,
                      const struct sw_span *span,
-                     char xOrY, GLfloat result[4] )
+                     char xOrY, GLint column, GLfloat result[4] )
 {
    GLfloat src[4];
 
    ASSERT(xOrY == 'X' || xOrY == 'Y');
 
-   assert(source->File == PROGRAM_INPUT);
-
    switch (source->Index) {
    case FRAG_ATTRIB_WPOS:
       if (xOrY == 'X') {
          src[0] = 1.0;
          src[1] = 0.0;
-         src[2] = span->dzdx;
+         src[2] = span->dzdx / ctx->DepthMaxF;
          src[3] = span->dwdx;
       }
       else {
          src[0] = 0.0;
          src[1] = 1.0;
-         src[2] = span->dzdy;
+         src[2] = span->dzdy / ctx->DepthMaxF;
          src[3] = span->dwdy;
       }
       break;
@@ -258,17 +256,22 @@ fetch_vector4_deriv( const struct fp_src_register *source,
    case FRAG_ATTRIB_TEX7:
       if (xOrY == 'X') {
          const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
-         src[0] = span->texStepX[u][0] * (1.0F / CHAN_MAXF);
-         src[1] = span->texStepX[u][1] * (1.0F / CHAN_MAXF);
-         src[2] = span->texStepX[u][2] * (1.0F / CHAN_MAXF);
-         src[3] = span->texStepX[u][3] * (1.0F / CHAN_MAXF);
+         /* this is a little tricky - I think I've got it right */
+         const GLfloat invQ = 1.0f / (span->tex[u][3]
+                                      + span->texStepX[u][3] * column);
+         src[0] = span->texStepX[u][0] * invQ;
+         src[1] = span->texStepX[u][1] * invQ;
+         src[2] = span->texStepX[u][2] * invQ;
+         src[3] = span->texStepX[u][3] * invQ;
       }
       else {
          const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
-         src[0] = span->texStepY[u][0] * (1.0F / CHAN_MAXF);
-         src[1] = span->texStepY[u][1] * (1.0F / CHAN_MAXF);
-         src[2] = span->texStepY[u][2] * (1.0F / CHAN_MAXF);
-         src[3] = span->texStepY[u][3] * (1.0F / CHAN_MAXF);
+         /* Tricky, as above, but in Y direction */
+         const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]);
+         src[0] = span->texStepY[u][0] * invQ;
+         src[1] = span->texStepY[u][1] * invQ;
+         src[2] = span->texStepY[u][2] * invQ;
+         src[3] = span->texStepY[u][3] * invQ;
       }
       break;
    default:
@@ -527,6 +530,7 @@ init_machine_deriv( GLcontext *ctx,
    for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
       if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
          GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u];
+         /* XXX perspective-correct interpolation */
          if (xOrY == 'X') {
             tex[0] += span->texStepX[u][0];
             tex[1] += span->texStepX[u][1];
@@ -572,12 +576,11 @@ execute_program( GLcontext *ctx,
    printf("execute fragment program --------------------\n");
 #endif
 
-       /* XXX: This should go someplace else, but it is safe here (and slow!) 
-        *        - karl
-        */
+   /* XXX: This should go someplace else, but it is safe here (and slow!) 
+    *        - karl
+    */
    _mesa_load_state_parameters(ctx, program->Parameters); 
 
-
    for (pc = 0; pc < maxInst; pc++) {
       const struct fp_instruction *inst = program->Instructions + pc;
 
@@ -637,7 +640,7 @@ execute_program( GLcontext *ctx,
             {
                GLfloat a[4], aNext[4], result[4];
                struct fp_machine dMachine;
-               if (!fetch_vector4_deriv(&inst->SrcReg[0], span, 'X', result)) {
+               if (!fetch_vector4_deriv(&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
@@ -662,7 +665,7 @@ execute_program( GLcontext *ctx,
             {
                GLfloat a[4], aNext[4], result[4];
                struct fp_machine dMachine;
-               if (!fetch_vector4_deriv(&inst->SrcReg[0], span, 'Y', result)) {
+               if (!fetch_vector4_deriv(&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);