X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fbuffers.c;h=cc268b67cbca57bca3f48443a6eb96df4fe18ba2;hb=d012e6d8fe2f4f1139af9e47a684960e8cde103e;hp=fb30b5996093542fd9903db8d95c15f381ad923a;hpb=9b346f83a7b672e913a7bb6a089d5dbd7fbdce06;p=mesa.git diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index fb30b599609..cc268b67cbc 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -35,6 +35,8 @@ #include "colormac.h" #include "context.h" #include "enums.h" +#include "fbobject.h" +#include "mtypes.h" #define BAD_MASK ~0u @@ -50,11 +52,12 @@ * \return bitmask of BUFFER_BIT_* flags */ static GLbitfield -supported_buffer_bitmask(const GLcontext *ctx, const struct gl_framebuffer *fb) +supported_buffer_bitmask(const struct gl_context *ctx, + const struct gl_framebuffer *fb) { GLbitfield mask = 0x0; - if (fb->Name > 0) { + if (_mesa_is_user_fbo(fb)) { /* A user-created renderbuffer */ GLuint i; ASSERT(ctx->Extensions.EXT_framebuffer_object); @@ -241,7 +244,8 @@ _mesa_DrawBuffer(GLenum buffer) destMask = draw_buffer_enum_to_bitmask(buffer); if (destMask == BAD_MASK) { /* totally bogus buffer */ - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer=0x%x)", buffer); + _mesa_error(ctx, GL_INVALID_ENUM, + "glDrawBuffer(buffer=0x%x)", buffer); return; } destMask &= supportedMask; @@ -340,6 +344,26 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) } +/** + * Performs necessary state updates when _mesa_drawbuffers makes an + * actual change. + */ +static void +updated_drawbuffers(struct gl_context *ctx) +{ + FLUSH_VERTICES(ctx, _NEW_BUFFERS); + + if (ctx->API == API_OPENGL && !ctx->Extensions.ARB_ES2_compatibility) { + struct gl_framebuffer *fb = ctx->DrawBuffer; + + /* Flag the FBO as requiring validation. */ + if (_mesa_is_user_fbo(fb)) { + fb->_Status = 0; + } + } +} + + /** * Helper function to set the GL_DRAW_BUFFER state in the context and * current FBO. Called via glDrawBuffer(), glDrawBuffersARB() @@ -355,12 +379,12 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). */ void -_mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, +_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, const GLbitfield *destMask) { struct gl_framebuffer *fb = ctx->DrawBuffer; GLbitfield mask[MAX_DRAW_BUFFERS]; - GLboolean newState = GL_FALSE; + GLuint buf; if (!destMask) { /* compute destMask values now */ @@ -381,66 +405,82 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, if (n == 1) { GLuint count = 0, destMask0 = destMask[0]; while (destMask0) { - GLint bufIndex = _mesa_ffs(destMask0) - 1; + GLint bufIndex = ffs(destMask0) - 1; if (fb->_ColorDrawBufferIndexes[count] != bufIndex) { + updated_drawbuffers(ctx); fb->_ColorDrawBufferIndexes[count] = bufIndex; - newState = GL_TRUE; } count++; destMask0 &= ~(1 << bufIndex); } fb->ColorDrawBuffer[0] = buffers[0]; - if (fb->_NumColorDrawBuffers != count) { - fb->_NumColorDrawBuffers = count; - newState = GL_TRUE; - } + fb->_NumColorDrawBuffers = count; } else { - GLuint buf, count = 0; + GLuint count = 0; for (buf = 0; buf < n; buf++ ) { if (destMask[buf]) { - GLint bufIndex = _mesa_ffs(destMask[buf]) - 1; + GLint bufIndex = ffs(destMask[buf]) - 1; /* only one bit should be set in the destMask[buf] field */ ASSERT(_mesa_bitcount(destMask[buf]) == 1); if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) { + updated_drawbuffers(ctx); fb->_ColorDrawBufferIndexes[buf] = bufIndex; - newState = GL_TRUE; } - fb->ColorDrawBuffer[buf] = buffers[buf]; count = buf + 1; } else { if (fb->_ColorDrawBufferIndexes[buf] != -1) { + updated_drawbuffers(ctx); fb->_ColorDrawBufferIndexes[buf] = -1; - newState = GL_TRUE; } } - } - /* set remaining outputs to -1 (GL_NONE) */ - while (buf < ctx->Const.MaxDrawBuffers) { - if (fb->_ColorDrawBufferIndexes[buf] != -1) { - fb->_ColorDrawBufferIndexes[buf] = -1; - newState = GL_TRUE; - } - fb->ColorDrawBuffer[buf] = GL_NONE; - buf++; + fb->ColorDrawBuffer[buf] = buffers[buf]; } fb->_NumColorDrawBuffers = count; } - if (fb->Name == 0) { + /* set remaining outputs to -1 (GL_NONE) */ + for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) { + if (fb->_ColorDrawBufferIndexes[buf] != -1) { + updated_drawbuffers(ctx); + fb->_ColorDrawBufferIndexes[buf] = -1; + } + } + for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) { + fb->ColorDrawBuffer[buf] = GL_NONE; + } + + if (_mesa_is_winsys_fbo(fb)) { /* also set context drawbuffer state */ - GLuint buf; for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) { + updated_drawbuffers(ctx); ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; - newState = GL_TRUE; } } } +} + + +/** + * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc. + * from the context's Color.DrawBuffer[] state. + * Use when changing contexts. + */ +void +_mesa_update_draw_buffers(struct gl_context *ctx) +{ + GLenum buffers[MAX_DRAW_BUFFERS]; + GLuint i; + + /* should be a window system FBO */ + assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); + + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) + buffers[i] = ctx->Color.DrawBuffer[i]; - if (newState) - FLUSH_VERTICES(ctx, _NEW_BUFFERS); + _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); } @@ -452,11 +492,11 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, * \param bufferIndex the numerical index corresponding to 'buffer' */ void -_mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex) +_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex) { struct gl_framebuffer *fb = ctx->ReadBuffer; - if (fb->Name == 0) { + if (_mesa_is_winsys_fbo(fb)) { /* Only update the per-context READ_BUFFER state if we're bound to * a window-system framebuffer. */ @@ -492,7 +532,7 @@ _mesa_ReadBuffer(GLenum buffer) if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - if (fb->Name > 0 && buffer == GL_NONE) { + if (_mesa_is_user_fbo(fb) && buffer == GL_NONE) { /* This is legal for user-created framebuffer objects */ srcBuffer = -1; }