From 601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedaf Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 6 Jan 2008 18:07:26 -0700 Subject: Replace gl_framebuffer's _ColorDrawBufferMask with _ColorDrawBufferIndexes Each array element is now a BUFFER_x token rather than a BUFFER_BIT_x bitmask. The number of active color buffers is specified by _NumColorDrawBuffers. This builds on the previous DrawBuffer changes and will help with drivers implementing GL_ARB_draw_buffers. --- src/mesa/main/buffers.c | 89 ++++++++++++++++++++++----------------------- src/mesa/main/framebuffer.c | 45 +++++++---------------- src/mesa/main/mtypes.h | 8 ++-- 3 files changed, 60 insertions(+), 82 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 2252bbd4c5..2099977291 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -159,7 +159,10 @@ _mesa_Clear( GLbitfield mask ) */ bufferMask = 0; if (mask & GL_COLOR_BUFFER_BIT) { - bufferMask |= ctx->DrawBuffer->_ColorDrawBufferMask[0]; + GLuint i; + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); + } } if ((mask & GL_DEPTH_BUFFER_BIT) @@ -486,41 +489,6 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) } -/** - * Set color output state. Traditionally, there was only one color - * output, but fragment programs can now have several distinct color - * outputs (see GL_ARB_draw_buffers). This function sets the state - * for one such color output. - * \param ctx current context - * \param output which fragment program output - * \param buffer buffer to write to (like GL_LEFT) - * \param destMask BUFFER_* bitmask - * (like BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). - */ -static void -set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, - GLbitfield destMask) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - - ASSERT(output < ctx->Const.MaxDrawBuffers); - - /* Set per-FBO state */ - fb->ColorDrawBuffer[output] = buffer; - fb->_ColorDrawBufferMask[output] = destMask; - - /* 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 - * drawing to a window system framebuffer. - */ - ctx->Color.DrawBuffer[output] = buffer; - } -} - - /** * Helper function to set the GL_DRAW_BUFFER state in the context and * current FBO. @@ -531,7 +499,7 @@ set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, * \param ctx current context * \param n number of color outputs to set * \param buffers array[n] of colorbuffer names, like GL_LEFT. - * \param destMask array[n] of BUFFER_* bitmasks which correspond to the + * \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the * colorbuffer names. (i.e. GL_FRONT_AND_BACK => * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). */ @@ -539,13 +507,13 @@ void _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, const GLbitfield *destMask) { + struct gl_framebuffer *fb = ctx->DrawBuffer; GLbitfield mask[MAX_DRAW_BUFFERS]; - GLuint output; if (!destMask) { /* compute destMask values now */ - const GLbitfield supportedMask - = supported_buffer_bitmask(ctx, ctx->DrawBuffer); + const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); + GLuint output; for (output = 0; output < n; output++) { mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); ASSERT(mask[output] != BAD_MASK); @@ -554,13 +522,44 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, destMask = mask; } - for (output = 0; output < n; output++) { - set_color_output(ctx, output, buffers[output], destMask[output]); + if (n == 1) { + GLuint buf, count = 0; + /* init to -1 to help catch errors */ + fb->_ColorDrawBufferIndexes[0] = -1; + for (buf = 0; buf < BUFFER_COUNT; buf++) { + if (destMask[0] & (1 << buf)) { + fb->_ColorDrawBufferIndexes[count] = buf; + count++; + } + } + fb->ColorDrawBuffer[0] = buffers[0]; + fb->_NumColorDrawBuffers = count; + } + else { + GLuint buf, count = 0; + for (buf = 0; buf < n; buf++ ) { + if (destMask[buf]) { + fb->_ColorDrawBufferIndexes[buf] = _mesa_ffs(destMask[buf]) - 1; + count = buf + 1; + } + else { + fb->_ColorDrawBufferIndexes[buf] = -1; + } + } + /* set remaining outputs to -1 (GL_NONE) */ + while (buf < ctx->Const.MaxDrawBuffers) { + fb->_ColorDrawBufferIndexes[buf] = -1; + buf++; + } + fb->_NumColorDrawBuffers = count; } - /* set remaining color outputs to NONE */ - for (output = n; output < ctx->Const.MaxDrawBuffers; output++) { - set_color_output(ctx, output, GL_NONE, 0x0); + if (fb->Name == 0) { + /* also set context drawbuffer state */ + GLuint buf; + for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { + ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; + } } ctx->NewState |= _NEW_COLOR; diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 8f92fd3b42..06a3457488 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -109,8 +109,9 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) if (fb) { fb->Name = name; fb->RefCount = 1; + fb->_NumColorDrawBuffers = 1; fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; - fb->_ColorDrawBufferMask[0] = BUFFER_BIT_COLOR0; + fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; fb->_ColorReadBufferIndex = BUFFER_COLOR0; fb->Delete = _mesa_destroy_framebuffer; @@ -141,14 +142,16 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) /* Init read/draw renderbuffer state */ if (visual->doubleBufferMode) { + fb->_NumColorDrawBuffers = 1; fb->ColorDrawBuffer[0] = GL_BACK; - fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT; + fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT; fb->ColorReadBuffer = GL_BACK; fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT; } else { + fb->_NumColorDrawBuffers = 1; fb->ColorDrawBuffer[0] = GL_FRONT; - fb->_ColorDrawBufferMask[0] = BUFFER_BIT_FRONT_LEFT; + fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT; fb->ColorReadBuffer = GL_FRONT; fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT; } @@ -636,39 +639,17 @@ _mesa_update_stencil_buffer(GLcontext *ctx, static void update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb) { - GLuint output, count = 0; + GLuint output; - /* 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++) { - 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; + for (output = 0; output < fb->_NumColorDrawBuffers; output++) { + GLint buf = fb->_ColorDrawBufferIndexes[output]; + if (buf >= 0) { + fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer; } - } - - /* 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; - 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); + else { + fb->_ColorDrawBuffers[output] = NULL; } } - - fb->_NumColorDrawBuffers = count; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0e7364c08f..c8718a7f63 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2395,12 +2395,10 @@ struct gl_framebuffer GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS]; GLenum ColorReadBuffer; - /* These are computed from ColorDrawBuffer and ColorReadBuffer */ - GLbitfield _ColorDrawBufferMask[MAX_DRAW_BUFFERS]; /* Mask of BUFFER_BIT_* flags */ - GLint _ColorReadBufferIndex; /* -1 = None */ - - /* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */ + /** Computed from ColorDraw/ReadBuffer above */ GLuint _NumColorDrawBuffers; + GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */ + GLint _ColorReadBufferIndex; /* -1 = None */ struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS]; struct gl_renderbuffer *_ColorReadBuffer; -- cgit v1.2.3