summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/buffers.c89
-rw-r--r--src/mesa/main/framebuffer.c45
-rw-r--r--src/mesa/main/mtypes.h8
3 files changed, 60 insertions, 82 deletions
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)
@@ -487,41 +490,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;