initial support for GL_EXT_framebuffer_object

This commit is contained in:
Brian Paul
2005-02-09 03:51:11 +00:00
parent f0bbbf66b8
commit 1f6735a6a5

View File

@@ -35,6 +35,7 @@
#include "context.h" #include "context.h"
#include "depth.h" #include "depth.h"
#include "enums.h" #include "enums.h"
#include "fbobject.h"
#include "stencil.h" #include "stencil.h"
#include "state.h" #include "state.h"
#include "mtypes.h" #include "mtypes.h"
@@ -294,34 +295,53 @@ read_buffer_enum_to_bitmask(GLenum buffer)
void GLAPIENTRY void GLAPIENTRY
_mesa_DrawBuffer( GLenum mode ) _mesa_DrawBuffer( GLenum mode )
{ {
GLenum destMask, supportedMask;
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
if (MESA_VERBOSE & VERBOSE_API) if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
/* if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
* Do error checking and compute the _DrawDestMask bitfield. /* Set drawbuffer for a framebuffer object */
*/ if (mode == GL_NONE) {
destMask = draw_buffer_enum_to_bitmask(mode); ctx->CurrentFramebuffer->DrawBuffer[0] = mode;
if (destMask == ~0u) { }
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)"); else {
return; 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;
supportedMask = supported_buffer_bitmask(ctx); destMask = draw_buffer_enum_to_bitmask(mode);
destMask &= supportedMask; if (destMask == ~0u) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)");
return;
}
if (destMask == 0) { supportedMask = supported_buffer_bitmask(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(mode)"); destMask &= supportedMask;
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. * Call device driver function.
*/ */
@@ -337,8 +357,6 @@ _mesa_DrawBuffer( GLenum mode )
void GLAPIENTRY void GLAPIENTRY
_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
{ {
GLint i;
GLuint usedBufferMask, supportedMask;
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -347,34 +365,79 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
return; return;
} }
supportedMask = supported_buffer_bitmask(ctx); if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
usedBufferMask = 0; /* Set drawbuffers for a framebuffer object */
for (i = 0; i < n; i++) { GLint i;
GLuint destMask = draw_buffer_enum_to_bitmask(buffers[i]); GLuint usedAttachments = 0x0;
if (destMask == ~0u ) { for (i = 0; i < n; i++) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); if (buffers[i] == GL_NONE) {
return; /* OK */
} ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE;
destMask &= supportedMask; }
if (destMask == 0) { else {
_mesa_error(ctx, GL_INVALID_OPERATION, const GLint k = buffers[i] - GL_COLOR_ATTACHMENT0_EXT;
"glDrawBuffersARB(unsupported buffer)"); if (k >= 0 && k < ctx->Const.MaxColorAttachments) {
return; /* 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;
}
/* 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->CurrentFramebuffer->DrawBuffer[i] = GL_NONE;
}
}
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;
}
/* 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. * Call device driver function.
@@ -398,26 +461,47 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
void GLAPIENTRY void GLAPIENTRY
_mesa_ReadBuffer( GLenum mode ) _mesa_ReadBuffer( GLenum mode )
{ {
GLuint srcMask, supportedMask;
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & VERBOSE_API) if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
srcMask = read_buffer_enum_to_bitmask(mode); if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) {
if (srcMask == ~0u) { /* Set readbuffer for a framebuffer object */
_mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)"); if (mode == GL_NONE) {
return; 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); else {
if ((srcMask & supportedMask) == 0) { /* conventional operation */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(mode)"); GLuint srcMask, supportedMask;
return;
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. * Call device driver function.