From ff73c783cc47361ff0dd819c82d067b4b85870dd Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 6 Jan 2008 10:43:20 -0700 Subject: [PATCH] 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... --- src/mesa/drivers/dri/i915/intel_state.c | 2 +- src/mesa/drivers/dri/i965/brw_fallback.c | 9 +- src/mesa/drivers/dri/i965/brw_sf_state.c | 2 +- src/mesa/drivers/dri/intel/intel_buffers.c | 6 +- src/mesa/drivers/dri/intel/intel_span.c | 27 ++- src/mesa/drivers/dri/nouveau/nouveau_driver.c | 12 +- src/mesa/drivers/dri/nouveau/nouveau_fbo.c | 5 +- src/mesa/drivers/dri/r128/r128_state.c | 2 +- src/mesa/drivers/dri/r200/r200_pixel.c | 4 +- src/mesa/drivers/dri/r200/r200_span.c | 2 +- src/mesa/drivers/x11/xm_dd.c | 6 +- src/mesa/drivers/x11/xm_line.c | 6 +- src/mesa/drivers/x11/xm_tri.c | 4 +- src/mesa/main/buffers.c | 5 +- src/mesa/main/framebuffer.c | 97 ++++++++--- src/mesa/main/mtypes.h | 4 +- src/mesa/swrast/s_accum.c | 4 +- src/mesa/swrast/s_blit.c | 6 +- src/mesa/swrast/s_buffers.c | 10 +- src/mesa/swrast/s_context.c | 43 +---- src/mesa/swrast/s_context.h | 4 - src/mesa/swrast/s_copypix.c | 4 +- src/mesa/swrast/s_drawpix.c | 6 +- src/mesa/swrast/s_fragprog.c | 10 +- src/mesa/swrast/s_span.c | 161 +++++++++--------- src/mesa/swrast/s_triangle.c | 4 +- 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 4bcc9af2b60..d1ca11dec4f 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 3c4c60a3eab..58aeeb4228c 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 05c64909495..f083e3148b1 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 78ffa3c1f84..c654474200b 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 9ce4a184fd4..298e453c428 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 8b76779002b..1135817fe9a 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 cc3da8b9bde..23525509d14 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 e476afa5d82..f1e92d7a7a9 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 2f5aab0744b..db8ceeabe03 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 fe427bdcdec..ff2eb011225 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 4c8bf5f656d..e7d41401f9a 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 deeae5019c4..7109c439157 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 95c6d7c1d20..a3978abdd07 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 0fba73b3c2f..2252bbd4c51 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 3e36197d884..8f92fd3b42b 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 0da487ea044..0e7364c08fa 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 3c45dee3998..b74f794d090 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 5aec4aad035..a2c40bd9a6b 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 90a56284c51..b74c4ab1c8c 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 314931d4676..8e6b28bb4c6 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 aebc80c2080..3dcc3ed16e2 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 218a3b5590b..3962721a61c 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 969787381c2..7bab14f200e 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 76c79eb0d81..2dfc033d501 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 000e192a4a5..d4045792790 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 938cdefa561..5036020b7c4 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; \ -- 2.30.2