summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/buffers.c194
1 files changed, 139 insertions, 55 deletions
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 3415a2b9b5..e0db6712a6 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -35,6 +35,7 @@
#include "context.h"
#include "depth.h"
#include "enums.h"
+#include "fbobject.h"
#include "stencil.h"
#include "state.h"
#include "mtypes.h"
@@ -294,33 +295,52 @@ read_buffer_enum_to_bitmask(GLenum buffer)
void GLAPIENTRY
_mesa_DrawBuffer( GLenum mode )
{
- GLenum destMask, supportedMask;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
- /*
- * Do error checking and compute the _DrawDestMask bitfield.
- */
- destMask = draw_buffer_enum_to_bitmask(mode);
- if (destMask == ~0u) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)");
- return;
+ if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
+ /* Set drawbuffer for a framebuffer object */
+ if (mode == GL_NONE) {
+ ctx->CurrentFramebuffer->DrawBuffer[0] = mode;
+ }
+ else {
+ const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT;
+ if (k >= 0 && k < ctx->Const.MaxColorAttachments) {
+ /* XXX check that the attachment point's Type != GL_NONE */
+ ctx->CurrentFramebuffer->DrawBuffer[0] = mode;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)");
+ return;
+ }
+ }
}
+ else {
+ /* conventional behaviour */
+ /* Do error checking and compute the _DrawDestMask bitfield. */
+ GLenum destMask, supportedMask;
+
+ destMask = draw_buffer_enum_to_bitmask(mode);
+ if (destMask == ~0u) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)");
+ return;
+ }
- supportedMask = supported_buffer_bitmask(ctx);
- destMask &= supportedMask;
+ supportedMask = supported_buffer_bitmask(ctx);
+ destMask &= supportedMask;
- if (destMask == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(mode)");
- return;
- }
+ if (destMask == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(mode)");
+ return;
+ }
- ctx->Color.DrawBuffer[0] = mode;
- ctx->Color._DrawDestMask[0] = destMask;
- ctx->NewState |= _NEW_COLOR;
+ ctx->Color.DrawBuffer[0] = mode;
+ ctx->Color._DrawDestMask[0] = destMask;
+ ctx->NewState |= _NEW_COLOR;
+ }
/*
* Call device driver function.
@@ -337,8 +357,6 @@ _mesa_DrawBuffer( GLenum mode )
void GLAPIENTRY
_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
{
- GLint i;
- GLuint usedBufferMask, supportedMask;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -347,34 +365,79 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
return;
}
- supportedMask = supported_buffer_bitmask(ctx);
- usedBufferMask = 0;
- for (i = 0; i < n; i++) {
- GLuint destMask = draw_buffer_enum_to_bitmask(buffers[i]);
- if (destMask == ~0u ) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
- return;
- }
- destMask &= supportedMask;
- if (destMask == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(unsupported buffer)");
- return;
+ if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
+ /* Set drawbuffers for a framebuffer object */
+ GLint i;
+ GLuint usedAttachments = 0x0;
+ for (i = 0; i < n; i++) {
+ if (buffers[i] == GL_NONE) {
+ /* OK */
+ ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE;
+ }
+ else {
+ const GLint k = buffers[i] - GL_COLOR_ATTACHMENT0_EXT;
+ if (k >= 0 && k < ctx->Const.MaxColorAttachments) {
+ /* XXX check that the attachment point's Type != GL_NONE */
+ if ((1 << k) & usedAttachments) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawBuffersARB(duplicated attachment)");
+ return;
+ }
+ usedAttachments |= (1 << k);
+ ctx->CurrentFramebuffer->DrawBuffer[i] = buffers[i];
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(mode)");
+ return;
+ }
+ }
}
- if (destMask & usedBufferMask) {
- /* can't use a dest buffer more than once! */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawBuffersARB(duplicated buffer)");
- return;
+
+ /* set remaining color outputs to NONE */
+ for (i = n; i < ctx->Const.MaxDrawBuffers; i++) {
+ ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE;
}
- /* update bitmask */
- usedBufferMask |= destMask;
- /* save state */
- ctx->Color.DrawBuffer[i] = buffers[i];
- ctx->Color._DrawDestMask[i] = destMask;
}
+ else {
+ /* Conventional operation */
+ GLint i;
+ GLuint usedBufferMask, supportedMask;
+
+ supportedMask = supported_buffer_bitmask(ctx);
+ usedBufferMask = 0;
+ for (i = 0; i < n; i++) {
+ GLuint destMask = draw_buffer_enum_to_bitmask(buffers[i]);
+ if (destMask == ~0u ) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
+ return;
+ }
+ destMask &= supportedMask;
+ if (destMask == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawBuffersARB(unsupported buffer)");
+ return;
+ }
+ if (destMask & usedBufferMask) {
+ /* can't specify a dest buffer more than once! */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawBuffersARB(duplicated buffer)");
+ return;
+ }
+ /* update bitmask */
+ usedBufferMask |= destMask;
+ /* save state */
+ ctx->Color.DrawBuffer[i] = buffers[i];
+ ctx->Color._DrawDestMask[i] = destMask;
+ }
- ctx->NewState |= _NEW_COLOR;
+ /* set remaining color outputs to NONE */
+ for (i = n; i < ctx->Const.MaxDrawBuffers; i++) {
+ ctx->Color.DrawBuffer[i] = GL_NONE;
+ ctx->Color._DrawDestMask[i] = 0;
+ }
+
+ ctx->NewState |= _NEW_COLOR;
+ }
/*
* Call device driver function.
@@ -398,26 +461,47 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
void GLAPIENTRY
_mesa_ReadBuffer( GLenum mode )
{
- GLuint srcMask, supportedMask;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
- srcMask = read_buffer_enum_to_bitmask(mode);
- if (srcMask == ~0u) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)");
- return;
+ if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
+ /* Set readbuffer for a framebuffer object */
+ if (mode == GL_NONE) {
+ ctx->CurrentFramebuffer->ReadBuffer = mode;
+ }
+ else {
+ const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT;
+ if (k >= 0 && k < ctx->Const.MaxColorAttachments) {
+ /* XXX check that the attachment point's Type != GL_NONE */
+ ctx->CurrentFramebuffer->ReadBuffer = mode;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)");
+ return;
+ }
+ }
}
- supportedMask = supported_buffer_bitmask(ctx);
- if ((srcMask & supportedMask) == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(mode)");
- return;
+ else {
+ /* conventional operation */
+ GLuint srcMask, supportedMask;
+
+ srcMask = read_buffer_enum_to_bitmask(mode);
+ if (srcMask == ~0u) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)");
+ return;
+ }
+ supportedMask = supported_buffer_bitmask(ctx);
+ if ((srcMask & supportedMask) == 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(mode)");
+ return;
+ }
+ ctx->Pixel._ReadSrcMask = srcMask;
+ ctx->Pixel.ReadBuffer = mode;
+ ctx->NewState |= _NEW_PIXEL;
}
- ctx->Pixel._ReadSrcMask = srcMask;
- ctx->Pixel.ReadBuffer = mode;
- ctx->NewState |= _NEW_PIXEL;
/*
* Call device driver function.