swrast: update renderbuffer format assertion
[mesa.git] / src / mesa / swrast / s_span.c
index f1f37dfe837ff4bec48b1a2ca7917930a620106e..4124e444e000c37368eddc4e248b6ab22915e106 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "main/glheader.h"
 #include "main/colormac.h"
-#include "main/context.h"
 #include "main/macros.h"
 #include "main/imports.h"
 #include "main/image.h"
@@ -58,8 +57,9 @@
  * and glBitmap.
  */
 void
-_swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
+_swrast_span_default_attribs(struct gl_context *ctx, SWspan *span)
 {
+   GLchan r, g, b, a;
    /* Z*/
    {
       const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
@@ -80,7 +80,6 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
    span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
 
    /* primary color, or color index */
-   GLchan r, g, b, a;
    UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
    UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
    UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
@@ -163,8 +162,8 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
  * Perspective correction will be done.  The point/line/triangle function
  * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]!
  */
-static INLINE void
-interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
+static inline void
+interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attrMask)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
@@ -210,13 +209,13 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
  * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
  * color array.
  */
-static INLINE void
-interpolate_int_colors(GLcontext *ctx, SWspan *span)
+static inline void
+interpolate_int_colors(struct gl_context *ctx, SWspan *span)
 {
+#if CHAN_BITS != 32
    const GLuint n = span->end;
    GLuint i;
 
-#if CHAN_BITS != 32
    ASSERT(!(span->arrayMask & SPAN_RGBA));
 #endif
 
@@ -300,7 +299,8 @@ interpolate_int_colors(GLcontext *ctx, SWspan *span)
       interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
       break;
    default:
-      _mesa_problem(NULL, "bad datatype in interpolate_int_colors");
+      _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors",
+                    span->array->ChanType);
    }
    span->arrayMask |= SPAN_RGBA;
 }
@@ -309,7 +309,7 @@ interpolate_int_colors(GLcontext *ctx, SWspan *span)
 /**
  * Populate the FRAG_ATTRIB_COL0 array.
  */
