fix color interpolation problem reported on VMS
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 15 Nov 2005 15:08:03 +0000 (15:08 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 15 Nov 2005 15:08:03 +0000 (15:08 +0000)
src/mesa/swrast/s_tritemp.h

index 93454346bd5f792daf11140e6b65a08da16787bc..d4c9fdd7cb9f0520247ddd4645cdecc1afba18a4 100644 (file)
 #endif
 
 
+
+/*
+ * Some code we unfortunately need to prevent negative interpolated colors.
+ */
+#ifndef CLAMP_INTERPOLANT
+#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)           \
+do {                                                           \
+   GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;   \
+   if (endVal < 0) {                                           \
+      span.CHANNEL -= endVal;                                  \
+   }                                                           \
+   if (span.CHANNEL < 0) {                                     \
+      span.CHANNEL = 0;                                                \
+   }                                                           \
+} while (0)
+#endif
+
+
 static void NAME(GLcontext *ctx, const SWvertex *v0,
                                  const SWvertex *v1,
                                  const SWvertex *v2 )
@@ -304,6 +322,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       oneOverArea = 1.0F / area;
    }
 
+
    span.facing = ctx->_Facing; /* for 2-sided stencil test */
 
    /* Edge setup.  For a triangle strip these could be reused... */
@@ -510,7 +529,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif /* INTERP_ALPHA */
       }
       else {
-         ASSERT (ctx->Light.ShadeModel == GL_FLAT);
+         ASSERT(ctx->Light.ShadeModel == GL_FLAT);
          span.interpMask |= SPAN_FLAT;
          span.drdx = span.drdy = 0.0F;
          span.dgdx = span.dgdy = 0.0F;
@@ -903,7 +922,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                }
                else {
-                  ASSERT (ctx->Light.ShadeModel == GL_FLAT);
+                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 #  if CHAN_TYPE == GL_FLOAT
                   rLeft = v2->color[RCOMP];
                   gLeft = v2->color[GCOMP];
@@ -925,7 +944,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #    endif
 #  endif
                }
-#endif
+#endif /* INTERP_RGB */
+
 
 #ifdef INTERP_SPEC
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
@@ -946,6 +966,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                }
                else {
+                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 #if  CHAN_TYPE == GL_FLOAT
                   srLeft = v2->specular[RCOMP];
                   sgLeft = v2->specular[GCOMP];
@@ -967,6 +988,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   diOuter = SignedFloatToFixed(didy + dxOuter * didx);
                }
                else {
+                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
                   iLeft = FloatToFixed(v2->index);
                   diOuter = 0;
                }
@@ -1114,77 +1136,29 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                )
 #endif
 
-               if (span.end > 1) {
-                  /* Under rare circumstances, we might have to fudge the
-                   * colors. XXX does this really happen anymore???
-                   */
+               /* This is where we actually generate fragments */
+               /* XXX the test for span.y > 0 _shouldn't_ be needed but
+                * it fixes a problem on 64-bit Opterons (bug 4842).
+                */
+               if (span.end > 0 && span.y >= 0) {
                   const GLint len = span.end - 1;
                   (void) len;
 #ifdef INTERP_RGB
-                  {
-                     GLfixed ffrend = span.red + len * span.redStep;
-                     GLfixed ffgend = span.green + len * span.greenStep;
-                     GLfixed ffbend = span.blue + len * span.blueStep;
-                     if (ffrend < 0) {
-                        span.red -= ffrend;
-                        if (span.red < 0)
-                           span.red = 0;
-                     }
-                     if (ffgend < 0) {
-                        span.green -= ffgend;
-                        if (span.green < 0)
-                           span.green = 0;
-                     }
-                     if (ffbend < 0) {
-                        span.blue -= ffbend;
-                        if (span.blue < 0)
-                           span.blue = 0;
-                     }
-                  }
+                  CLAMP_INTERPOLANT(red, redStep, len);
+                  CLAMP_INTERPOLANT(green, greenStep, len);
+                  CLAMP_INTERPOLANT(blue, blueStep, len);
 #endif
 #ifdef INTERP_ALPHA
-                  {
-                     GLfixed ffaend = span.alpha + len * span.alphaStep;
-                     if (ffaend < 0) {
-                        span.alpha -= ffaend;
-                        if (span.alpha < 0)
-                           span.alpha = 0;
-                     }
-                  }
+                  CLAMP_INTERPOLANT(alpha, alphaStep, len);
 #endif
 #ifdef INTERP_SPEC
-                  {
-                     GLfixed ffsrend = span.specRed + len * span.specRedStep;
-                     GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
-                     GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
-                     if (ffsrend < 0) {
-                        span.specRed -= ffsrend;
-                        if (span.specRed < 0)
-                           span.specRed = 0;
-                     }
-                     if (ffsgend < 0) {
-                        span.specGreen -= ffsgend;
-                        if (span.specGreen < 0)
-                           span.specGreen = 0;
-                     }
-                     if (ffsbend < 0) {
-                        span.specBlue -= ffsbend;
-                        if (span.specBlue < 0)
-                           span.specBlue = 0;
-                     }
-                  }
+                  CLAMP_INTERPOLANT(specRed, specRedStep, len);
+                  CLAMP_INTERPOLANT(specGreen, specGreenStep, len);
+                  CLAMP_INTERPOLANT(specBlue, specBlueStep, len);
 #endif
 #ifdef INTERP_INDEX
-                  if (span.index < 0)
-                     span.index = 0;
+                  CLAMP_INTERPOLANT(index, indexStep, len);
 #endif
-               } /* span.end > 1 */
-
-               /* This is where we actually generate fragments */
-               /* XXX the test for span.y > 0 _shouldn't_ be needed but
-                * it fixes a problem on 64-bit Opterons (bug 4842).
-                */
-               if (span.end > 0 && span.y >= 0) {
                   RENDER_SPAN( span );
                }