Simplify ctx->_NumColorDrawBuffers, _ColorDrawBuffers and fix bug 13835.
authorBrian <brian.paul@tungstengraphics.com>
Sun, 6 Jan 2008 17:43:20 +0000 (10:43 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Sun, 6 Jan 2008 17:43:20 +0000 (10:43 -0700)
These fields are no longer indexed by shader output.  Now, we just have
a simple array of renderbuffer pointers.

If the shader writes to gl_FragData[i], send those colors to the N
_ColorDrawBuffers.  Otherwise, replicate the single gl_FragColor (or
the fixed-function color) to the N _ColorDrawBuffers.

A few more changes and simplifications can follow from this...

26 files changed:
src/mesa/drivers/dri/i915/intel_state.c
src/mesa/drivers/dri/i965/brw_fallback.c
src/mesa/drivers/dri/i965/brw_sf_state.c
src/mesa/drivers/dri/intel/intel_buffers.c
src/mesa/drivers/dri/intel/intel_span.c
src/mesa/drivers/dri/nouveau/nouveau_driver.c
src/mesa/drivers/dri/nouveau/nouveau_fbo.c
src/mesa/drivers/dri/r128/r128_state.c
src/mesa/drivers/dri/r200/r200_pixel.c
src/mesa/drivers/dri/r200/r200_span.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/drivers/x11/xm_line.c
src/mesa/drivers/x11/xm_tri.c
src/mesa/main/buffers.c
src/mesa/main/framebuffer.c
src/mesa/main/mtypes.h
src/mesa/swrast/s_accum.c
src/mesa/swrast/s_blit.c
src/mesa/swrast/s_buffers.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_copypix.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_span.c
src/mesa/swrast/s_triangle.c

index 4bcc9af2b606ec8971b156662911e636117e049d..d1ca11dec4f2f94254f16b64df2621634d908503 100644 (file)
@@ -234,7 +234,7 @@ intelCalcViewport(GLcontext * ctx)
    if (ctx->DrawBuffer->Name) {
       /* User created FBO */
       struct intel_renderbuffer *irb
-         = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
+         = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
       if (irb && !irb->RenderToTexture) {
          /* y=0=top */
          yScale = -1.0;
index 3c4c60a3eab33dc43597cd0fe2facfde7807b35d..58aeeb4228c9245585cca2adceaba514f70d5979 100644 (file)
@@ -62,12 +62,9 @@ static GLboolean do_check_fallback(struct brw_context *brw)
    /* We can only handle a single draw buffer at the moment, and only as the
     * first color buffer.
     */
-   for (i = 0; i < MAX_DRAW_BUFFERS; i++) {
-      if (fb->_NumColorDrawBuffers[i] > (i == 0 ? 1 : 0)) {
-        DBG("FALLBACK: draw buffer %d: 0x%08x\n",
-            i, ctx->DrawBuffer->_ColorDrawBufferMask[i]);
-        return GL_TRUE;
-      }
+   if (fb->_NumColorDrawBuffers > 1) {
+      DBG("FALLBACK: multiple color draw buffers\n");
+      return GL_TRUE;
    }
 
    /* _NEW_RENDERMODE
index 05c64909495f7caaa0e9cc74dc9f458bda92cb58..f083e3148b140fd493c6b0e59c0314a0f19a6011 100644 (file)
@@ -43,7 +43,7 @@ static void upload_sf_vp(struct brw_context *brw)
    const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
    struct brw_sf_viewport sfv;
    struct intel_renderbuffer *irb =
-      intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
+      intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
    GLfloat y_scale, y_bias;
 
    memset(&sfv, 0, sizeof(sfv));
index 78ffa3c1f84b00e59cf338473238be6a0d464dd7..c654474200be51e8c5230e2849adf78c1769bf12 100644 (file)
@@ -102,7 +102,7 @@ struct intel_region *
 intel_drawbuf_region(struct intel_context *intel)
 {
    struct intel_renderbuffer *irbColor =
-      intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]);
+      intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
    if (irbColor)
       return irbColor->region;
    else
@@ -931,7 +931,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
    /*
     * How many color buffers are we drawing into?
     */
-   if (fb->_NumColorDrawBuffers[0] != 1) {
+   if (fb->_NumColorDrawBuffers != 1) {
       /* writing to 0 or 2 or 4 color buffers */
       /*_mesa_debug(ctx, "Software rendering\n");*/
       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
@@ -967,7 +967,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
         /* drawing to user-created FBO */
         struct intel_renderbuffer *irb;
         intelSetRenderbufferClipRects(intel);
-        irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]);
+        irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
         colorRegion = (irb && irb->region) ? irb->region : NULL;
       }
    }
index 9ce4a184fd4065236d5aff7b75967a14c39764ed..298e453c428ae0faab8c58f62c0e8b3833f4f430 100644 (file)
@@ -186,21 +186,18 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
    struct intel_renderbuffer *irb;
 
    /* color draw buffers */
-   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
-      for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
-         struct gl_renderbuffer *rb =
-            ctx->DrawBuffer->_ColorDrawBuffers[i][j];
-         irb = intel_renderbuffer(rb);
-         if (irb) {
-            /* this is a user-created intel_renderbuffer */
-            if (irb->region) {
-               if (map)
-                  intel_region_map(intel, irb->region);
-               else
-                  intel_region_unmap(intel, irb->region);
-               irb->pfMap = irb->region->map;
-               irb->pfPitch = irb->region->pitch;
-            }
+   for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
+      irb = intel_renderbuffer(rb);
+      if (irb) {
+         /* this is a user-created intel_renderbuffer */
+         if (irb->region) {
+            if (map)
+               intel_region_map(intel, irb->region);
+            else
+               intel_region_unmap(intel, irb->region);
+            irb->pfMap = irb->region->map;
+            irb->pfPitch = irb->region->pitch;
          }
       }
    }
index 8b76779002bd8403cf5bcf591f1242285d5e619a..1135817fe9a9da450f4659b91ccc820e5e37b66c 100644 (file)
@@ -149,12 +149,12 @@ static void nouveauClear( GLcontext *ctx, GLbitfield mask )
                clear_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
 
                if (ctx->DrawBuffer) {
-                       /* FIXME: find correct color buffer, instead of [0][0] */
-                       if (ctx->DrawBuffer->_ColorDrawBuffers[0][0]) {
-                               color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0][0]->RedBits;
-                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->GreenBits;
-                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->BlueBits;
-                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->AlphaBits;
+                       /* FIXME: find correct color buffer, instead of [0] */
+                       if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
+                               color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0]->RedBits;
+                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->GreenBits;
+                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->BlueBits;
+                               color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->AlphaBits;
                        }
                }
 