-static INLINE void
+static inline void
 interpolate_float_colors(SWspan *span)
 {
    GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
@@ -371,7 +371,7 @@ interpolate_float_colors(SWspan *span)
  * Fill in the span.zArray array from the span->z, zStep values.
  */
 void
-_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
+_swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span )
 {
    const GLuint n = span->end;
    GLuint i;
@@ -461,7 +461,7 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
  * texels with (s/q, t/q, r/q).
  */
 static void
-interpolate_texcoords(GLcontext *ctx, SWspan *span)
+interpolate_texcoords(struct gl_context *ctx, SWspan *span)
 {
    const GLuint maxUnit
       = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
@@ -490,10 +490,20 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
 
          if (obj) {
             const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
-            needLambda = (obj->MinFilter != obj->MagFilter)
+            const struct swrast_texture_image *swImg =
+               swrast_texture_image_const(img);
+
+            needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter)
                || ctx->FragmentProgram._Current;
-            texW = img->WidthScale;
-            texH = img->HeightScale;
+            /* LOD is calculated directly in the ansiotropic filter, we can
+             * skip the normal lambda function as the result is ignored.
+             */
+            if (obj->Sampler.MaxAnisotropy > 1.0 &&
+                obj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
+               needLambda = GL_FALSE;
+            }
+            texW = swImg->WidthScale;
+            texH = swImg->HeightScale;
          }
          else {
             /* using a fragment program */
@@ -601,8 +611,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
 /**
  * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
  */
-static INLINE void
-interpolate_wpos(GLcontext *ctx, SWspan *span)
+static inline void
+interpolate_wpos(struct gl_context *ctx, SWspan *span)
 {
    GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
    GLuint i;
@@ -635,8 +645,8 @@ interpolate_wpos(GLcontext *ctx, SWspan *span)
 /**
  * Apply the current polygon stipple pattern to a span of pixels.
  */
-static INLINE void
-stipple_polygon_span(GLcontext *ctx, SWspan *span)
+static inline void
+stipple_polygon_span(struct gl_context *ctx, SWspan *span)
 {
    GLubyte *mask = span->array->mask;
 
@@ -680,8 +690,8 @@ stipple_polygon_span(GLcontext *ctx, SWspan *span)
  * Return:   GL_TRUE   some pixels still visible
  *           GL_FALSE  nothing visible
  */
-static INLINE GLuint
-clip_span( GLcontext *ctx, SWspan *span )
+static inline GLuint
+clip_span( struct gl_context *ctx, SWspan *span )
 {
    const GLint xmin = ctx->DrawBuffer->_Xmin;
    const GLint xmax = ctx->DrawBuffer->_Xmax;
@@ -697,11 +707,13 @@ clip_span( GLcontext *ctx, SWspan *span )
       const GLint n = span->end;
       GLubyte *mask = span->array->mask;
       GLint i;
+      GLuint passed = 0;
       if (span->arrayMask & SPAN_MASK) {
          /* note: using & intead of && to reduce branches */
          for (i = 0; i < n; i++) {
             mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
                      & (y[i] >= ymin) & (y[i] < ymax);
+            passed += mask[i];
          }
       }
       else {
@@ -709,9 +721,10 @@ clip_span( GLcontext *ctx, SWspan *span )
          for (i = 0; i < n; i++) {
             mask[i] = (x[i] >= xmin) & (x[i] < xmax)
                     & (y[i] >= ymin) & (y[i] < ymax);
+            passed += mask[i];
          }
       }
-      return GL_TRUE;  /* some pixels visible */
+      return passed > 0;
    }
    else {
       /* horizontal span of pixels */
@@ -807,8 +820,8 @@ clip_span( GLcontext *ctx, SWspan *span )
  * Only called during fixed-function operation.
  * Result is float color array (FRAG_ATTRIB_COL0).
  */
-static INLINE void
-add_specular(GLcontext *ctx, SWspan *span)
+static inline void
+add_specular(struct gl_context *ctx, SWspan *span)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLubyte *mask = span->array->mask;
@@ -856,7 +869,7 @@ add_specular(GLcontext *ctx, SWspan *span)
 /**
  * Apply antialiasing coverage value to alpha values.
  */
-static INLINE void
+static inline void
 apply_aa_coverage(SWspan *span)
 {
    const GLfloat *coverage = span->array->coverage;
@@ -890,7 +903,7 @@ apply_aa_coverage(SWspan *span)
 /**
  * Clamp span's float colors to [0,1]
  */
-static INLINE void
+static inline void
 clamp_colors(SWspan *span)
 {
    GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
@@ -911,7 +924,7 @@ clamp_colors(SWspan *span)
  * program that writes to gl_FragData[1] or higher.
  * \param output  which fragment program color output is being processed
  */
-static INLINE void
+static inline void
 convert_color_type(SWspan *span, GLenum newType, GLuint output)
 {
    GLvoid *src, *dst;
@@ -951,26 +964,19 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
 /**
  * Apply fragment shader, fragment program or normal texturing to span.
  */
-static INLINE void
-shade_texture_span(GLcontext *ctx, SWspan *span)
+static inline void
+shade_texture_span(struct gl_context *ctx, SWspan *span)
 {
-   GLbitfield inputsRead;
-
-   /* Determine which fragment attributes are actually needed */
-   if (ctx->FragmentProgram._Current) {
-      inputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
-   }
-   else {
-      /* XXX we could be a bit smarter about this */
-      inputsRead = ~0;
-   }
-
    if (ctx->FragmentProgram._Current ||
        ctx->ATIFragmentShader._Enabled) {
       /* programmable shading */
       if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
          convert_color_type(span, GL_FLOAT, 0);
       }
+      else {
+         span->array->rgba = (void *) span->array->attribs[FRAG_ATTRIB_COL0];
+      }
+
       if (span->primitive != GL_POINT ||
          (span->interpMask & SPAN_RGBA) ||
          ctx->Point.PointSprite) {
@@ -1026,7 +1032,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
  * to their original values before returning.
  */
 void
-_swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
+_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
@@ -1222,9 +1228,22 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
             GLchan rgbaSave[MAX_WIDTH][4];
             const GLuint fragOutput = multiFragOutputs ? buf : 0;
 
+            /* set span->array->rgba to colors for render buffer's datatype */
             if (rb->DataType != span->array->ChanType || fragOutput > 0) {
                convert_color_type(span, rb->DataType, fragOutput);
             }
+            else {
+               if (rb->DataType == GL_UNSIGNED_BYTE) {
+                  span->array->rgba = span->array->rgba8;
+               }
+               else if (rb->DataType == GL_UNSIGNED_SHORT) {
+                  span->array->rgba = (void *) span->array->rgba16;
+               }
+               else {
+                  span->array->rgba = (void *)
+                     span->array->attribs[FRAG_ATTRIB_COL0];
+               }
+            }
 
             if (!multiFragOutputs && numBuffers > 1) {
                /* save colors for second, third renderbuffer writes */
@@ -1232,9 +1251,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
                       4 * span->end * sizeof(GLchan));
             }
 
-            ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
+            ASSERT(rb->_BaseFormat == GL_RGBA ||
+                   rb->_BaseFormat == GL_RGB ||
+                   rb->_BaseFormat == GL_RED ||
+                   rb->_BaseFormat == GL_RG ||
+                  rb->_BaseFormat == GL_ALPHA);
 
-            if (ctx->Color._LogicOpEnabled) {
+            if (ctx->Color.ColorLogicOpEnabled) {
                _swrast_logicop_rgba_span(ctx, rb, span);
             }
             else if ((ctx->Color.BlendEnabled >> buf) & 1) {
@@ -1287,7 +1310,7 @@ end:
  * \param rgba  the returned colors
  */
 void
-_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
+_swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
                         GLuint n, GLint x, GLint y, GLenum dstType,
                         GLvoid *rgba)
 {
@@ -1330,7 +1353,14 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
 
       ASSERT(rb);
       ASSERT(rb->GetRow);
-      ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
+      ASSERT(rb->_BaseFormat == GL_RGBA ||
+            rb->_BaseFormat == GL_RGB ||
+            rb->_BaseFormat == GL_RG ||
+            rb->_BaseFormat == GL_RED ||
+            rb->_BaseFormat == GL_LUMINANCE ||
+            rb->_BaseFormat == GL_INTENSITY ||
+            rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
+            rb->_BaseFormat == GL_ALPHA);
 
       if (rb->DataType == dstType) {
          rb->GetRow(ctx, rb, length, x + skip, y,
@@ -1347,74 +1377,6 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
 }
 
 
-/**
- * Read CI pixels from a renderbuffer.  Clipping will be done to prevent
- * reading ouside the buffer's boundaries.
- */
-void
-_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
-                         GLuint n, GLint x, GLint y, GLuint index[] )
-{
-   const GLint bufWidth = (GLint) rb->Width;
-   const GLint bufHeight = (GLint) rb->Height;
-
-   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
-      /* completely above, below, or right */
-      memset(index, 0, n * sizeof(GLuint));
-   }
-   else {
-      GLint skip, length;
-      if (x < 0) {
-         /* left edge clipping */
-         skip = -x;
-         length = (GLint) n - skip;
-         if (length < 0) {
-            /* completely left of window */
-            return;
-         }
-         if (length > bufWidth) {
-            length = bufWidth;
-         }
-      }
-      else if ((GLint) (x + n) > bufWidth) {
-         /* right edge clipping */
-         skip = 0;
-         length = bufWidth - x;
-         if (length < 0) {
-            /* completely to right of window */
-            return;
-         }
-      }
-      else {
-         /* no clipping */
-         skip = 0;
-         length = (GLint) n;
-      }
-
-      ASSERT(rb->GetRow);
-      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
-
-      if (rb->DataType == GL_UNSIGNED_BYTE) {
-         GLubyte index8[MAX_WIDTH];
-         GLint i;
-         rb->GetRow(ctx, rb, length, x + skip, y, index8);
-         for (i = 0; i < length; i++)
-            index[skip + i] = index8[i];
-      }
-      else if (rb->DataType == GL_UNSIGNED_SHORT) {
-         GLushort index16[MAX_WIDTH];
-         GLint i;
-         rb->GetRow(ctx, rb, length, x + skip, y, index16);
-         for (i = 0; i < length; i++)
-            index[skip + i] = index16[i];
-      }
-      else if (rb->DataType == GL_UNSIGNED_INT) {
-         rb->GetRow(ctx, rb, length, x + skip, y, index + skip);
-      }
-   }
-}
-
-
 /**
  * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
  * reading values outside the buffer bounds.
@@ -1423,7 +1385,7 @@ _swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
  *                  values array.
  */
 void
-_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
+_swrast_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
                    GLuint count, const GLint x[], const GLint y[],
                    void *values, GLuint valueSize)
 {
@@ -1459,7 +1421,7 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
  * \param valueSize  size of each value (pixel) in bytes
  */
 void
-_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
+_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
                 GLuint count, GLint x, GLint y,
                 const GLvoid *values, GLuint valueSize)
 {
@@ -1494,7 +1456,7 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
  * \param valueSize  size of each value (pixel) in bytes
  */
 void
-_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
+_swrast_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
                 GLuint count, GLint x, GLint y,
                 GLvoid *values, GLuint valueSize)
 {
@@ -1529,7 +1491,7 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
  * \return pointer to the colors we read.
  */
 void *
-_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
+_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
                       SWspan *span)
 {
    const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);