summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-01-06 10:43:20 -0700
committerBrian <brian.paul@tungstengraphics.com>2008-01-06 10:43:20 -0700
commitff73c783cc47361ff0dd819c82d067b4b85870dd (patch)
tree07706ff913e0db3164ab62eba430938f72efae85
parent9f6022d0567dc1288888212d7128acc48795b306 (diff)
Simplify ctx->_NumColorDrawBuffers, _ColorDrawBuffers and fix bug 13835.
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...
-rw-r--r--src/mesa/drivers/dri/i915/intel_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fallback.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffers.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c27
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.c12
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fbo.c5
-rw-r--r--src/mesa/drivers/dri/r128/r128_state.c2
-rw-r--r--src/mesa/drivers/dri/r200/r200_pixel.c4
-rw-r--r--src/mesa/drivers/dri/r200/r200_span.c2
-rw-r--r--src/mesa/drivers/x11/xm_dd.c6
-rw-r--r--src/mesa/drivers/x11/xm_line.c6
-rw-r--r--src/mesa/drivers/x11/xm_tri.c4
-rw-r--r--src/mesa/main/buffers.c5
-rw-r--r--src/mesa/main/framebuffer.c97
-rw-r--r--src/mesa/main/mtypes.h4
-rw-r--r--src/mesa/swrast/s_accum.c4
-rw-r--r--src/mesa/swrast/s_blit.c6
-rw-r--r--src/mesa/swrast/s_buffers.c10
-rw-r--r--src/mesa/swrast/s_context.c43
-rw-r--r--src/mesa/swrast/s_context.h4
-rw-r--r--src/mesa/swrast/s_copypix.c4
-rw-r--r--src/mesa/swrast/s_drawpix.c6
-rw-r--r--src/mesa/swrast/s_fragprog.c10
-rw-r--r--src/mesa/swrast/s_span.c161
-rw-r--r--src/mesa/swrast/s_triangle.c4
26 files changed, 220 insertions, 225 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_state.c b/src/mesa/drivers/dri/i915/intel_state.c
index 4bcc9af2b6..d1ca11dec4 100644
--- a/src/mesa/drivers/dri/i915/intel_state.c
+++ b/src/mesa/drivers/dri/i915/intel_state.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c
index 3c4c60a3ea..58aeeb4228 100644
--- a/src/mesa/drivers/dri/i965/brw_fallback.c
+++ b/src/mesa/drivers/dri/i965/brw_fallback.c
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 05c6490949..f083e3148b 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -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));
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 78ffa3c1f8..c654474200 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -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;
}
}
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 9ce4a184fd..298e453c42 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -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;
}
}
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
index 8b76779002..1135817fe9 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
@@ -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;
}
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
index cc3da8b9bd..23525509d1 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
@@ -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
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index e476afa5d8..f1e92d7a7a 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -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) |
diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c
index 2f5aab0744..db8ceeabe0 100644
--- a/src/mesa/drivers/dri/r200/r200_pixel.c
+++ b/src/mesa/drivers/dri/r200/r200_pixel.c
@@ -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) {
diff --git a/src/mesa/drivers/dri/r200/r200_span.c b/src/mesa/drivers/dri/r200/r200_span.c
index fe427bdcde..ff2eb01122 100644
--- a/src/mesa/drivers/dri/r200/r200_span.c
+++ b/src/mesa/drivers/dri/r200/r200_span.c
@@ -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;
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 4c8bf5f656..e7d41401f9 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -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);
diff --git a/src/mesa/drivers/x11/xm_line.c b/src/mesa/drivers/x11/xm_line.c
index deeae5019c..7109c43915 100644
--- a/src/mesa/drivers/x11/xm_line.c
+++ b/src/mesa/drivers/x11/xm_line.c
@@ -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
diff --git a/src/mesa/drivers/x11/xm_tri.c b/src/mesa/drivers/x11/xm_tri.c
index 95c6d7c1d2..a3978abdd0 100644
--- a/src/mesa/drivers/x11/xm_tri.c
+++ b/src/mesa/drivers/x11/xm_tri.c
@@ -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
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 0fba73b3c2..2252bbd4c5 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -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
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 3e36197d88..8f92fd3b42 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -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;
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 0da487ea04..0e7364c08f 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -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
diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c
index 3c45dee399..b74f794d09 100644
--- a/src/mesa/swrast/s_accum.c
+++ b/src/mesa/swrast/s_accum.c
@@ -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);
}
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c
index 5aec4aad03..a2c40bd9a6 100644
--- a/src/mesa/swrast/s_blit.c
+++ b/src/mesa/swrast/s_blit.c
@@ -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:
diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c
index 90a56284c5..b74c4ab1c8 100644
--- a/src/mesa/swrast/s_buffers.c
+++ b/src/mesa/swrast/s_buffers.c
@@ -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) {
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 314931d467..8e6b28bb4c 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -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;
diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h
index aebc80c208..3dcc3ed16e 100644
--- a/src/mesa/swrast/s_context.h
+++ b/src/mesa/swrast/s_context.h
@@ -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 */
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 218a3b5590..3962721a61 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -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;
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 969787381c..7bab14f200 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -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;
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 76c79eb0d8..2dfc033d50 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -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]);
}
}
}
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 000e192a4a..d404579279 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -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 */
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 938cdefa56..5036020b7c 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -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; \