summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/buffers.c5
-rw-r--r--src/mesa/main/framebuffer.c97
-rw-r--r--src/mesa/main/mtypes.h4
3 files changed, 76 insertions, 30 deletions
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