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 "context.h" 36 #include "enums.h" 37 #include "fbobject.h" 38 #include "mtypes.h" 39 #include "util/bitscan.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 */ 54 static GLbitfield 55 supported_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 mask = ((1 << ctx->Const.MaxColorAttachments) - 1) << BUFFER_COLOR0; 63 } 64 else { 65 /* A window system framebuffer */ 66 GLint i; 67 mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ 68 if (fb->Visual.stereoMode) { 69 mask |= BUFFER_BIT_FRONT_RIGHT; 70 if (fb->Visual.doubleBufferMode) { 71 mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 72 } 73 } 74 else if (fb->Visual.doubleBufferMode) { 75 mask |= BUFFER_BIT_BACK_LEFT; 76 } 77 78 for (i = 0; i < fb->Visual.numAuxBuffers; i++) { 79 mask |= (BUFFER_BIT_AUX0 << i); 80 } 81 } 82 83 return mask; 84 } 85 86 87 /** 88 * Helper routine used by glDrawBuffer and glDrawBuffersARB. 89 * Given a GLenum naming one or more color buffers (such as 90 * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. 91 */ 92 static GLbitfield 93 draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer) 94 { 95 switch (buffer) { 96 case GL_NONE: 97 return 0; 98 case GL_FRONT: 99 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; 100 case GL_BACK: 101 if (_mesa_is_gles(ctx)) { 102 /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL 103 * ES 3.0.1 specification says: 104 * 105 * "When draw buffer zero is BACK, color values are written 106 * into the sole buffer for single-buffered contexts, or into 107 * the back buffer for double-buffered contexts." 108 * 109 * Since there is no stereo rendering in ES 3.0, only return the 110 * LEFT bits. This also satisfies the "n must be 1" requirement. 111 * 112 * We also do this for GLES 1 and 2 because those APIs have no 113 * concept of selecting the front and back buffer anyway and it's 114 * convenient to be able to maintain the magic behaviour of 115 * GL_BACK in that case. 116 */ 117 if (ctx->DrawBuffer->Visual.doubleBufferMode) 118 return BUFFER_BIT_BACK_LEFT; 119 return BUFFER_BIT_FRONT_LEFT; 120 } 121 return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; 122 case GL_RIGHT: 123 return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 124 case GL_FRONT_RIGHT: 125 return BUFFER_BIT_FRONT_RIGHT; 126 case GL_BACK_RIGHT: 127 return BUFFER_BIT_BACK_RIGHT; 128 case GL_BACK_LEFT: 129 return BUFFER_BIT_BACK_LEFT; 130 case GL_FRONT_AND_BACK: 131 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT 132 | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; 133 case GL_LEFT: 134 return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; 135 case GL_FRONT_LEFT: 136 return BUFFER_BIT_FRONT_LEFT; 137 case GL_AUX0: 138 return BUFFER_BIT_AUX0; 139 case GL_AUX1: 140 case GL_AUX2: 141 case GL_AUX3: 142 return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */ 143 case GL_COLOR_ATTACHMENT0_EXT: 144 return BUFFER_BIT_COLOR0; 145 case GL_COLOR_ATTACHMENT1_EXT: 146 return BUFFER_BIT_COLOR1; 147 case GL_COLOR_ATTACHMENT2_EXT: 148 return BUFFER_BIT_COLOR2; 149 case GL_COLOR_ATTACHMENT3_EXT: 150 return BUFFER_BIT_COLOR3; 151 case GL_COLOR_ATTACHMENT4_EXT: 152 return BUFFER_BIT_COLOR4; 153 case GL_COLOR_ATTACHMENT5_EXT: 154 return BUFFER_BIT_COLOR5; 155 case GL_COLOR_ATTACHMENT6_EXT: 156 return BUFFER_BIT_COLOR6; 157 case GL_COLOR_ATTACHMENT7_EXT: 158 return BUFFER_BIT_COLOR7; 159 default: 160 /* not an error, but also not supported */ 161 if (buffer >= GL_COLOR_ATTACHMENT8 && buffer <= GL_COLOR_ATTACHMENT31) 162 return 1 << BUFFER_COUNT; 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 BUFFER_NONE for an invalid buffer. 174 */ 175 static gl_buffer_index 176 read_buffer_enum_to_index(const struct gl_context *ctx, GLenum buffer) 177 { 178 switch (buffer) { 179 case GL_FRONT: 180 return BUFFER_FRONT_LEFT; 181 case GL_BACK: 182 if (_mesa_is_gles(ctx)) { 183 /* In draw_buffer_enum_to_bitmask, when GLES contexts draw to 184 * GL_BACK with a single-buffered configuration, we actually end 185 * up drawing to the sole front buffer in our internal 186 * representation. For consistency, we must read from that 187 * front left buffer too. 188 */ 189 if (!ctx->DrawBuffer->Visual.doubleBufferMode) 190 return BUFFER_FRONT_LEFT; 191 } 192 return BUFFER_BACK_LEFT; 193 case GL_RIGHT: 194 return BUFFER_FRONT_RIGHT; 195 case GL_FRONT_RIGHT: 196 return BUFFER_FRONT_RIGHT; 197 case GL_BACK_RIGHT: 198 return BUFFER_BACK_RIGHT; 199 case GL_BACK_LEFT: 200 return BUFFER_BACK_LEFT; 201 case GL_LEFT: 202 return BUFFER_FRONT_LEFT; 203 case GL_FRONT_LEFT: 204 return BUFFER_FRONT_LEFT; 205 case GL_AUX0: 206 return BUFFER_AUX0; 207 case GL_FRONT_AND_BACK: 208 return BUFFER_FRONT_LEFT; 209 case GL_AUX1: 210 case GL_AUX2: 211 case GL_AUX3: 212 return BUFFER_COUNT; /* invalid, but not -1 */ 213 case GL_COLOR_ATTACHMENT0_EXT: 214 return BUFFER_COLOR0; 215 case GL_COLOR_ATTACHMENT1_EXT: 216 return BUFFER_COLOR1; 217 case GL_COLOR_ATTACHMENT2_EXT: 218 return BUFFER_COLOR2; 219 case GL_COLOR_ATTACHMENT3_EXT: 220 return BUFFER_COLOR3; 221 case GL_COLOR_ATTACHMENT4_EXT: 222 return BUFFER_COLOR4; 223 case GL_COLOR_ATTACHMENT5_EXT: 224 return BUFFER_COLOR5; 225 case GL_COLOR_ATTACHMENT6_EXT: 226 return BUFFER_COLOR6; 227 case GL_COLOR_ATTACHMENT7_EXT: 228 return BUFFER_COLOR7; 229 default: 230 /* not an error, but also not supported */ 231 if (buffer >= GL_COLOR_ATTACHMENT8 && buffer <= GL_COLOR_ATTACHMENT31) 232 return BUFFER_COUNT; 233 /* error */ 234 return BUFFER_NONE; 235 } 236 } 237 238 static bool 239 is_legal_es3_readbuffer_enum(GLenum buf) 240 { 241 return buf == GL_BACK || buf == GL_NONE || 242 (buf >= GL_COLOR_ATTACHMENT0 && buf <= GL_COLOR_ATTACHMENT31); 243 } 244 245 /** 246 * Called by glDrawBuffer() and glNamedFramebufferDrawBuffer(). 247 * Specify which renderbuffer(s) to draw into for the first color output. 248 * <buffer> can name zero, one, two or four renderbuffers! 249 * \sa _mesa_DrawBuffers 250 * 251 * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. 252 * 253 * Note that the behaviour of this function depends on whether the 254 * current ctx->DrawBuffer is a window-system framebuffer or a user-created 255 * framebuffer object. 256 * In the former case, we update the per-context ctx->Color.DrawBuffer 257 * state var _and_ the FB's ColorDrawBuffer state. 258 * In the later case, we update the FB's ColorDrawBuffer state only. 259 * 260 * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the 261 * new FB is a window system FB, we need to re-update the FB's 262 * ColorDrawBuffer state to match the context. This is handled in 263 * _mesa_update_framebuffer(). 264 * 265 * See the GL_EXT_framebuffer_object spec for more info. 266 */ 267 static ALWAYS_INLINE void 268 draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb, 269 GLenum buffer, const char *caller, bool no_error) 270 { 271 GLbitfield destMask; 272 273 FLUSH_VERTICES(ctx, 0); 274 275 if (MESA_VERBOSE & VERBOSE_API) { 276 _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer)); 277 } 278 279 if (buffer == GL_NONE) { 280 destMask = 0x0; 281 } 282 else { 283 const GLbitfield supportedMask 284 = supported_buffer_bitmask(ctx, fb); 285 destMask = draw_buffer_enum_to_bitmask(ctx, buffer); 286 if (!no_error && destMask == BAD_MASK) { 287 /* totally bogus buffer */ 288 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", caller, 289 _mesa_enum_to_string(buffer)); 290 return; 291 } 292 destMask &= supportedMask; 293 if (!no_error && destMask == 0x0) { 294 /* none of the named color buffers exist! */ 295 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffer %s)", 296 caller, _mesa_enum_to_string(buffer)); 297 return; 298 } 299 } 300 301 /* if we get here, there's no error so set new state */ 302 _mesa_drawbuffers(ctx, fb, 1, &buffer, &destMask); 303 304 /* Call device driver function only if fb is the bound draw buffer */ 305 if (fb == ctx->DrawBuffer) { 306 if (ctx->Driver.DrawBuffers) 307 ctx->Driver.DrawBuffers(ctx, 1, &buffer); 308 else if (ctx->Driver.DrawBuffer) 309 ctx->Driver.DrawBuffer(ctx, buffer); 310 } 311 } 312 313 314 static void 315 draw_buffer_error(struct gl_context *ctx, struct gl_framebuffer *fb, 316 GLenum buffer, const char *caller) 317 { 318 draw_buffer(ctx, fb, buffer, caller, false); 319 } 320 321 322 static void 323 draw_buffer_no_error(struct gl_context *ctx, struct gl_framebuffer *fb, 324 GLenum buffer, const char *caller) 325 { 326 draw_buffer(ctx, fb, buffer, caller, true); 327 } 328 329 330 void GLAPIENTRY 331 _mesa_DrawBuffer_no_error(GLenum buffer) 332 { 333 GET_CURRENT_CONTEXT(ctx); 334 draw_buffer_no_error(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer"); 335 } 336 337 338 void GLAPIENTRY 339 _mesa_DrawBuffer(GLenum buffer) 340 { 341 GET_CURRENT_CONTEXT(ctx); 342 draw_buffer_error(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer"); 343 } 344 345 346 void GLAPIENTRY 347 _mesa_NamedFramebufferDrawBuffer_no_error(GLuint framebuffer, GLenum buf) 348 { 349 GET_CURRENT_CONTEXT(ctx); 350 struct gl_framebuffer *fb; 351 352 if (framebuffer) { 353 fb = _mesa_lookup_framebuffer(ctx, framebuffer); 354 } else { 355 fb = ctx->WinSysDrawBuffer; 356 } 357 358 draw_buffer_no_error(ctx, fb, buf, "glNamedFramebufferDrawBuffer"); 359 } 360 361 362 void GLAPIENTRY 363 _mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf) 364 { 365 GET_CURRENT_CONTEXT(ctx); 366 struct gl_framebuffer *fb; 367 368 if (framebuffer) { 369 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 370 "glNamedFramebufferDrawBuffer"); 371 if (!fb) 372 return; 373 } 374 else 375 fb = ctx->WinSysDrawBuffer; 376 377 draw_buffer_error(ctx, fb, buf, "glNamedFramebufferDrawBuffer"); 378 } 379 380 381 /** 382 * Called by glDrawBuffersARB() and glNamedFramebufferDrawBuffers() to specify 383 * the destination color renderbuffers for N fragment program color outputs. 384 * \sa _mesa_DrawBuffer 385 * \param n number of outputs 386 * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the 387 * names cannot specify more than one buffer. For example, 388 * GL_FRONT_AND_BACK is illegal. The only exception is GL_BACK 389 * that is considered special and allowed as far as n is one 390 * since 4.5. 391 */ 392 static ALWAYS_INLINE void 393 draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n, 394 const GLenum *buffers, const char *caller, bool no_error) 395 { 396 GLuint output; 397 GLbitfield usedBufferMask, supportedMask; 398 GLbitfield destMask[MAX_DRAW_BUFFERS]; 399 400 FLUSH_VERTICES(ctx, 0); 401 402 if (!no_error) { 403 /* Turns out n==0 is a valid input that should not produce an error. 404 * The remaining code below correctly handles the n==0 case. 405 * 406 * From the OpenGL 3.0 specification, page 258: 407 * "An INVALID_VALUE error is generated if n is greater than 408 * MAX_DRAW_BUFFERS." 409 */ 410 if (n < 0) { 411 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller); 412 return; 413 } 414 415 if (n > (GLsizei) ctx->Const.MaxDrawBuffers) { 416 _mesa_error(ctx, GL_INVALID_VALUE, 417 "%s(n > maximum number of draw buffers)", caller); 418 return; 419 } 420 421 /* From the ES 3.0 specification, page 180: 422 * "If the GL is bound to the default framebuffer, then n must be 1 423 * and the constant must be BACK or NONE." 424 * (same restriction applies with GL_EXT_draw_buffers specification) 425 */ 426 if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(fb) && 427 (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) { 428 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffers)", caller); 429 return; 430 } 431 } 432 433 supportedMask = supported_buffer_bitmask(ctx, fb); 434 usedBufferMask = 0x0; 435 436 /* complicated error checking... */ 437 for (output = 0; output < n; output++) { 438 destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); 439 440 if (!no_error) { 441 /* From the OpenGL 3.0 specification, page 258: 442 * "Each buffer listed in bufs must be one of the values from tables 443 * 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated. 444 */ 445 if (destMask[output] == BAD_MASK) { 446 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", 447 caller, _mesa_enum_to_string(buffers[output])); 448 return; 449 } 450 451 /* From the OpenGL 4.5 specification, page 493 (page 515 of the PDF) 452 * "An INVALID_ENUM error is generated if any value in bufs is FRONT, 453 * LEFT, RIGHT, or FRONT_AND_BACK . This restriction applies to both 454 * the default framebuffer and framebuffer objects, and exists because 455 * these constants may themselves refer to multiple buffers, as shown 456 * in table 17.4." 457 * 458 * And on page 492 (page 514 of the PDF): 459 * "If the default framebuffer is affected, then each of the constants 460 * must be one of the values listed in table 17.6 or the special value 461 * BACK. When BACK is used, n must be 1 and color values are written 462 * into the left buffer for single-buffered contexts, or into the back 463 * left buffer for double-buffered contexts." 464 * 465 * Note "special value BACK". GL_BACK also refers to multiple buffers, 466 * but it is consider a special case here. This is a change on 4.5. 467 * For OpenGL 4.x we check that behaviour. For any previous version we 468 * keep considering it wrong (as INVALID_ENUM). 469 */ 470 if (_mesa_bitcount(destMask[output]) > 1) { 471 if (_mesa_is_winsys_fbo(fb) && ctx->Version >= 40 && 472 buffers[output] == GL_BACK) { 473 if (n != 1) { 474 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(with GL_BACK n must be 1)", 475 caller); 476 return; 477 } 478 } else { 479 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", 480 caller, _mesa_enum_to_string(buffers[output])); 481 return; 482 } 483 } 484 485 /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL ES 3.0 486 * specification says: 487 * 488 * "If the GL is bound to a draw framebuffer object, the ith 489 * buffer listed in bufs must be COLOR_ATTACHMENTi or NONE . 490 * Specifying a buffer out of order, BACK , or COLOR_ATTACHMENTm 491 * where m is greater than or equal to the value of MAX_- 492 * COLOR_ATTACHMENTS , will generate the error INVALID_OPERATION . 493 */ 494 if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(fb) && 495 buffers[output] != GL_NONE && 496 (buffers[output] < GL_COLOR_ATTACHMENT0 || 497 buffers[output] >= GL_COLOR_ATTACHMENT0 + ctx->Const.MaxColorAttachments)) { 498 _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); 499 return; 500 } 501 } 502 503 if (buffers[output] == GL_NONE) { 504 destMask[output] = 0x0; 505 } 506 else { 507 /* Page 259 (page 275 of the PDF) in section 4.2.1 of the OpenGL 3.0 508 * spec (20080923) says: 509 * 510 * "If the GL is bound to a framebuffer object and DrawBuffers is 511 * supplied with [...] COLOR_ATTACHMENTm where m is greater than 512 * or equal to the value of MAX_COLOR_ATTACHMENTS, then the error 513 * INVALID_OPERATION results." 514 */ 515 if (!no_error && _mesa_is_user_fbo(fb) && buffers[output] >= 516 GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) { 517 _mesa_error(ctx, GL_INVALID_OPERATION, 518 "%s(buffers[%d] >= maximum number of draw buffers)", 519 caller, output); 520 return; 521 } 522 523 /* From the OpenGL 3.0 specification, page 259: 524 * "If the GL is bound to the default framebuffer and DrawBuffers is 525 * supplied with a constant (other than NONE) that does not indicate 526 * any of the color buffers allocated to the GL context by the window 527 * system, the error INVALID_OPERATION will be generated. 528 * 529 * If the GL is bound to a framebuffer object and DrawBuffers is 530 * supplied with a constant from table 4.6 [...] then the error 531 * INVALID_OPERATION results." 532 */ 533 destMask[output] &= supportedMask; 534 if (!no_error) { 535 if (destMask[output] == 0) { 536 _mesa_error(ctx, GL_INVALID_OPERATION, 537 "%s(unsupported buffer %s)", 538 caller, _mesa_enum_to_string(buffers[output])); 539 return; 540 } 541 542 /* ES 3.0 is even more restrictive. From the ES 3.0 spec, page 180: 543 * "If the GL is bound to a framebuffer object, the ith buffer 544 * listed in bufs must be COLOR_ATTACHMENTi or NONE. [...] 545 * INVALID_OPERATION." (same restriction applies with 546 * GL_EXT_draw_buffers specification) 547 */ 548 if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(fb) && 549 buffers[output] != GL_NONE && 550 buffers[output] != GL_COLOR_ATTACHMENT0 + output) { 551 _mesa_error(ctx, GL_INVALID_OPERATION, 552 "%s(unsupported buffer %s)", 553 caller, _mesa_enum_to_string(buffers[output])); 554 return; 555 } 556 557 /* From the OpenGL 3.0 specification, page 258: 558 * "Except for NONE, a buffer may not appear more than once in the 559 * array pointed to by bufs. Specifying a buffer more then once 560 * will result in the error INVALID_OPERATION." 561 */ 562 if (destMask[output] & usedBufferMask) { 563 _mesa_error(ctx, GL_INVALID_OPERATION, 564 "%s(duplicated buffer %s)", 565 caller, _mesa_enum_to_string(buffers[output])); 566 return; 567 } 568 } 569 570 /* update bitmask */ 571 usedBufferMask |= destMask[output]; 572 } 573 } 574 575 /* OK, if we get here, there were no errors so set the new state */ 576 _mesa_drawbuffers(ctx, fb, n, buffers, destMask); 577 578 /* 579 * Call device driver function if fb is the bound draw buffer. 580 * Note that n can be equal to 0, 581 * in which case we don't want to reference buffers[0], which 582 * may not be valid. 583 */ 584 if (fb == ctx->DrawBuffer) { 585 if (ctx->Driver.DrawBuffers) 586 ctx->Driver.DrawBuffers(ctx, n, buffers); 587 else if (ctx->Driver.DrawBuffer) 588 ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE); 589 } 590 } 591 592 593 static void 594 draw_buffers_error(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n, 595 const GLenum *buffers, const char *caller) 596 { 597 draw_buffers(ctx, fb, n, buffers, caller, false); 598 } 599 600 601 static void 602 draw_buffers_no_error(struct gl_context *ctx, struct gl_framebuffer *fb, 603 GLsizei n, const GLenum *buffers, const char *caller) 604 { 605 draw_buffers(ctx, fb, n, buffers, caller, true); 606 } 607 608 609 void GLAPIENTRY 610 _mesa_DrawBuffers_no_error(GLsizei n, const GLenum *buffers) 611 { 612 GET_CURRENT_CONTEXT(ctx); 613 draw_buffers_no_error(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers"); 614 } 615 616 617 void GLAPIENTRY 618 _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) 619 { 620 GET_CURRENT_CONTEXT(ctx); 621 draw_buffers_error(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers"); 622 } 623 624 625 void GLAPIENTRY 626 _mesa_NamedFramebufferDrawBuffers_no_error(GLuint framebuffer, GLsizei n, 627 const GLenum *bufs) 628 { 629 GET_CURRENT_CONTEXT(ctx); 630 struct gl_framebuffer *fb; 631 632 if (framebuffer) { 633 fb = _mesa_lookup_framebuffer(ctx, framebuffer); 634 } else { 635 fb = ctx->WinSysDrawBuffer; 636 } 637 638 draw_buffers_no_error(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers"); 639 } 640 641 642 void GLAPIENTRY 643 _mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, 644 const GLenum *bufs) 645 { 646 GET_CURRENT_CONTEXT(ctx); 647 struct gl_framebuffer *fb; 648 649 if (framebuffer) { 650 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 651 "glNamedFramebufferDrawBuffers"); 652 if (!fb) 653 return; 654 } 655 else 656 fb = ctx->WinSysDrawBuffer; 657 658 draw_buffers_error(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers"); 659 } 660 661 662 /** 663 * Performs necessary state updates when _mesa_drawbuffers makes an 664 * actual change. 665 */ 666 static void 667 updated_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb) 668 { 669 FLUSH_VERTICES(ctx, _NEW_BUFFERS); 670 671 if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) { 672 /* Flag the FBO as requiring validation. */ 673 if (_mesa_is_user_fbo(fb)) { 674 fb->_Status = 0; 675 } 676 } 677 } 678 679 680 /** 681 * Helper function to set the GL_DRAW_BUFFER state for the given context and 682 * FBO. Called via glDrawBuffer(), glDrawBuffersARB() 683 * 684 * All error checking will have been done prior to calling this function 685 * so nothing should go wrong at this point. 686 * 687 * \param ctx current context 688 * \param fb the desired draw buffer 689 * \param n number of color outputs to set 690 * \param buffers array[n] of colorbuffer names, like GL_LEFT. 691 * \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the 692 * colorbuffer names. (i.e. GL_FRONT_AND_BACK => 693 * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). 694 */ 695 void 696 _mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 697 GLuint n, const GLenum *buffers, const GLbitfield *destMask) 698 { 699 GLbitfield mask[MAX_DRAW_BUFFERS]; 700 GLuint buf; 701 702 if (!destMask) { 703 /* compute destMask values now */ 704 const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); 705 GLuint output; 706 for (output = 0; output < n; output++) { 707 mask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); 708 assert(mask[output] != BAD_MASK); 709 mask[output] &= supportedMask; 710 } 711 destMask = mask; 712 } 713 714 /* 715 * destMask[0] may have up to four bits set 716 * (ex: glDrawBuffer(GL_FRONT_AND_BACK)). 717 * Otherwise, destMask[x] can only have one bit set. 718 */ 719 if (n > 0 && _mesa_bitcount(destMask[0]) > 1) { 720 GLuint count = 0, destMask0 = destMask[0]; 721 while (destMask0) { 722 const gl_buffer_index bufIndex = u_bit_scan(&destMask0); 723 if (fb->_ColorDrawBufferIndexes[count] != bufIndex) { 724 updated_drawbuffers(ctx, fb); 725 fb->_ColorDrawBufferIndexes[count] = bufIndex; 726 } 727 count++; 728 } 729 fb->ColorDrawBuffer[0] = buffers[0]; 730 fb->_NumColorDrawBuffers = count; 731 } 732 else { 733 GLuint count = 0; 734 for (buf = 0; buf < n; buf++ ) { 735 if (destMask[buf]) { 736 gl_buffer_index bufIndex = ffs(destMask[buf]) - 1; 737 /* only one bit should be set in the destMask[buf] field */ 738 assert(_mesa_bitcount(destMask[buf]) == 1); 739 if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) { 740 updated_drawbuffers(ctx, fb); 741 fb->_ColorDrawBufferIndexes[buf] = bufIndex; 742 } 743 count = buf + 1; 744 } 745 else { 746 if (fb->_ColorDrawBufferIndexes[buf] != BUFFER_NONE) { 747 updated_drawbuffers(ctx, fb); 748 fb->_ColorDrawBufferIndexes[buf] = BUFFER_NONE; 749 } 750 } 751 fb->ColorDrawBuffer[buf] = buffers[buf]; 752 } 753 fb->_NumColorDrawBuffers = count; 754 } 755 756 /* set remaining outputs to BUFFER_NONE */ 757 for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) { 758 if (fb->_ColorDrawBufferIndexes[buf] != BUFFER_NONE) { 759 updated_drawbuffers(ctx, fb); 760 fb->_ColorDrawBufferIndexes[buf] = BUFFER_NONE; 761 } 762 } 763 for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) { 764 fb->ColorDrawBuffer[buf] = GL_NONE; 765 } 766 767 if (_mesa_is_winsys_fbo(fb)) { 768 /* also set context drawbuffer state */ 769 for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 770 if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) { 771 updated_drawbuffers(ctx, fb); 772 ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; 773 } 774 } 775 } 776 } 777 778 779 /** 780 * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc. 781 * from the context's Color.DrawBuffer[] state. 782 * Use when changing contexts. 783 */ 784 void 785 _mesa_update_draw_buffers(struct gl_context *ctx) 786 { 787 /* should be a window system FBO */ 788 assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); 789 790 _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers, 791 ctx->Color.DrawBuffer, NULL); 792 } 793 794 795 /** 796 * Like \sa _mesa_drawbuffers(), this is a helper function for setting 797 * GL_READ_BUFFER state for the given context and FBO. 798 * Note that all error checking should have been done before calling 799 * this function. 800 * \param ctx the rendering context 801 * \param fb the framebuffer object to update 802 * \param buffer GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc. 803 * \param bufferIndex the numerical index corresponding to 'buffer' 804 */ 805 void 806 _mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 807 GLenum buffer, gl_buffer_index bufferIndex) 808 { 809 if ((fb == ctx->ReadBuffer) && _mesa_is_winsys_fbo(fb)) { 810 /* Only update the per-context READ_BUFFER state if we're bound to 811 * a window-system framebuffer. 812 */ 813 ctx->Pixel.ReadBuffer = buffer; 814 } 815 816 fb->ColorReadBuffer = buffer; 817 fb->_ColorReadBufferIndex = bufferIndex; 818 819 ctx->NewState |= _NEW_BUFFERS; 820 } 821 822 823 824 /** 825 * Called by glReadBuffer and glNamedFramebufferReadBuffer to set the source 826 * renderbuffer for reading pixels. 827 * \param mode color buffer such as GL_FRONT, GL_BACK, etc. 828 */ 829 static ALWAYS_INLINE void 830 read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb, 831 GLenum buffer, const char *caller, bool no_error) 832 { 833 gl_buffer_index srcBuffer; 834 835 FLUSH_VERTICES(ctx, 0); 836 837 if (MESA_VERBOSE & VERBOSE_API) 838 _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer)); 839 840 if (buffer == GL_NONE) { 841 /* This is legal--it means that no buffer should be bound for reading. */ 842 srcBuffer = BUFFER_NONE; 843 } 844 else { 845 /* general case / window-system framebuffer */ 846 if (!no_error &&_mesa_is_gles3(ctx) && 847 !is_legal_es3_readbuffer_enum(buffer)) 848 srcBuffer = BUFFER_NONE; 849 else 850 srcBuffer = read_buffer_enum_to_index(ctx, buffer); 851 852 if (!no_error) { 853 GLbitfield supportedMask; 854 855 if (srcBuffer == BUFFER_NONE) { 856 _mesa_error(ctx, GL_INVALID_ENUM, 857 "%s(invalid buffer %s)", caller, 858 _mesa_enum_to_string(buffer)); 859 return; 860 } 861 862 supportedMask = supported_buffer_bitmask(ctx, fb); 863 if (((1 << srcBuffer) & supportedMask) == 0) { 864 _mesa_error(ctx, GL_INVALID_OPERATION, 865 "%s(invalid buffer %s)", caller, 866 _mesa_enum_to_string(buffer)); 867 return; 868 } 869 } 870 } 871 872 /* OK, all error checking has been completed now */ 873 874 _mesa_readbuffer(ctx, fb, buffer, srcBuffer); 875 876 /* Call the device driver function only if fb is the bound read buffer */ 877 if (fb == ctx->ReadBuffer) { 878 if (ctx->Driver.ReadBuffer) 879 ctx->Driver.ReadBuffer(ctx, buffer); 880 } 881 } 882 883 884 static void 885 read_buffer_err(struct gl_context *ctx, struct gl_framebuffer *fb, 886 GLenum buffer, const char *caller) 887 { 888 read_buffer(ctx, fb, buffer, caller, false); 889 } 890 891 892 static void 893 read_buffer_no_error(struct gl_context *ctx, struct gl_framebuffer *fb, 894 GLenum buffer, const char *caller) 895 { 896 read_buffer(ctx, fb, buffer, caller, true); 897 } 898 899 900 void GLAPIENTRY 901 _mesa_ReadBuffer_no_error(GLenum buffer) 902 { 903 GET_CURRENT_CONTEXT(ctx); 904 read_buffer_no_error(ctx, ctx->ReadBuffer, buffer, "glReadBuffer"); 905 } 906 907 908 void GLAPIENTRY 909 _mesa_ReadBuffer(GLenum buffer) 910 { 911 GET_CURRENT_CONTEXT(ctx); 912 read_buffer_err(ctx, ctx->ReadBuffer, buffer, "glReadBuffer"); 913 } 914 915 916 void GLAPIENTRY 917 _mesa_NamedFramebufferReadBuffer_no_error(GLuint framebuffer, GLenum src) 918 { 919 GET_CURRENT_CONTEXT(ctx); 920 921 struct gl_framebuffer *fb; 922 923 if (framebuffer) { 924 fb = _mesa_lookup_framebuffer(ctx, framebuffer); 925 } else { 926 fb = ctx->WinSysReadBuffer; 927 } 928 929 read_buffer_no_error(ctx, fb, src, "glNamedFramebufferReadBuffer"); 930 } 931 932 933 void GLAPIENTRY 934 _mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src) 935 { 936 GET_CURRENT_CONTEXT(ctx); 937 struct gl_framebuffer *fb; 938 939 if (framebuffer) { 940 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 941 "glNamedFramebufferReadBuffer"); 942 if (!fb) 943 return; 944 } 945 else 946 fb = ctx->WinSysReadBuffer; 947 948 read_buffer_err(ctx, fb, src, "glNamedFramebufferReadBuffer"); 949 } 950