swrast: implement GL_ARB_texture_storage
[mesa.git] / src / mesa / swrast / s_span.c
index 3240b1357743961443ebf8b96bab862c1f3d9ea4..4124e444e000c37368eddc4e248b6ab22915e106 100644 (file)
@@ -162,7 +162,7 @@ _swrast_span_default_attribs(struct gl_context *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
+static inline void
 interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attrMask)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
@@ -209,13 +209,13 @@ interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attr
  * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
  * color array.
  */
-static INLINE void
+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
 
@@ -299,7 +299,8 @@ interpolate_int_colors(struct gl_context *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;
 }
@@ -308,7 +309,7 @@ interpolate_int_colors(struct gl_context *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];
@@ -489,10 +490,20 @@ interpolate_texcoords(struct gl_context *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 */
@@ -600,7 +611,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
 /**
  * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
  */
-static INLINE void
+static inline void
 interpolate_wpos(struct gl_context *ctx, SWspan *span)
 {
    GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
@@ -634,7 +645,7 @@ interpolate_wpos(struct gl_context *ctx, SWspan *span)
 /**
  * Apply the current polygon stipple pattern to a span of pixels.
  */
-static INLINE void
+static inline void
 stipple_polygon_span(struct gl_context *ctx, SWspan *span)
 {
    GLubyte *mask = span->array->mask;
@@ -679,7 +690,7 @@ stipple_polygon_span(struct gl_context *ctx, SWspan *span)
  * Return:   GL_TRUE   some pixels still visible
  *           GL_FALSE  nothing visible
  */
-static INLINE GLuint
+static inline GLuint
 clip_span( struct gl_context *ctx, SWspan *span )
 {
    const GLint xmin = ctx->DrawBuffer->_Xmin;
@@ -696,11 +707,13 @@ clip_span( struct gl_context *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 {
@@ -708,9 +721,10 @@ clip_span( struct gl_context *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 */
@@ -806,7 +820,7 @@ clip_span( struct gl_context *ctx, SWspan *span )
  * Only called during fixed-function operation.
  * Result is float color array (FRAG_ATTRIB_COL0).
  */
-static INLINE void
+static inline void
 add_specular(struct gl_context *ctx, SWspan *span)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
@@ -855,7 +869,7 @@ add_specular(struct gl_context *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;
@@ -889,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];
@@ -910,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;
@@ -950,20 +964,9 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
 /**
  * Apply fragment shader, fragment program or normal texturing to span.
  */
-static INLINE void
+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 */
@@ -1248,10 +1251,13 @@ _swrast_write_rgba_span( struct gl_context *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) {
@@ -1347,7 +1353,13 @@ _swrast_read_rgba_span( struct gl_context *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) {