index cc3da8b9bde853fc8cde72c5bf66e81d6c98ab9b..23525509d14388192d8762d8ff71acaa34f14854 100644 (file)
@@ -177,8 +177,7 @@ nouveau_window_moved(GLcontext * ctx)
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
        nouveau_renderbuffer_t *nrb;
 
-       nrb = (nouveau_renderbuffer_t *)
-               ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+       nrb = (nouveau_renderbuffer_t *) ctx->DrawBuffer->_ColorDrawBuffers[0];
        if (!nrb)
                return;
 
@@ -204,7 +203,7 @@ nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
        _mesa_update_framebuffer(ctx);
        _mesa_update_draw_buffer_bounds(ctx);
 
-       color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0][0];
+       color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0];
        if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
                depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped;
        else
index e476afa5d828a982d56173102e5cb2e6f0aeace7..f1e92d7a7a9ce3ef890e8044c1c2a3322c2ac31f 100644 (file)
@@ -813,7 +813,7 @@ static void r128UpdateWindow( GLcontext *ctx )
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    int x = rmesa->driDrawable->x;
    int y = rmesa->driDrawable->y;
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    driRenderbuffer *drb = (driRenderbuffer *) rb;
 
    rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
index 2f5aab0744b2be72a1c829240eae19ead412984c..db8ceeabe034292f3ae57e811508329bf1a73736 100644 (file)
@@ -294,7 +294,7 @@ static void do_draw_pix( GLcontext *ctx,
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
    drm_clip_rect_t *box = dPriv->pClipRects;
-   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0][0];
+   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0];
    driRenderbuffer *drb = (driRenderbuffer *) rb;
    int nbox = dPriv->numClipRects;
    int i;
