Roll the multi_write_rgba_span() code into _swrast_write_rgba_span().
authorBrian Paul <brian.paul@tungstengraphics.com>
Sun, 24 Sep 2006 19:46:42 +0000 (19:46 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sun, 24 Sep 2006 19:46:42 +0000 (19:46 +0000)
src/mesa/swrast/s_span.c

index cc7d4113fc32f63ad94a380e1d1f4a35ed1e15f5..f67f083e3baaa63961a8a584d46f20e8a6543b28 100644 (file)
@@ -812,11 +812,8 @@ void
 _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const struct gl_framebuffer *fb = ctx->DrawBuffer;
-   const GLuint output = 0;
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
-   GLuint buf;
 
    ASSERT(span->end <= MAX_WIDTH);
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
@@ -931,95 +928,106 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
       }
    }
 
-   /* Loop over drawing buffers */
-   for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
-      struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
-      GLuint indexTemp[MAX_WIDTH], *index32;
+   /*
+    * Write to renderbuffers
+    */
+   {
+      struct gl_framebuffer *fb = ctx->DrawBuffer;
+      const GLuint output = 0; /* only frag progs can write to others */
+      const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
+      GLuint indexSave[MAX_WIDTH];
+      GLuint buf;
 
-      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
+      if (numDrawBuffers > 1) {
+         /* save indexes for second, third renderbuffer writes */
+         _mesa_memcpy(indexSave, span->array->index,
+                      span->end * sizeof(indexSave[0]));
+      }
 
-      if (ctx->Color.IndexLogicOpEnabled ||
-          ctx->Color.IndexMask != 0xffffffff) {
-         /* make copy of incoming indexes */
-         MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint));
+      for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
+         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
+         ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
 
          if (ctx->Color.IndexLogicOpEnabled) {
-            _swrast_logicop_ci_span(ctx, rb, span, indexTemp);
+            _swrast_logicop_ci_span(ctx, rb, span, span->array->index);
          }
 
          if (ctx->Color.IndexMask != 0xffffffff) {
-            _swrast_mask_ci_span(ctx, rb, span, indexTemp);
+            _swrast_mask_ci_span(ctx, rb, span, span->array->index);
          }
-         index32 = indexTemp;
-      }
-      else {
-         index32 = span->array->index;
-      }
 
-      if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
-         /* all fragments have same color index */
-         GLubyte index8;
-         GLushort index16;
-         GLuint index32;
-         void *value;
+         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+            /* all fragments have same color index */
+            GLubyte index8;
+            GLushort index16;
+            GLuint index32;
+            void *value;
 
-         if (rb->DataType == GL_UNSIGNED_BYTE) {
-            index8 = FixedToInt(span->index);
-            value = &index8;
-         }
-         else if (rb->DataType == GL_UNSIGNED_SHORT) {
-            index16 = FixedToInt(span->index);
-            value = &index16;
-         }
-         else {
-            ASSERT(rb->DataType == GL_UNSIGNED_INT);
-            index32 = FixedToInt(span->index);
-            value = &index32;
-         }
-
-         if (span->arrayMask & SPAN_XY) {
-            rb->PutMonoValues(ctx, rb, span->end, span->array->x, 
-                              span->array->y, value, span->array->mask);
-         }
-         else {
-            rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,
-                           value, span->array->mask);
-         }
-      }
-      else {
-         /* each fragment is a different color */
-         GLubyte index8[MAX_WIDTH];
-         GLushort index16[MAX_WIDTH];
-         void *values;
+            if (rb->DataType == GL_UNSIGNED_BYTE) {
+               index8 = FixedToInt(span->index);
+               value = &index8;
+            }
+            else if (rb->DataType == GL_UNSIGNED_SHORT) {
+               index16 = FixedToInt(span->index);
+               value = &index16;
+            }
+            else {
+               ASSERT(rb->DataType == GL_UNSIGNED_INT);
+               index32 = FixedToInt(span->index);
+               value = &index32;
+            }
 
-         if (rb->DataType == GL_UNSIGNED_BYTE) {
-            GLuint k;
-            for (k = 0; k < span->end; k++) {
-               index8[k] = (GLubyte) index32[k];
+            if (span->arrayMask & SPAN_XY) {
+               rb->PutMonoValues(ctx, rb, span->end, span->array->x, 
+                                 span->array->y, value, span->array->mask);
             }
-            values = index8;
-         }
-         else if (rb->DataType == GL_UNSIGNED_SHORT) {
-            GLuint k;
-            for (k = 0; k < span->end; k++) {
-               index16[k] = (GLushort) index32[k];
+            else {
+               rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,
+                              value, span->array->mask);
             }
-            values = index16;
          }
          else {
-            ASSERT(rb->DataType == GL_UNSIGNED_INT);
-            values = index32;
-         }
+            /* each fragment is a different color */
+            GLubyte index8[MAX_WIDTH];
+            GLushort index16[MAX_WIDTH];
+            void *values;
+
+            if (rb->DataType == GL_UNSIGNED_BYTE) {
+               GLuint k;
+               for (k = 0; k < span->end; k++) {
+                  index8[k] = (GLubyte) span->array->index[k];
+               }
+               values = index8;
+            }
+            else if (rb->DataType == GL_UNSIGNED_SHORT) {
+               GLuint k;
+               for (k = 0; k < span->end; k++) {
+                  index16[k] = (GLushort) span->array->index[k];
+               }
+               values = index16;
+            }
+            else {
+               ASSERT(rb->DataType == GL_UNSIGNED_INT);
+               values = span->array->index;
+            }
 
-         if (span->arrayMask & SPAN_XY) {
-            rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y,
+            if (span->arrayMask & SPAN_XY) {
+               rb->PutValues(ctx, rb, span->end,
+                             span->array->x, span->array->y,
+                             values, span->array->mask);
+            }
+            else {
+               rb->PutRow(ctx, rb, span->end, span->x, span->y,
                           values, span->array->mask);
+            }
          }
-         else {
-            rb->PutRow(ctx, rb, span->end, span->x, span->y,
-                       values, span->array->mask);
+
+         if (buf + 1 < numDrawBuffers) {
+            /* restore original span values */
+            _mesa_memcpy(span->array->index, indexSave,
+                         span->end * sizeof(indexSave[0]));
          }
-      }
+      } /* for buf */
    }
 
    span->interpMask = origInterpMask;
