Consolidate texObj->Pos/Neg/X/Y/Z and texObj->Image into a single
[mesa.git] / src / mesa / swrast / s_span.c
index d6959e1f4c9495de52ec089fe1bdabe181215c2c..ee46f323076e64964e54b481ce5e4db10be95472 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: s_span.c,v 1.60 2003/03/25 02:23:47 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
  * Version:  5.1
@@ -112,7 +110,7 @@ _swrast_span_default_color( GLcontext *ctx, struct sw_span *span )
       span->interpMask |= SPAN_RGBA;
    }
    else {
-      span->index = IntToFixed(ctx->Current.RasterIndex);
+      span->index = FloatToFixed(ctx->Current.RasterIndex);
       span->indexStep = 0;
       span->interpMask |= SPAN_INDEX;
    }
@@ -353,21 +351,30 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
    ASSERT(span->interpMask & SPAN_TEXTURE);
    ASSERT(!(span->arrayMask & SPAN_TEXTURE));
 
-   if (ctx->Texture._EnabledUnits > 1) {
+   if (ctx->Texture._EnabledCoordUnits > 1) {
       /* multitexture */
       GLuint u;
       span->arrayMask |= SPAN_TEXTURE;
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-         if (ctx->Texture.Unit[u]._ReallyEnabled) {
+         if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
             const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
-            const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
-            const GLboolean needLambda = (obj->MinFilter != obj->MagFilter)
-               || ctx->FragmentProgram.Enabled;
+            GLfloat texW, texH;
+            GLboolean needLambda;
+            if (obj) {
+               const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
+               needLambda = (obj->MinFilter != obj->MagFilter)
+                  || ctx->FragmentProgram.Enabled;
+               texW = img->WidthScale;
+               texH = img->HeightScale;
+            }
+            else {
+               texW = 1.0;
+               texH = 1.0;
+               needLambda = GL_FALSE;
+            }
             if (needLambda) {
                GLfloat (*texcoord)[4] = span->array->texcoords[u];
                GLfloat *lambda = span->array->lambda[u];
-               const GLfloat texW = (GLfloat) img->WidthScale;
-               const GLfloat texH = (GLfloat) img->HeightScale;
                const GLfloat dsdx = span->texStepX[u][0];
                const GLfloat dsdy = span->texStepY[u][0];
                const GLfloat dtdx = span->texStepX[u][1];
@@ -415,6 +422,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
                      texcoord[i][0] = s * invQ;
                      texcoord[i][1] = t * invQ;
                      texcoord[i][2] = r * invQ;
+                     texcoord[i][3] = q;
                      lambda[i] = 0.0;
                      s += dsdx;
                      t += dtdx;
@@ -427,6 +435,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
                      texcoord[i][0] = s * invQ;
                      texcoord[i][1] = t * invQ;
                      texcoord[i][2] = r * invQ;
+                     texcoord[i][3] = q;
                      lambda[i] = 0.0;
                      s += dsdx;
                      t += dtdx;
@@ -441,16 +450,24 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
    else {
       /* single texture */
       const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
-      const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
-      const GLboolean needLambda = (obj->MinFilter != obj->MagFilter)
-         || ctx->FragmentProgram.Enabled;
+      GLfloat texW, texH;
+      GLboolean needLambda;
+      if (obj) {
+         const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
+         needLambda = (obj->MinFilter != obj->MagFilter)
+            || ctx->FragmentProgram.Enabled;
+         texW = (GLfloat) img->WidthScale;
+         texH = (GLfloat) img->HeightScale;
+      }
+      else {
+         needLambda = GL_FALSE;
+         texW = texH = 1.0;
+      }
       span->arrayMask |= SPAN_TEXTURE;
       if (needLambda) {
          /* just texture unit 0, with lambda */
          GLfloat (*texcoord)[4] = span->array->texcoords[0];
          GLfloat *lambda = span->array->lambda[0];
-         const GLfloat texW = (GLfloat) img->WidthScale;
-         const GLfloat texH = (GLfloat) img->HeightScale;
          const GLfloat dsdx = span->texStepX[0][0];
          const GLfloat dsdy = span->texStepY[0][0];
          const GLfloat dtdx = span->texStepX[0][1];
@@ -498,6 +515,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
                texcoord[i][0] = s * invQ;
                texcoord[i][1] = t * invQ;
                texcoord[i][2] = r * invQ;
+               texcoord[i][3] = q;
                s += dsdx;
                t += dtdx;
                r += drdx;
@@ -509,6 +527,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
                texcoord[i][0] = s * invQ;
                texcoord[i][1] = t * invQ;
                texcoord[i][2] = r * invQ;
+               texcoord[i][3] = q;
                s += dsdx;
                t += dtdx;
                r += drdx;
@@ -697,7 +716,7 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
          /* make copy of incoming colors */
          MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );
 
-         if (ctx->Color.ColorLogicOpEnabled) {
+         if (ctx->Color._LogicOpEnabled) {
             _swrast_logicop_rgba_span(ctx, span, rgbaTmp);
          }
          else if (ctx->Color.BlendEnabled) {
@@ -775,6 +794,13 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
       }
    }
 
+   /* Depth bounds test */
+   if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) {
+      if (!_swrast_depth_bounds_test(ctx, span)) {
+         return;
+      }
+   }
+
 #ifdef DEBUG
    if (span->arrayMask & SPAN_XY) {
       GLuint i;
@@ -817,6 +843,14 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, something passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* we have to wait until after occlusion to do this test */
    if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
       /* write no pixels */
@@ -945,6 +979,13 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
       }
    }
 
+   /* Depth bounds test */
+   if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) {
+      if (!_swrast_depth_bounds_test(ctx, span)) {
+         return;
+      }
+   }
+
 #ifdef DEBUG
    if (span->arrayMask & SPAN_XY) {
       GLuint i;
@@ -972,6 +1013,9 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
          interpolate_colors(ctx, span);
          span->interpMask &= ~SPAN_RGBA;
       }
+      if (span->interpMask & SPAN_SPEC) {
+         interpolate_specular(ctx, span);
+      }
       _swrast_exec_nv_fragment_program(ctx, span);
       monoColor = GL_FALSE;
    }
@@ -1012,6 +1056,14 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, something passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* can't abort span-writing until after occlusion testing */
    if (colorMask == 0x0) {
       span->interpMask = origInterpMask;
@@ -1048,7 +1100,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
    }
    else {
       /* normal: write to exactly one buffer */
-      if (ctx->Color.ColorLogicOpEnabled) {
+      if (ctx->Color._LogicOpEnabled) {
          _swrast_logicop_rgba_span(ctx, span, span->array->rgba);
          monoColor = GL_FALSE;
       }
@@ -1148,13 +1200,14 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
 {
    const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLuint origInterpMask = span->interpMask;
    const GLuint origArrayMask = span->arrayMask;
 
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
          span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
    ASSERT(span->end <= MAX_WIDTH);
    ASSERT((span->interpMask & span->arrayMask) == 0);
-   ASSERT(ctx->Texture._EnabledUnits);
+   ASSERT(ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram.Enabled);
 
    /*
    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
@@ -1207,6 +1260,10 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
       if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
          interpolate_colors(ctx, span);
 
+      if (span->interpMask & SPAN_SPEC) {
+         interpolate_specular(ctx, span);
+      }
+
       /* Texturing without alpha is done after depth-testing which
        * gives a potential speed-up.
        */
@@ -1229,6 +1286,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
 
       if (ctx->Stencil.Enabled) {
          if (!_swrast_stencil_and_ztest_span(ctx, span)) {
+            span->interpMask = origInterpMask;
             span->arrayMask = origArrayMask;
             return;
          }
@@ -1238,6 +1296,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
          ASSERT(span->arrayMask & SPAN_Z);
          /* regular depth testing */
          if (!_swrast_depth_test_span(ctx, span)) {
+            span->interpMask = origInterpMask;
             span->arrayMask = origArrayMask;
             return;
          }
@@ -1247,10 +1306,19 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, some fragments passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* We had to wait until now to check for glColorMask(F,F,F,F) because of
     * the occlusion test.
     */
    if (colorMask == 0x0) {
+      span->interpMask = origInterpMask;
       span->arrayMask = origArrayMask;
       return;
    }
@@ -1262,6 +1330,10 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
       if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
          interpolate_colors(ctx, span);
 
+      if (span->interpMask & SPAN_SPEC) {
+         interpolate_specular(ctx, span);
+      }
+
       if (ctx->FragmentProgram.Enabled)
          _swrast_exec_nv_fragment_program( ctx, span );
       else
@@ -1301,18 +1373,19 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
    }
    else {
       /* normal: write to exactly one buffer */
-      if (ctx->Color.ColorLogicOpEnabled) {
+      if (ctx->Color._LogicOpEnabled) {
          _swrast_logicop_rgba_span(ctx, span, span->array->rgba);
       }
       else if (ctx->Color.BlendEnabled) {
          _swrast_blend_span(ctx, span, span->array->rgba);
       }
 
+      /* Color component masking */
       if (colorMask != 0xffffffff) {
          _swrast_mask_rgba_span(ctx, span, span->array->rgba);
       }
 
+      /* write pixels */
       if (span->arrayMask & SPAN_XY) {
          /* array of pixel coords */
          (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
@@ -1337,6 +1410,7 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
       }
    }
 
+   span->interpMask = origInterpMask;
    span->arrayMask = origArrayMask;
 }