@@ -388,7 +388,7 @@ r200TryDrawPixels( GLcontext *ctx,
       fprintf(stderr, "%s\n", __FUNCTION__);
 
    /* check that we're drawing to exactly one color buffer */
-   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1)
+   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1)
      return GL_FALSE;
 
    switch (format) {
index fe427bdcdecb383365bc4cecb0712bde5f5f5b57..ff2eb01122518b5535e38495e9504f4ba6974dc5 100644 (file)
@@ -255,7 +255,7 @@ static void r200SpanRenderStart( GLcontext *ctx )
    {
       int p;
       driRenderbuffer *drb =
-        (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0][0];
+        (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0];
       volatile int *buf =
         (volatile int *)(rmesa->dri.screen->pFB + drb->offset);
       p = *buf;
index 4c8bf5f656d099530cb05faf930aebb721ceaae6..e7d41401f9aa5723efb3b57a87146db73423a8b3 100644 (file)
@@ -435,7 +435,7 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
                          const GLvoid *pixels )
 {
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped);
 
    if (swrast->NewState)
@@ -544,7 +544,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
                          const GLvoid *pixels )
 {
    struct xmesa_renderbuffer *xrb
-      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
    XMesaDisplay *dpy = xmesa->xm_visual->display;
@@ -654,7 +654,7 @@ xmesa_CopyPixels( GLcontext *ctx,
    struct xmesa_renderbuffer *srcXrb
       = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped);
    struct xmesa_renderbuffer *dstXrb
-      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
 
    ASSERT(dpy);
    ASSERT(gc);
index deeae5019c4dbfea323ed3a8e1dd281ca8732cd9..7109c43915700a8ccf51ebc9d6bdb8c1ef6dc773 100644 (file)
@@ -121,7 +121,7 @@ void xmesa_choose_point( GLcontext *ctx )
 
 
 #define GET_XRB(XRB)  struct xmesa_renderbuffer *XRB = \
-   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
+   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
 
 
 /*
@@ -598,7 +598,7 @@ get_line_func(GLcontext *ctx)
    if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
    if (xmbuf->swAlpha)                    return (swrast_line_func) NULL;
 
-   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
 
    if (xrb->ximage
        && swrast->_RasterMask==DEPTH_BIT
@@ -661,7 +661,7 @@ get_line_func(GLcontext *ctx)
    }
 
 #ifndef XFree86Server
-   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1
+   if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
        && ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT
        && swrast->_RasterMask == LOGIC_OP_BIT
        && ctx->Color.LogicOp == GL_XOR
index 95c6d7c1d20a80faa234d4d2f64485c953771001..a3978abdd070ba90241d9dadd4258abba6d85dce 100644 (file)
@@ -45,7 +45,7 @@
 
 
 #define GET_XRB(XRB)  struct xmesa_renderbuffer *XRB = \
-   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
+   xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
 
 
 /**********************************************************************/
@@ -1479,7 +1479,7 @@ get_triangle_func(GLcontext *ctx)
    if (xmbuf->swAlpha)
       return (swrast_tri_func) NULL;
 
-   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+   xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
 
    if (xrb->ximage) {
       if (   ctx->Light.ShadeModel==GL_SMOOTH
index 0fba73b3c2f541b24caaaf73461dd432fa0e68e0..2252bbd4c5185b897cd665a8c12803e6e4a26a1c 100644 (file)
@@ -508,8 +508,9 @@ set_color_output(GLcontext *ctx, GLuint output, GLenum buffer,
    /* Set per-FBO state */
    fb->ColorDrawBuffer[output] = buffer;
    fb->_ColorDrawBufferMask[output] = destMask;
-   /* not really needed, will be set later */
-   fb->_NumColorDrawBuffers[output] = 0;
+
+   /* this will be computed later, but zero to be safe */
+   fb->_NumColorDrawBuffers = 0;
 
    if (fb->Name == 0) {
       /* Only set the per-context DrawBuffer state if we're currently
index 3e36197d884fbf990a77af87de4376d91a6ef17e..8f92fd3b42b2b15f888ce8cc38aaca568cbaf5a5 100644 (file)
@@ -583,6 +583,51 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
 }
 
 
+/*
+ * Example DrawBuffers scenarios:
+ *
+ * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
+ * "gl_FragColor" or program writes to the "result.color" register:
+ *
+ *   fragment color output   renderbuffer
+ *   ---------------------   ---------------
+ *   color[0]                Front, Back
+ *
+ *
+ * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
+ * gl_FragData[i] or program writes to result.color[i] registers:
+ *
+ *   fragment color output   renderbuffer
+ *   ---------------------   ---------------
+ *   color[0]                Front
+ *   color[1]                Aux0
+ *   color[3]                Aux1
+ *
+ *
+ * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
+ * gl_FragColor, or fixed function:
+ *
+ *   fragment color output   renderbuffer
+ *   ---------------------   ---------------
+ *   color[0]                Front, Aux0, Aux1
+ *
+ *
+ * In either case, the list of renderbuffers is stored in the
+ * framebuffer->_ColorDrawBuffers[] array and
+ * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
+ * The renderer (like swrast) has to look at the current fragment shader
+ * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
+ * how to map color outputs to renderbuffers.
+ *
+ * Note that these two calls are equivalent (for fixed function fragment
+ * shading anyway):
+ *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
+ *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
+ */
+
+
+
+
 /**
  * Update the (derived) list of color drawing renderbuffer pointers.
  * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
@@ -591,39 +636,39 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
 static void
 update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
 {
-   GLuint output;
+   GLuint output, count = 0;
 
-   /*
-    * Fragment programs can write to multiple colorbuffers with
-    * the GL_ARB_draw_buffers extension.
+   /* First, interpret _ColorDrawBufferMask[] in the manner that would be
+    * used if the fragment program/shader writes to gl_FragData[]
     */
    for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
-      GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
-      GLuint count = 0;
+      GLuint buf = _mesa_ffs(fb->_ColorDrawBufferMask[output]);
+      if (buf) {
+         struct gl_renderbuffer *rb = fb->Attachment[buf - 1].Renderbuffer;
+         fb->_ColorDrawBuffers[output] = rb; /* may be NULL */
+         if (rb)
+            count = output + 1;
+      }
+   }
+
+   /* Second, handle the GL_FRONT_AND_BACK case, overwriting the above
+    * if needed.
+    */
+   GLbitfield bufferMask = fb->_ColorDrawBufferMask[0];
+   if (_mesa_bitcount(bufferMask) > 1) {
       GLuint i;
-      if (!fb->DeletePending) {
-         /* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
-          * can specify writing to two or four color buffers (for example).
-          */
-         for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
-            const GLuint bufferBit = 1 << i;
-            if (bufferBit & bufferMask) {
-               struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
-               if (rb && rb->Width > 0 && rb->Height > 0) {
-                  fb->_ColorDrawBuffers[output][count] = rb;
-                  count++;
-               }
-               else {
-                  /*
-                  _mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");
-                  */
-               }
-               bufferMask &= ~bufferBit;
-            }
+      count = 0;
+      for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
+         if (bufferMask & (1 << i)) {
+            struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
+            fb->_ColorDrawBuffers[count] = rb;
+            count++;
          }
+         bufferMask &= ~(1 << i);
       }
-      fb->_NumColorDrawBuffers[output] = count;
    }
+                               
+   fb->_NumColorDrawBuffers = count;
 }
 
 
index 0da487ea044d88c5b129731b5c639dbea99d2861..0e7364c08fa70e7116c67ccdabdfe0c4bbdcfc5a 100644 (file)
@@ -2400,8 +2400,8 @@ struct gl_framebuffer
    GLint _ColorReadBufferIndex; /* -1 = None */
 
    /* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */
-   GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS];
-   struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
+   GLuint _NumColorDrawBuffers;
+   struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
    struct gl_renderbuffer *_ColorReadBuffer;
 
    /** The Actual depth/stencil buffers to use.  May be wrappers around the
index 3c45dee3998382fb9c815ba36adae3b5c411da1a..b74f794d09060d0717f350b64292befd5faf38fc 100644 (file)
@@ -525,8 +525,8 @@ accum_return(GLcontext *ctx, GLfloat value,
          }
 
          /* store colors */
-         for (buffer = 0; buffer < fb->_NumColorDrawBuffers[0]; buffer++) {
-            struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[0][buffer];
+         for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
+            struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer];
             if (masking) {
                _swrast_mask_rgba_span(ctx, rb, &span);
             }
index 5aec4aad03567ce7de874d526963a678ee7953f8..a2c40bd9a6b30f58a29d570c7b5998ea35483ddf 100644 (file)
@@ -135,7 +135,7 @@ blit_nearest(GLcontext *ctx,
    switch (buffer) {
    case GL_COLOR_BUFFER_BIT:
       readRb = ctx->ReadBuffer->_ColorReadBuffer;
-      drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+      drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
       comps = 4;
       break;
    case GL_DEPTH_BUFFER_BIT:
@@ -319,7 +319,7 @@ blit_linear(GLcontext *ctx,
             GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
 {
    struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
-   struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
 
    const GLint srcWidth = ABS(srcX1 - srcX0);
    const GLint dstWidth = ABS(dstX1 - dstX0);
@@ -493,7 +493,7 @@ simple_blit(GLcontext *ctx,
    switch (buffer) {
    case GL_COLOR_BUFFER_BIT:
       readRb = ctx->ReadBuffer->_ColorReadBuffer;
-      drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+      drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
       comps = 4;
       break;
    case GL_DEPTH_BUFFER_BIT:
index 90a56284c51d96a187ca63c29e4f5fe6da93547a..b74c4ab1c8c27db68efe330b665591a4ae38fada 100644 (file)
@@ -251,7 +251,7 @@ static void
 clear_color_buffers(GLcontext *ctx)
 {
    GLboolean masking;
-   GLuint i;
+   GLuint buf;
 
    if (ctx->Visual.rgbMode) {
       if (ctx->Color.ColorMask[0] && 
@@ -265,7 +265,7 @@ clear_color_buffers(GLcontext *ctx)
       }
    }
    else {
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
       const GLuint indexBits = (1 << rb->IndexBits) - 1;
       if ((ctx->Color.IndexMask & indexBits) == indexBits) {
          masking = GL_FALSE;
@@ -275,8 +275,8 @@ clear_color_buffers(GLcontext *ctx)
       }
    }
 
-   for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers[0]; i++) {
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][i];
+   for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
       if (ctx->Visual.rgbMode) {
          if (masking) {
             clear_rgba_buffer_with_masking(ctx, rb);
@@ -331,7 +331,7 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)
 
    /* do software clearing here */
    if (buffers) {
-      if (buffers & ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
+      if (buffers & ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
          clear_color_buffers(ctx);
       }
       if (buffers & BUFFER_BIT_DEPTH) {
index 314931d46763965fb5b876798f6b33799bbd8ea9..8e6b28bb4c6e8523a8edd5666eed782fcf2d3455 100644 (file)
@@ -87,7 +87,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
     * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
     * buffers or the RGBA or CI mask disables all writes.
     */
-   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) {
+   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
       /* more than one color buffer designated for writing (or zero buffers) */
       rasterMask |= MULTI_DRAW_BIT;
    }
@@ -596,44 +596,6 @@ _swrast_update_active_attribs(GLcontext *ctx)
 }
 
 
-/**
- * Update the swrast->_ColorOutputsMask which indicates which color
- * renderbuffers (aka rendertargets) are being written to by the current
- * fragment program.
- * We also take glDrawBuffers() into account to skip outputs that are
- * set to GL_NONE.
- */
-static void
-_swrast_update_color_outputs(GLcontext *ctx)
-{
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const struct gl_framebuffer *fb = ctx->DrawBuffer;
-
-   swrast->_ColorOutputsMask = 0;
-   swrast->_NumColorOutputs = 0;
-
-   if (ctx->FragmentProgram._Current) {
-      const GLbitfield outputsWritten
-         = ctx->FragmentProgram._Current->Base.OutputsWritten;
-      GLuint output;
-      for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
-         if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output)))
-             && (fb->_NumColorDrawBuffers[output] > 0)) {
-            swrast->_ColorOutputsMask |= (1 << output);
-            swrast->_NumColorOutputs = output + 1;
-         }
-      }
-   }
-   if (swrast->_ColorOutputsMask == 0x0) {
-      /* no fragment program, or frag prog didn't write to gl_FragData[] */
-      if (fb->_NumColorDrawBuffers[0] > 0) {
-         swrast->_ColorOutputsMask = 0x1;
-         swrast->_NumColorOutputs = 1;
-      }
-   }
-}
-
-
 void
 _swrast_validate_derived( GLcontext *ctx )
 {
@@ -683,9 +645,6 @@ _swrast_validate_derived( GLcontext *ctx )
                               _NEW_TEXTURE))
          _swrast_update_active_attribs(ctx);
 
-      if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
-         _swrast_update_color_outputs(ctx);
-
       swrast->NewState = 0;
       swrast->StateChanges = 0;
       swrast->InvalidateState = _swrast_invalidate_state;
index aebc80c2080ea10645943e465cda1688b7e6a956..3dcc3ed16e2080d753d4abb0eedd42c273869d2d 100644 (file)
@@ -136,10 +136,6 @@ typedef struct
    GLboolean _DeferredTexture;
    GLenum _FogMode;  /* either GL_FOG_MODE or fragment program's fog mode */
 
-   /** Multiple render targets */
-   GLbitfield _ColorOutputsMask;
-   GLuint _NumColorOutputs;
-
    /** List/array of the fragment attributes to interpolate */
    GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
    /** Same info, but as a bitmask */
index 218a3b5590bddb26e851beffe2b08e7c43093697..3962721a61cf12f032c00394821eac6d836dd94d 100644 (file)
@@ -830,10 +830,10 @@ fast_copy_pixels(GLcontext *ctx,
    }
 
    if (type == GL_COLOR) {
-      if (dstFb->_NumColorDrawBuffers[0] != 1)
+      if (dstFb->_NumColorDrawBuffers != 1)
          return GL_FALSE;
       srcRb = srcFb->_ColorReadBuffer;
-      dstRb = dstFb->_ColorDrawBuffers[0][0];
+      dstRb = dstFb->_ColorDrawBuffers[0];
    }
    else if (type == GL_STENCIL) {
       srcRb = srcFb->_StencilBuffer;
index 969787381c24e4c3511903937f2758a1d5acde76..7bab14f200eefd663734a1580ec17603cef341dd 100644 (file)
@@ -53,7 +53,7 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
                       const GLvoid *pixels)
 {
    const GLint imgX = x, imgY = y;
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    const GLenum rbType = rb->DataType;
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan span;
@@ -608,8 +608,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                        IMAGE_POST_CONVOLUTION_SCALE_BIAS);
    }
 
-   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] > 0 &&
-       ctx->DrawBuffer->_ColorDrawBuffers[0][0]->DataType != GL_FLOAT &&
+   if (ctx->DrawBuffer->_NumColorDrawBuffers > 0 &&
+       ctx->DrawBuffer->_ColorDrawBuffers[0]->DataType != GL_FLOAT &&
        ctx->Color.ClampFragmentColor != GL_FALSE) {
       /* need to clamp colors before applying fragment ops */
       transferOps |= IMAGE_CLAMP_BIT;
index 76c79eb0d81694da840b242af1e907890a669bf4..2dfc033d5012f0fbba9edf8fe66ab094dacef24b 100644 (file)
@@ -167,11 +167,11 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
                 * Note that colors beyond 0 and 1 will overwrite other
                 * attributes, such as FOGC, TEX0, TEX1, etc.  That's OK.
                 */
-               GLuint output;
-               for (output = 0; output < swrast->_NumColorOutputs; output++) {
-                  if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) {
-                     COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i],
-                             machine->Outputs[FRAG_RESULT_DATA0 + output]);
+               GLuint buf;
+               for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
+                  if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + buf))) {
+                     COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i],
+                             machine->Outputs[FRAG_RESULT_DATA0 + buf]);
                   }
                }
             }
