fragment program writing to result.depth.z was broken
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 24 Oct 2005 19:28:36 +0000 (19:28 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 24 Oct 2005 19:28:36 +0000 (19:28 +0000)
src/mesa/swrast/s_nvfragprog.c
src/mesa/swrast/s_span.c

index 441d1e8ca7d21ad583361b70771bf72d5dd4f3c4..987163389a197ec3b7c7995e81ad26032fa398c7 100644 (file)
@@ -1390,6 +1390,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
    /* Load input registers */
    if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) {
       GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS];
+      ASSERT(span->arrayMask & SPAN_Z);
       wpos[0] = (GLfloat) span->x + col;
       wpos[1] = (GLfloat) span->y;
       wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF;
@@ -1397,6 +1398,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
    }
    if (inputsRead & (1 << FRAG_ATTRIB_COL0)) {
       GLfloat *col0 = machine->Inputs[FRAG_ATTRIB_COL0];
+      ASSERT(span->arrayMask & SPAN_RGBA);
       col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]);
       col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]);
       col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]);
@@ -1411,6 +1413,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
    }
    if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) {
       GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC];
+      ASSERT(span->arrayMask & SPAN_FOG);
       fogc[0] = span->array->fog[col];
       fogc[1] = 0.0F;
       fogc[2] = 0.0F;
@@ -1479,11 +1482,19 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
             UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]);
          }
          /* depth value */
-         if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR))
-            span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][0] * ctx->DrawBuffer->_DepthMaxF);
+         if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) {
+            const GLfloat depth
+               = ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][2];
+            span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF);
+         }
       }
    }
 
+   if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) {
+      span->interpMask &= ~SPAN_Z;
+      span->arrayMask |= SPAN_Z;
+   }
+
    ctx->_CurrentProgram = 0;
 }
 
index b6d4098f24795e0b3a6dd4875b6beea0bf5fa741..5e26064c64c413900fdba1213fee3244777991ca 100644 (file)
@@ -328,6 +328,7 @@ _swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )
          zval += span->zStep;
       }
    }
+   span->interpMask &= ~SPAN_Z;
    span->arrayMask |= SPAN_Z;
 }
 
@@ -1080,6 +1081,9 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
+   const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled ||
+                                       ctx->FragmentProgram._Active ||
+                                       ctx->ATIFragmentShader._Enabled);
 
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
          span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
@@ -1134,14 +1138,12 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
       interpolate_texcoords(ctx, span);
    }
 
-   /* If the alpha test is enabled, we have to compute the fragment colors
-    * at this point and do the alpha test.
-    * Else, if alpha test is not enabled, we'll try to defer fragment
-    * color computation (by interpolation, texture mapping, fragment program)
-    * until after the Z/stencil tests in the hope that many fragments will
-    * get culled, leaving less work to do.
+   /* This is the normal place to compute the resulting fragment color/Z.
+    * As an optimization, we try to defer this until after Z/stencil
+    * testing in order to try to avoid computing colors that we won't
+    * actually need.
     */
-   if (ctx->Color.AlphaEnabled) {
+   if (!deferredTexture) {
       /* Now we need the rgba array, fill it in if needed */
       if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
          interpolate_colors(ctx, span);
@@ -1153,9 +1155,12 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
          interpolate_fog(ctx, span);
 
       /* Compute fragment colors with fragment program or texture lookups */
-      if (ctx->FragmentProgram._Active)
-         /* XXX interpolate depth values here??? */
+      if (ctx->FragmentProgram._Active) {
+         /* frag prog may need Z values */
+         if (span->interpMask & SPAN_Z)
+            _swrast_span_interpolate_z(ctx, span);
          _swrast_exec_fragment_program( ctx, span );
+      }
       else if (ctx->ATIFragmentShader._Enabled)
          _swrast_exec_fragment_shader( ctx, span );
       else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE))
@@ -1212,11 +1217,11 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
       return;
    }
 
-   /* If the alpha test isn't enabled, we're able to defer computing fragment
-    * colors (by interpolation, texturing, fragment program) until now.
-    * Hopefully, Z/stencil tests culled many of the fragments!
+   /* If we were able to defer fragment color computation to now, there's
+    * a good chance that many fragments will have already been killed by
+    * Z/stencil testing.
     */
-   if (!ctx->Color.AlphaEnabled) {
+   if (deferredTexture) {
       /* Now we need the rgba array, fill it in if needed */
       if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
          interpolate_colors(ctx, span);