buffers.c revision 848b8605
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file buffers.c 28 * glReadBuffer, DrawBuffer functions. 29 */ 30 31 32 33#include "glheader.h" 34#include "buffers.h" 35#include "colormac.h" 36#include "context.h" 37#include "enums.h" 38#include "fbobject.h" 39#include "mtypes.h" 40 41 42#define BAD_MASK ~0u 43 44 45/** 46 * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are 47 * available to the rendering context (for drawing or reading). 48 * This depends on the type of framebuffer. For window system framebuffers 49 * we look at the framebuffer's visual. But for user-create framebuffers we 50 * look at the number of supported color attachments. 51 * \param fb the framebuffer to draw to, or read from 52 * \return bitmask of BUFFER_BIT_* flags 53 */ 54static GLbitfield 55supported_buffer_bitmask(const struct gl_context *ctx, 56 const struct gl_framebuffer *fb) 57{ 58 GLbitfield mask = 0x0; 59 60 if (_mesa_is_user_fbo(fb)) { 61 /* A user-created renderbuffer */ 62 GLuint i; 63 for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { 64 mask |= (BUFFER_BIT_COLOR0 << i); 65 } 66 } 67 else { 68 /* A window system framebuffer */ 69 GLint i; 70 mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ 71 if (fb->Visual.stereoMode) { 72 mask |= BUFFER_BIT_FRONT_RIGHT; 73 if (fb->Visual.doubleBufferMode) { 74 mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 75 } 76 } 77 else if (fb->Visual.doubleBufferMode) { 78 mask |= BUFFER_BIT_BACK_LEFT; 79 } 80 81 for (i = 0; i < fb->Visual.numAuxBuffers; i++) { 82 mask |= (BUFFER_BIT_AUX0 << i); 83 } 84 } 85 86 return mask; 87} 88 89 90/** 91 * Helper routine used by glDrawBuffer and glDrawBuffersARB. 92 * Given a GLenum naming one or more color buffers (such as 93 * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. 94 */ 95static GLbitfield 96draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer) 97{ 98 switch (buffer) { 99 case GL_NONE: 100 return 0; 101 case GL_FRONT: 102 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; 103 case GL_BACK: 104 if (_mesa_is_gles(ctx)) { 105 /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL 106 * ES 3.0.1 specification says: 107 * 108 * "When draw buffer zero is BACK, color values are written 109 * into the sole buffer for single-buffered contexts, or into 110 * the back buffer for double-buffered contexts." 111 * 112 * Since there is no stereo rendering in ES 3.0, only return the 113 * LEFT bits. This also satisfies the "n must be 1" requirement. 114 * 115 * We also do this for GLES 1 and 2 because those APIs have no 116 * concept of selecting the front and back buffer anyway and it's 117 * convenient to be able to maintain the magic behaviour of 118 * GL_BACK in that case. 119 */ 120 if (ctx->DrawBuffer->Visual.doubleBufferMode) 121 return BUFFER_BIT_BACK_LEFT; 122 return BUFFER_BIT_FRONT_LEFT; 123 } 124 return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 125 case GL_RIGHT: 126 return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 127 case GL_FRONT_RIGHT: 128 return BUFFER_BIT_FRONT_RIGHT; 129 case GL_BACK_RIGHT: 130 return BUFFER_BIT_BACK_RIGHT; 131 case GL_BACK_LEFT: 132 return BUFFER_BIT_BACK_LEFT; 133 case GL_FRONT_AND_BACK: 134 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT 135 | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 136 case GL_LEFT: 137 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; 138 case GL_FRONT_LEFT: 139 return BUFFER_BIT_FRONT_LEFT; 140 case GL_AUX0: 141 return BUFFER_BIT_AUX0; 142 case GL_AUX1: 143 case GL_AUX2: 144 case GL_AUX3: 145 return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */ 146 case GL_COLOR_ATTACHMENT0_EXT: 147 return BUFFER_BIT_COLOR0; 148 case GL_COLOR_ATTACHMENT1_EXT: 149 return BUFFER_BIT_COLOR1; 150 case GL_COLOR_ATTACHMENT2_EXT: 151 return BUFFER_BIT_COLOR2; 152 case GL_COLOR_ATTACHMENT3_EXT: 153 return BUFFER_BIT_COLOR3; 154 case GL_COLOR_ATTACHMENT4_EXT: 155 return BUFFER_BIT_COLOR4; 156 case GL_COLOR_ATTACHMENT5_EXT: 157 return BUFFER_BIT_COLOR5; 158 case GL_COLOR_ATTACHMENT6_EXT: 159 return BUFFER_BIT_COLOR6; 160 case GL_COLOR_ATTACHMENT7_EXT: 161 return BUFFER_BIT_COLOR7; 162 default: 163 /* error */ 164 return BAD_MASK; 165 } 166} 167 168 169/** 170 * Helper routine used by glReadBuffer. 171 * Given a GLenum naming a color buffer, return the index of the corresponding 172 * renderbuffer (a BUFFER_* value). 173 * return -1 for an invalid buffer. 174 */ 175static GLint 176read_buffer_enum_to_index(GLenum buffer) 177{ 178 switch (buffer) { 179 case GL_FRONT: 180 return BUFFER_FRONT_LEFT; 181 case GL_BACK: 182 return BUFFER_BACK_LEFT; 183 case GL_RIGHT: 184 return BUFFER_FRONT_RIGHT; 185 case GL_FRONT_RIGHT: 186 return BUFFER_FRONT_RIGHT; 187 case GL_BACK_RIGHT: 188 return BUFFER_BACK_RIGHT; 189 case GL_BACK_LEFT: 190 return BUFFER_BACK_LEFT; 191 case GL_LEFT: 192 return BUFFER_FRONT_LEFT; 193 case GL_FRONT_LEFT: 194 return BUFFER_FRONT_LEFT; 195 case GL_AUX0: 196 return BUFFER_AUX0; 197 case GL_AUX1: 198 case GL_AUX2: 199 case GL_AUX3: 200 return BUFFER_COUNT; /* invalid, but not -1 */ 201 case GL_COLOR_ATTACHMENT0_EXT: 202 return BUFFER_COLOR0; 203 case GL_COLOR_ATTACHMENT1_EXT: 204 return BUFFER_COLOR1; 205 case GL_COLOR_ATTACHMENT2_EXT: 206 return BUFFER_COLOR2; 207 case GL_COLOR_ATTACHMENT3_EXT: 208 return BUFFER_COLOR3; 209 case GL_COLOR_ATTACHMENT4_EXT: 210 return BUFFER_COLOR4; 211 case GL_COLOR_ATTACHMENT5_EXT: 212 return BUFFER_COLOR5; 213 case GL_COLOR_ATTACHMENT6_EXT: 214 return BUFFER_COLOR6; 215 case GL_COLOR_ATTACHMENT7_EXT: 216 return BUFFER_COLOR7; 217 default: 218 /* error */ 219 return -1; 220 } 221} 222 223 224/** 225 * Called by glDrawBuffer(). 226 * Specify which renderbuffer(s) to draw into for the first color output. 227 * <buffer> can name zero, one, two or four renderbuffers! 228 * \sa _mesa_DrawBuffers 229 * 230 * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. 231 * 232 * Note that the behaviour of this function depends on whether the 233 * current ctx->DrawBuffer is a window-system framebuffer or a user-created 234 * framebuffer object. 235 * In the former case, we update the per-context ctx->Color.DrawBuffer 236 * state var _and_ the FB's ColorDrawBuffer state. 237 * In the later case, we update the FB's ColorDrawBuffer state only. 238 * 239 * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the 240 * new FB is a window system FB, we need to re-update the FB's 241 * ColorDrawBuffer state to match the context. This is handled in 242 * _mesa_update_framebuffer(). 243 * 244 * See the GL_EXT_framebuffer_object spec for more info. 245 */ 246void GLAPIENTRY 247_mesa_DrawBuffer(GLenum buffer) 248{ 249 GLbitfield destMask; 250 GET_CURRENT_CONTEXT(ctx); 251 252 FLUSH_VERTICES(ctx, 0); 253 254 if (MESA_VERBOSE & VERBOSE_API) { 255 _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 256 } 257 258 if (buffer == GL_NONE) { 259 destMask = 0x0; 260 } 261 else { 262 const GLbitfield supportedMask 263 = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 264 destMask = draw_buffer_enum_to_bitmask(ctx, buffer); 265 if (destMask == BAD_MASK) { 266 /* totally bogus buffer */ 267 _mesa_error(ctx, GL_INVALID_ENUM, 268 "glDrawBuffer(buffer=0x%x)", buffer); 269 return; 270 } 271 destMask &= supportedMask; 272 if (destMask == 0x0) { 273 /* none of the named color buffers exist! */ 274 _mesa_error(ctx, GL_INVALID_OPERATION, 275 "glDrawBuffer(buffer=0x%x)", buffer); 276 return; 277 } 278 } 279 280 /* if we get here, there's no error so set new state */ 281 _mesa_drawbuffers(ctx, 1, &buffer, &destMask); 282 283 /* 284 * Call device driver function. 285 */ 286 if (ctx->Driver.DrawBuffers) 287 ctx->Driver.DrawBuffers(ctx, 1, &buffer); 288 else if (ctx->Driver.DrawBuffer) 289 ctx->Driver.DrawBuffer(ctx, buffer); 290} 291 292 293/** 294 * Called by glDrawBuffersARB; specifies the destination color renderbuffers 295 * for N fragment program color outputs. 296 * \sa _mesa_DrawBuffer 297 * \param n number of outputs 298 * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the 299 * names cannot specify more than one buffer. For example, 300 * GL_FRONT_AND_BACK is illegal. 301 */ 302void GLAPIENTRY 303_mesa_DrawBuffers(GLsizei n, const GLenum *buffers) 304{ 305 GLint output; 306 GLbitfield usedBufferMask, supportedMask; 307 GLbitfield destMask[MAX_DRAW_BUFFERS]; 308 GET_CURRENT_CONTEXT(ctx); 309 310 FLUSH_VERTICES(ctx, 0); 311 312 /* Turns out n==0 is a valid input that should not produce an error. 313 * The remaining code below correctly handles the n==0 case. 314 * 315 * From the OpenGL 3.0 specification, page 258: 316 * "An INVALID_VALUE error is generated if n is greater than 317 * MAX_DRAW_BUFFERS." 318 */ 319 if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { 320 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); 321 return; 322 } 323 324 supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer); 325 usedBufferMask = 0x0; 326 327 /* From the ES 3.0 specification, page 180: 328 * "If the GL is bound to the default framebuffer, then n must be 1 329 * and the constant must be BACK or NONE." 330 */ 331 if (_mesa_is_gles3(ctx) && _mesa_is_winsys_fbo(ctx->DrawBuffer) && 332 (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) { 333 _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); 334 return; 335 } 336 337 /* complicated error checking... */ 338 for (output = 0; output < n; output++) { 339 if (buffers[output] == GL_NONE) { 340 destMask[output] = 0x0; 341 } 342 else { 343 /* Page 259 (page 275 of the PDF) in section 4.2.1 of the OpenGL 3.0 344 * spec (20080923) says: 345 * 346 * "If the GL is bound to a framebuffer object and DrawBuffers is 347 * supplied with [...] COLOR_ATTACHMENTm where m is greater than 348 * or equal to the value of MAX_COLOR_ATTACHMENTS, then the error 349 * INVALID_OPERATION results." 350 */ 351 if (_mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] >= 352 GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) { 353 _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)"); 354 return; 355 } 356 357 destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); 358 359 /* From the OpenGL 3.0 specification, page 258: 360 * "Each buffer listed in bufs must be one of the values from tables 361 * 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated. 362 */ 363 if (destMask[output] == BAD_MASK) { 364 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); 365 return; 366 } 367 368 /* From the OpenGL 4.0 specification, page 256: 369 * "For both the default framebuffer and framebuffer objects, the 370 * constants FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK are not 371 * valid in the bufs array passed to DrawBuffers, and will result in 372 * the error INVALID_ENUM. This restriction is because these 373 * constants may themselves refer to multiple buffers, as shown in 374 * table 4.4." 375 * Previous versions of the OpenGL specification say INVALID_OPERATION, 376 * but the Khronos conformance tests expect INVALID_ENUM. 377 */ 378 if (_mesa_bitcount(destMask[output]) > 1) { 379 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); 380 return; 381 } 382 383 /* From the OpenGL 3.0 specification, page 259: 384 * "If the GL is bound to the default framebuffer and DrawBuffers is 385 * supplied with a constant (other than NONE) that does not indicate 386 * any of the color buffers allocated to the GL context by the window 387 * system, the error INVALID_OPERATION will be generated. 388 * 389 * If the GL is bound to a framebuffer object and DrawBuffers is 390 * supplied with a constant from table 4.6 [...] then the error 391 * INVALID_OPERATION results." 392 */ 393 destMask[output] &= supportedMask; 394 if (destMask[output] == 0) { 395 _mesa_error(ctx, GL_INVALID_OPERATION, 396 "glDrawBuffersARB(unsupported buffer)"); 397 return; 398 } 399 400 /* ES 3.0 is even more restrictive. From the ES 3.0 spec, page 180: 401 * "If the GL is bound to a framebuffer object, the ith buffer listed 402 * in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION." 403 */ 404 if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(ctx->DrawBuffer) && 405 buffers[output] != GL_NONE && 406 buffers[output] != GL_COLOR_ATTACHMENT0 + output) { 407 _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); 408 return; 409 } 410 411 /* From the OpenGL 3.0 specification, page 258: 412 * "Except for NONE, a buffer may not appear more than once in the 413 * array pointed to by bufs. Specifying a buffer more then once will 414 * result in the error INVALID_OPERATION." 415 */ 416 if (destMask[output] & usedBufferMask) { 417 _mesa_error(ctx, GL_INVALID_OPERATION, 418 "glDrawBuffersARB(duplicated buffer)"); 419 return; 420 } 421 422 /* update bitmask */ 423 usedBufferMask |= destMask[output]; 424 } 425 } 426 427 /* OK, if we get here, there were no errors so set the new state */ 428 _mesa_drawbuffers(ctx, n, buffers, destMask); 429 430 /* 431 * Call device driver function. Note that n can be equal to 0, 432 * in which case we don't want to reference buffers[0], which 433 * may not be valid. 434 */ 435 if (ctx->Driver.DrawBuffers) 436 ctx->Driver.DrawBuffers(ctx, n, buffers); 437 else if (ctx->Driver.DrawBuffer) 438 ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE); 439} 440 441 442/** 443 * Performs necessary state updates when _mesa_drawbuffers makes an 444 * actual change. 445 */ 446static void 447updated_drawbuffers(struct gl_context *ctx) 448{ 449 FLUSH_VERTICES(ctx, _NEW_BUFFERS); 450 451 if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) { 452 struct gl_framebuffer *fb = ctx->DrawBuffer; 453 454 /* Flag the FBO as requiring validation. */ 455 if (_mesa_is_user_fbo(fb)) { 456 fb->_Status = 0; 457 } 458 } 459} 460 461 462/** 463 * Helper function to set the GL_DRAW_BUFFER state in the context and 464 * current FBO. Called via glDrawBuffer(), glDrawBuffersARB() 465 * 466 * All error checking will have been done prior to calling this function 467 * so nothing should go wrong at this point. 468 * 469 * \param ctx current context 470 * \param n number of color outputs to set 471 * \param buffers array[n] of colorbuffer names, like GL_LEFT. 472 * \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the 473 * colorbuffer names. (i.e. GL_FRONT_AND_BACK => 474 * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). 475 */ 476void 477_mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, 478 const GLbitfield *destMask) 479{ 480 struct gl_framebuffer *fb = ctx->DrawBuffer; 481 GLbitfield mask[MAX_DRAW_BUFFERS]; 482 GLuint buf; 483 484 if (!destMask) { 485 /* compute destMask values now */ 486 const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); 487 GLuint output; 488 for (output = 0; output < n; output++) { 489 mask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); 490 ASSERT(mask[output] != BAD_MASK); 491 mask[output] &= supportedMask; 492 } 493 destMask = mask; 494 } 495 496 /* 497 * destMask[0] may have up to four bits set 498 * (ex: glDrawBuffer(GL_FRONT_AND_BACK)). 499 * Otherwise, destMask[x] can only have one bit set. 500 */ 501 if (n > 0 && _mesa_bitcount(destMask[0]) > 1) { 502 GLuint count = 0, destMask0 = destMask[0]; 503 while (destMask0) { 504 GLint bufIndex = ffs(destMask0) - 1; 505 if (fb->_ColorDrawBufferIndexes[count] != bufIndex) { 506 updated_drawbuffers(ctx); 507 fb->_ColorDrawBufferIndexes[count] = bufIndex; 508 } 509 count++; 510 destMask0 &= ~(1 << bufIndex); 511 } 512 fb->ColorDrawBuffer[0] = buffers[0]; 513 fb->_NumColorDrawBuffers = count; 514 } 515 else { 516 GLuint count = 0; 517 for (buf = 0; buf < n; buf++ ) { 518 if (destMask[buf]) { 519 GLint bufIndex = ffs(destMask[buf]) - 1; 520 /* only one bit should be set in the destMask[buf] field */ 521 ASSERT(_mesa_bitcount(destMask[buf]) == 1); 522 if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) { 523 updated_drawbuffers(ctx); 524 fb->_ColorDrawBufferIndexes[buf] = bufIndex; 525 } 526 count = buf + 1; 527 } 528 else { 529 if (fb->_ColorDrawBufferIndexes[buf] != -1) { 530 updated_drawbuffers(ctx); 531 fb->_ColorDrawBufferIndexes[buf] = -1; 532 } 533 } 534 fb->ColorDrawBuffer[buf] = buffers[buf]; 535 } 536 fb->_NumColorDrawBuffers = count; 537 } 538 539 /* set remaining outputs to -1 (GL_NONE) */ 540 for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) { 541 if (fb->_ColorDrawBufferIndexes[buf] != -1) { 542 updated_drawbuffers(ctx); 543 fb->_ColorDrawBufferIndexes[buf] = -1; 544 } 545 } 546 for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) { 547 fb->ColorDrawBuffer[buf] = GL_NONE; 548 } 549 550 if (_mesa_is_winsys_fbo(fb)) { 551 /* also set context drawbuffer state */ 552 for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 553 if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) { 554 updated_drawbuffers(ctx); 555 ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; 556 } 557 } 558 } 559} 560 561 562/** 563 * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc. 564 * from the context's Color.DrawBuffer[] state. 565 * Use when changing contexts. 566 */ 567void 568_mesa_update_draw_buffers(struct gl_context *ctx) 569{ 570 /* should be a window system FBO */ 571 assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); 572 573 _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, 574 ctx->Color.DrawBuffer, NULL); 575} 576 577 578/** 579 * Like \sa _mesa_drawbuffers(), this is a helper function for setting 580 * GL_READ_BUFFER state in the context and current FBO. 581 * \param ctx the rendering context 582 * \param buffer GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc. 583 * \param bufferIndex the numerical index corresponding to 'buffer' 584 */ 585void 586_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex) 587{ 588 struct gl_framebuffer *fb = ctx->ReadBuffer; 589 590 if (_mesa_is_winsys_fbo(fb)) { 591 /* Only update the per-context READ_BUFFER state if we're bound to 592 * a window-system framebuffer. 593 */ 594 ctx->Pixel.ReadBuffer = buffer; 595 } 596 597 fb->ColorReadBuffer = buffer; 598 fb->_ColorReadBufferIndex = bufferIndex; 599 600 ctx->NewState |= _NEW_BUFFERS; 601} 602 603 604 605/** 606 * Called by glReadBuffer to set the source renderbuffer for reading pixels. 607 * \param mode color buffer such as GL_FRONT, GL_BACK, etc. 608 */ 609void GLAPIENTRY 610_mesa_ReadBuffer(GLenum buffer) 611{ 612 struct gl_framebuffer *fb; 613 GLbitfield supportedMask; 614 GLint srcBuffer; 615 GET_CURRENT_CONTEXT(ctx); 616 617 FLUSH_VERTICES(ctx, 0); 618 619 if (MESA_VERBOSE & VERBOSE_API) 620 _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 621 622 fb = ctx->ReadBuffer; 623 624 if (MESA_VERBOSE & VERBOSE_API) 625 _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); 626 627 if (buffer == GL_NONE) { 628 /* This is legal--it means that no buffer should be bound for reading. */ 629 srcBuffer = -1; 630 } 631 else { 632 /* general case / window-system framebuffer */ 633 srcBuffer = read_buffer_enum_to_index(buffer); 634 if (srcBuffer == -1) { 635 _mesa_error(ctx, GL_INVALID_ENUM, 636 "glReadBuffer(buffer=0x%x)", buffer); 637 return; 638 } 639 supportedMask = supported_buffer_bitmask(ctx, fb); 640 if (((1 << srcBuffer) & supportedMask) == 0) { 641 _mesa_error(ctx, GL_INVALID_OPERATION, 642 "glReadBuffer(buffer=0x%x)", buffer); 643 return; 644 } 645 } 646 647 /* OK, all error checking has been completed now */ 648 649 _mesa_readbuffer(ctx, buffer, srcBuffer); 650 651 /* 652 * Call device driver function. 653 */ 654 if (ctx->Driver.ReadBuffer) 655 (*ctx->Driver.ReadBuffer)(ctx, buffer); 656} 657