index 000e192a4a52cefbf150e47cec7ce3b3a8beae1f..d40457927905658eceb28091fe6a8ee5fbbda6e4 100644 (file)
@@ -792,6 +792,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
 
    ASSERT(span->end <= MAX_WIDTH);
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
@@ -818,7 +819,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
    }
 
    /* Depth bounds test */
-   if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) {
+   if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {
       if (!_swrast_depth_bounds_test(ctx, span)) {
          return;
       }
@@ -830,10 +831,10 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
       GLuint i;
       for (i = 0; i < span->end; i++) {
          if (span->array->mask[i]) {
-            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
-            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
-            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
-            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+            assert(span->array->x[i] >= fb->_Xmin);
+            assert(span->array->x[i] < fb->_Xmax);
+            assert(span->array->y[i] >= fb->_Ymin);
+            assert(span->array->y[i] < fb->_Ymax);
          }
       }
    }
@@ -912,22 +913,21 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
     * Write to renderbuffers
     */
    {
-      struct gl_framebuffer *fb = ctx->DrawBuffer;
-      const GLuint output = 0; /* only frag progs can write to other outputs */
-      const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
-      GLuint indexSave[MAX_WIDTH];
+      const GLuint numBuffers = fb->_NumColorDrawBuffers;
       GLuint buf;
 
-      if (numDrawBuffers > 1) {
-         /* save indexes for second, third renderbuffer writes */
-         _mesa_memcpy(indexSave, span->array->index,
-                      span->end * sizeof(indexSave[0]));
-      }
+      for (buf = 0; buf < numBuffers; buf++) {
+         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
+         GLuint indexSave[MAX_WIDTH];
 
-      for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
-         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
          ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
 
+         if (numBuffers > 1) {
+            /* save indexes for second, third renderbuffer writes */
+            _mesa_memcpy(indexSave, span->array->index,
+                         span->end * sizeof(indexSave[0]));
+         }
+
          if (ctx->Color.IndexLogicOpEnabled) {
             _swrast_logicop_ci_span(ctx, rb, span);
          }
@@ -1002,7 +1002,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
             }
          }
 
-         if (buf + 1 < numDrawBuffers) {
+         if (buf + 1 < numBuffers) {
             /* restore original span values */
             _mesa_memcpy(span->array->index, indexSave,
                          span->end * sizeof(indexSave[0]));
@@ -1119,7 +1119,7 @@ clamp_colors(SWspan *span)
 
 /**
  * Convert the span's color arrays to the given type.
- * The only way 'output' can be greater than one is when we have a fragment
+ * The only way 'output' can be greater than zero is when we have a fragment
  * program that writes to gl_FragData[1] or higher.
  * \param output  which fragment program color output is being processed
  */
@@ -1249,7 +1249,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
                              || ctx->ATIFragmentShader._Enabled);
    const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
-   GLuint output;
 
    /*
    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
@@ -1399,67 +1398,69 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
    /*
     * Write to renderbuffers
     */
-   /* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */
-   for (output = 0; output < swrast->_NumColorOutputs; output++) {
-      if (swrast->_ColorOutputsMask & (1 << output)) {
-        const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
-        GLchan rgbaSave[MAX_WIDTH][4];
-        GLuint buf;
-
-        ASSERT(numDrawBuffers > 0);
-
-        if (fb->_ColorDrawBuffers[output][0]->DataType
-            != span->array->ChanType || output > 0) {
-           convert_color_type(span,
-                              fb->_ColorDrawBuffers[output][0]->DataType,
-                              output);
-        }
-
-        if (numDrawBuffers > 1) {
-           /* save colors for second, third renderbuffer writes */
-           _mesa_memcpy(rgbaSave, span->array->rgba,
-                        4 * span->end * sizeof(GLchan));
-        }
-
-        /* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */
-        for (buf = 0; buf < numDrawBuffers; buf++) {
-           struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
-           ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
-
-           if (ctx->Color._LogicOpEnabled) {
-              _swrast_logicop_rgba_span(ctx, rb, span);
-           }
-           else if (ctx->Color.BlendEnabled) {
-              _swrast_blend_span(ctx, rb, span);
-           }
-
-           if (colorMask != 0xffffffff) {
-              _swrast_mask_rgba_span(ctx, rb, span);
-           }
-
-           if (span->arrayMask & SPAN_XY) {
-              /* array of pixel coords */
-              ASSERT(rb->PutValues);
-              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);
-              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 */
-      } /* if output is written to */
-   } /* for output */
+   {
+      const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+      const GLboolean multiFragOutputs
+         = fp && fp->Base.InputsRead >= (1 << FRAG_RESULT_DATA0);
+      const GLuint numBuffers = fb->_NumColorDrawBuffers;
+      GLuint buf;
+
+      for (buf = 0; buf < numBuffers; buf++) {
+         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
+
+         /* color[fragOutput] will be written to buffer[buf] */
+
+         if (rb) {
+            GLchan rgbaSave[MAX_WIDTH][4];
+            const GLuint fragOutput = multiFragOutputs ? buf : 0;
+
+            if (rb->DataType != span->array->ChanType || fragOutput > 0) {
+               convert_color_type(span, rb->DataType, fragOutput);
+            }
+
+            if (!multiFragOutputs && numBuffers > 1) {
+               /* save colors for second, third renderbuffer writes */
+               _mesa_memcpy(rgbaSave, span->array->rgba,
+                            4 * span->end * sizeof(GLchan));
+            }
+
+            ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
+
+            if (ctx->Color._LogicOpEnabled) {
+               _swrast_logicop_rgba_span(ctx, rb, span);
+            }
+            else if (ctx->Color.BlendEnabled) {
+               _swrast_blend_span(ctx, rb, span);
+            }
+
+            if (colorMask != 0xffffffff) {
+               _swrast_mask_rgba_span(ctx, rb, span);
+            }
+
+            if (span->arrayMask & SPAN_XY) {
+               /* array of pixel coords */
+               ASSERT(rb->PutValues);
+               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);
+               rb->PutRow(ctx, rb, span->end, span->x, span->y,
+                          span->array->rgba,
+                          span->writeAll ? NULL: span->array->mask);
+            }
+
+            if (!multiFragOutputs && numBuffers > 1) {
+               /* restore original span values */
+               _mesa_memcpy(span->array->rgba, rgbaSave,
+                            4 * span->end * sizeof(GLchan));
+            }
+
+         } /* if rb */
+      } /* for buf */
+   }
 
 end:
    /* restore these values before returning */
index 938cdefa561450b83034d499b3e82821bdc4e0ae..5036020b7c48665c4c91afbd988637c08a0568a6 100644 (file)
@@ -130,7 +130,7 @@ _swrast_culltriangle( GLcontext *ctx,
 #define T_SCALE theight
 
 #define SETUP_CODE                                                     \
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
    struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    const GLint b = obj->BaseLevel;                                     \
    const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
@@ -182,7 +182,7 @@ _swrast_culltriangle( GLcontext *ctx,
 #define T_SCALE theight
 
 #define SETUP_CODE                                                     \
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
    struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    const GLint b = obj->BaseLevel;                                     \
    const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \