swrast: remove dstType param from _swrast_read_rgba_span()
[mesa.git] / src / mesa / swrast / s_span.c
index f81de3c0c7b30be5aa3841c107581170353253a3..3d3ec57d3977310d66b5fd1179f085109a55cf6e 100644 (file)
@@ -50,6 +50,7 @@
 #include "s_stencil.h"
 #include "s_texcombine.h"
 
+#include <stdbool.h>
 
 /**
  * Set default fragment attributes for the span using the
@@ -162,8 +163,9 @@ _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
-interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attrMask)
+static inline void
+interpolate_active_attribs(struct gl_context *ctx, SWspan *span,
+                           GLbitfield64 attrMask)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
@@ -174,7 +176,7 @@ interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attr
    attrMask &= ~span->arrayAttribs;
 
    ATTRIB_LOOP_BEGIN
-      if (attrMask & (1 << attr)) {
+      if (attrMask & BITFIELD64_BIT(attr)) {
          const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
          GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
          const GLfloat dv0dx = span->attrStepX[attr][0];
@@ -198,8 +200,8 @@ interpolate_active_attribs(struct gl_context *ctx, SWspan *span, GLbitfield attr
             v3 += dv3dx;
             w += dwdx;
          }
-         ASSERT((span->arrayAttribs & (1 << attr)) == 0);
-         span->arrayAttribs |= (1 << attr);
+         ASSERT((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0);
+         span->arrayAttribs |= BITFIELD64_BIT(attr);
       }
    ATTRIB_LOOP_END
 }
@@ -209,13 +211,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
 
@@ -309,7 +311,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];
@@ -490,6 +492,9 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
 
          if (obj) {
             const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
+            const struct swrast_texture_image *swImg =
+               swrast_texture_image_const(img);
+
             needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter)
                || ctx->FragmentProgram._Current;
             /* LOD is calculated directly in the ansiotropic filter, we can
@@ -499,8 +504,8 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
                 obj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
                needLambda = GL_FALSE;
             }
-            texW = img->WidthScale;
-            texH = img->HeightScale;
+            texW = swImg->WidthScale;
+            texH = swImg->HeightScale;
          }
          else {
             /* using a fragment program */
@@ -608,7 +613,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];
@@ -642,7 +647,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;
@@ -687,7 +692,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;
@@ -704,11 +709,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 {
@@ -716,9 +723,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 */
@@ -770,7 +778,7 @@ clip_span( struct gl_context *ctx, SWspan *span )
          span->intTex[1] += leftClip * span->intTexStep[1];
 
 #define SHIFT_ARRAY(ARRAY, SHIFT, LEN) \
-         memcpy(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0]))
+         memmove(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0]))
 
          for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
             if (span->arrayAttribs & (1 << i)) {
@@ -814,7 +822,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);
@@ -863,7 +871,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;
@@ -897,7 +905,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];
@@ -918,7 +926,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;
@@ -958,21 +966,28 @@ 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;
-   }
+   /* This is a hack to work around drivers such as i965 that:
+    *
+    *     - Set _MaintainTexEnvProgram to generate GLSL IR for
+    *       fixed-function fragment processing.
+    *     - Don't call _mesa_ir_link_shader to generate Mesa IR from
+    *       the GLSL IR.
+    *     - May use swrast to handle glDrawPixels.
+    *
+    * Since _mesa_ir_link_shader is never called, there is no Mesa IR
+    * to execute.  Instead do regular fixed-function processing.
+    *
+    * It is also worth noting that the software fixed-function path is
+    * much faster than the software shader path.
+    */
+   const bool use_fragment_program =
+      ctx->FragmentProgram._Current
+      && ctx->FragmentProgram._Current != ctx->FragmentProgram._TexEnvProgram;
 
-   if (ctx->FragmentProgram._Current ||
+   if (use_fragment_program ||
        ctx->ATIFragmentShader._Enabled) {
       /* programmable shading */
       if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
@@ -1001,7 +1016,7 @@ shade_texture_span(struct gl_context *ctx, SWspan *span)
          interpolate_wpos(ctx, span);
 
       /* Run fragment program/shader now */
-      if (ctx->FragmentProgram._Current) {
+      if (use_fragment_program) {
          _swrast_exec_fragment_program(ctx, span);
       }
       else {
@@ -1043,7 +1058,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
    const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
-   const GLbitfield origArrayAttribs = span->arrayAttribs;
+   const GLbitfield64 origArrayAttribs = span->arrayAttribs;
    const GLenum origChanType = span->array->ChanType;
    void * const origRgba = span->array->rgba;
    const GLboolean shader = (ctx->FragmentProgram._Current
@@ -1256,10 +1271,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) {
@@ -1306,16 +1324,16 @@ end:
 
 
 /**
- * Read RGBA pixels from a renderbuffer.  Clipping will be done to prevent
- * reading ouside the buffer's boundaries.
- * \param dstType  datatype for returned colors
+ * Read float RGBA pixels from a renderbuffer.  Clipping will be done to
+ * prevent reading ouside the buffer's boundaries.
  * \param rgba  the returned colors
  */
 void
 _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                        GLuint n, GLint x, GLint y, GLenum dstType,
+                        GLuint n, GLint x, GLint y,
                         GLvoid *rgba)
 {
+   GLenum dstType = GL_FLOAT;
    const GLint bufWidth = (GLint) rb->Width;
    const GLint bufHeight = (GLint) rb->Height;
 
@@ -1418,41 +1436,6 @@ _swrast_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
 }
 
 
-/**
- * Wrapper for gl_renderbuffer::PutRow() which does clipping.
- * \param valueSize  size of each value (pixel) in bytes
- */
-void
-_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
-                GLuint count, GLint x, GLint y,
-                const GLvoid *values, GLuint valueSize)
-{
-   GLint skip = 0;
-
-   if (y < 0 || y >= (GLint) rb->Height)
-      return; /* above or below */
-
-   if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
-      return; /* entirely left or right */
-
-   if ((GLint) (x + count) > (GLint) rb->Width) {
-      /* right clip */
-      GLint clip = x + count - rb->Width;
-      count -= clip;
-   }
-
-   if (x < 0) {
-      /* left clip */
-      skip = -x;
-      x = 0;
-      count -= skip;
-   }
-
-   rb->PutRow(ctx, rb, count, x, y,
-              (const GLubyte *) values + skip * valueSize, NULL);
-}
-
-
 /**
  * Wrapper for gl_renderbuffer::GetRow() which does clipping.
  * \param valueSize  size of each value (pixel) in bytes