@@ -1053,58 +1061,6 @@ add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
 }
 
 
-/**
- * XXX merge this code into the _swrast_write_rgba_span() routine!
- *
- * Draw to more than one RGBA color buffer (or none).
- * All fragment operations, up to (but not) blending/logicop should
- * have been done first.
- */
-static void
-multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
-{
-   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   const GLuint output = 0;
-   GLuint i;
-
-   ASSERT(span->end < MAX_WIDTH);
-   ASSERT(colorMask != 0x0);
-
-   for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) {
-      struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i];
-      GLchan rgbaTmp[MAX_WIDTH][4];
-
-      /* make copy of incoming colors */
-      MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );
-
-      if (ctx->Color._LogicOpEnabled) {
-         _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp);
-      }
-      else if (ctx->Color.BlendEnabled) {
-         _swrast_blend_span(ctx, rb, span, rgbaTmp);
-      }
-
-      if (colorMask != 0xffffffff) {
-         _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp);
-      }
-
-      if (span->arrayMask & SPAN_XY) {
-         /* array of pixel coords */
-         ASSERT(rb->PutValues);
-         rb->PutValues(ctx, rb, span->end, span->array->x,
-                       span->array->y, rgbaTmp, span->array->mask);
-      }
-      else {
-         /* horizontal run of pixels */
-         ASSERT(rb->PutRow);
-         rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp,
-                    span->array->mask);
-      }
-   }
-}
-
-
 /**
  * Apply all the per-fragment operations to a span.
  * This now includes texturing (_swrast_write_texture_span() is history).
@@ -1350,43 +1306,59 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
    }
 #endif
 
-   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
-      /* need to do blend/logicop separately for each color buffer */
-      multi_write_rgba_span(ctx, span);
-   }
-   else {
-      /* normal: write to exactly one buffer */
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   /*
+    * Write to renderbuffers
+    */
+   {
+      struct gl_framebuffer *fb = ctx->DrawBuffer;
+      const GLuint output = 0; /* only frag progs can write to others */
+      const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
+      GLchan rgbaSave[MAX_WIDTH][4];
+      GLuint buf;
 
-      if (ctx->Color._LogicOpEnabled) {
-         _swrast_logicop_rgba_span(ctx, rb, span, span->array->rgba);
-      }
-      else if (ctx->Color.BlendEnabled) {
-         _swrast_blend_span(ctx, rb, span, span->array->rgba);
+      if (numDrawBuffers > 1) {
+         /* save colors for second, third renderbuffer writes */
+         _mesa_memcpy(rgbaSave, span->array->rgba,
+                      4 * span->end * sizeof(GLchan));
       }
 
-      /* Color component masking */
-      if (colorMask != 0xffffffff) {
-         _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba);
-      }
+      for (buf = 0; buf < numDrawBuffers; buf++) {
+         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
+         ASSERT(rb->_BaseFormat == GL_RGBA);
 
-      /* Finally, write the pixels to a color buffer */
-      if (span->arrayMask & SPAN_XY) {
-         /* array of pixel coords */
-         ASSERT(rb->PutValues);
-         ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
-         /* XXX check datatype */
-         rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y,
-                       span->array->rgba, span->array->mask);
-      }
-      else {
-         /* horizontal run of pixels */
-         ASSERT(rb->PutRow);
-         ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
-         /* XXX check datatype */
-         rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba,
-                    span->writeAll ? NULL : span->array->mask);
-      }
+         if (ctx->Color._LogicOpEnabled) {
+            _swrast_logicop_rgba_span(ctx, rb, span, span->array->rgba);
+         }
+         else if (ctx->Color.BlendEnabled) {
+            _swrast_blend_span(ctx, rb, span, span->array->rgba);
+         }
+
+         if (colorMask != 0xffffffff) {
+            _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba);
+         }
+
+         if (span->arrayMask & SPAN_XY) {
+            /* array of pixel coords */
+            ASSERT(rb->PutValues);
+            ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
+            rb->PutValues(ctx, rb, span->end,
+                          span->array->x, span->array->y,
+                          span->array->rgba, span->array->mask);
+         }
+         else {
+            /* horizontal run of pixels */
+            ASSERT(rb->PutRow);
+            ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
+            rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba,
+                       span->writeAll ? NULL: span->array->mask);
+         }
+
+         if (buf + 1 < numDrawBuffers) {
+            /* restore original span values */
+            _mesa_memcpy(span->array->rgba, rgbaSave,
+                         4 * span->end * sizeof(GLchan));
+         }
+      } /* for buf */
    }
 
    span->interpMask = origInterpMask;
@@ -1521,7 +1493,7 @@ _swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
  * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
  * reading values outside the buffer bounds.
  * We can use this for reading any format/type of renderbuffer.
- * \param valueSize is the size in bytes of each value put into the
+ * \param valueSize is the size in bytes of each value (pixel) put into the
  *                  values array.
  */
 void