1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 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 * Functions for allocating/managing framebuffers and renderbuffers. 28 * Also, routines for reading/writing renderbuffer data as ubytes, 29 * ushorts, uints, etc. 30 */ 31 32 #include <stdio.h> 33 #include "glheader.h" 34 #include "imports.h" 35 #include "blend.h" 36 #include "buffers.h" 37 #include "context.h" 38 #include "enums.h" 39 #include "formats.h" 40 #include "macros.h" 41 #include "mtypes.h" 42 #include "fbobject.h" 43 #include "framebuffer.h" 44 #include "renderbuffer.h" 45 #include "texobj.h" 46 #include "glformats.h" 47 #include "state.h" 48 49 50 51 /** 52 * Compute/set the _DepthMax field for the given framebuffer. 53 * This value depends on the Z buffer resolution. 54 */ 55 static void 56 compute_depth_max(struct gl_framebuffer *fb) 57 { 58 if (fb->Visual.depthBits == 0) { 59 /* Special case. Even if we don't have a depth buffer we need 60 * good values for DepthMax for Z vertex transformation purposes 61 * and for per-fragment fog computation. 62 */ 63 fb->_DepthMax = (1 << 16) - 1; 64 } 65 else if (fb->Visual.depthBits < 32) { 66 fb->_DepthMax = (1 << fb->Visual.depthBits) - 1; 67 } 68 else { 69 /* Special case since shift values greater than or equal to the 70 * number of bits in the left hand expression's type are undefined. 71 */ 72 fb->_DepthMax = 0xffffffff; 73 } 74 fb->_DepthMaxF = (GLfloat) fb->_DepthMax; 75 76 /* Minimum resolvable depth value, for polygon offset */ 77 fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF; 78 } 79 80 /** 81 * Create and initialize a gl_framebuffer object. 82 * This is intended for creating _window_system_ framebuffers, not generic 83 * framebuffer objects ala GL_EXT_framebuffer_object. 84 * 85 * \sa _mesa_new_framebuffer 86 */ 87 struct gl_framebuffer * 88 _mesa_create_framebuffer(const struct gl_config *visual) 89 { 90 struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); 91 assert(visual); 92 if (fb) { 93 _mesa_initialize_window_framebuffer(fb, visual); 94 } 95 return fb; 96 } 97 98 99 /** 100 * Allocate a new gl_framebuffer object. 101 * This is the default function for ctx->Driver.NewFramebuffer(). 102 * This is for allocating user-created framebuffers, not window-system 103 * framebuffers! 104 * \sa _mesa_create_framebuffer 105 */ 106 struct gl_framebuffer * 107 _mesa_new_framebuffer(struct gl_context *ctx, GLuint name) 108 { 109 struct gl_framebuffer *fb; 110 (void) ctx; 111 assert(name != 0); 112 fb = CALLOC_STRUCT(gl_framebuffer); 113 if (fb) { 114 _mesa_initialize_user_framebuffer(fb, name); 115 } 116 return fb; 117 } 118 119 120 /** 121 * Initialize a gl_framebuffer object. Typically used to initialize 122 * window system-created framebuffers, not user-created framebuffers. 123 * \sa _mesa_initialize_user_framebuffer 124 */ 125 void 126 _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, 127 const struct gl_config *visual) 128 { 129 assert(fb); 130 assert(visual); 131 132 memset(fb, 0, sizeof(struct gl_framebuffer)); 133 134 simple_mtx_init(&fb->Mutex, mtx_plain); 135 136 fb->RefCount = 1; 137 138 /* save the visual */ 139 fb->Visual = *visual; 140 141 /* Init read/draw renderbuffer state */ 142 if (visual->doubleBufferMode) { 143 fb->_NumColorDrawBuffers = 1; 144 fb->ColorDrawBuffer[0] = GL_BACK; 145 fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT; 146 fb->ColorReadBuffer = GL_BACK; 147 fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT; 148 } 149 else { 150 fb->_NumColorDrawBuffers = 1; 151 fb->ColorDrawBuffer[0] = GL_FRONT; 152 fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT; 153 fb->ColorReadBuffer = GL_FRONT; 154 fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT; 155 } 156 157 fb->Delete = _mesa_destroy_framebuffer; 158 fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; 159 fb->_AllColorBuffersFixedPoint = !visual->floatMode; 160 fb->_HasSNormOrFloatColorBuffer = visual->floatMode; 161 fb->_HasAttachments = true; 162 163 compute_depth_max(fb); 164 } 165 166 167 /** 168 * Initialize a user-created gl_framebuffer object. 169 * \sa _mesa_initialize_window_framebuffer 170 */ 171 void 172 _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name) 173 { 174 assert(fb); 175 assert(name); 176 177 memset(fb, 0, sizeof(struct gl_framebuffer)); 178 179 fb->Name = name; 180 fb->RefCount = 1; 181 fb->_NumColorDrawBuffers = 1; 182 fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; 183 fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; 184 fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; 185 fb->_ColorReadBufferIndex = BUFFER_COLOR0; 186 fb->Delete = _mesa_destroy_framebuffer; 187 simple_mtx_init(&fb->Mutex, mtx_plain); 188 } 189 190 191 /** 192 * Deallocate buffer and everything attached to it. 193 * Typically called via the gl_framebuffer->Delete() method. 194 */ 195 void 196 _mesa_destroy_framebuffer(struct gl_framebuffer *fb) 197 { 198 if (fb) { 199 _mesa_free_framebuffer_data(fb); 200 free(fb->Label); 201 free(fb); 202 } 203 } 204 205 206 /** 207 * Free all the data hanging off the given gl_framebuffer, but don't free 208 * the gl_framebuffer object itself. 209 */ 210 void 211 _mesa_free_framebuffer_data(struct gl_framebuffer *fb) 212 { 213 GLuint i; 214 215 assert(fb); 216 assert(fb->RefCount == 0); 217 218 simple_mtx_destroy(&fb->Mutex); 219 220 for (i = 0; i < BUFFER_COUNT; i++) { 221 struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; 222 if (att->Renderbuffer) { 223 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 224 } 225 if (att->Texture) { 226 _mesa_reference_texobj(&att->Texture, NULL); 227 } 228 assert(!att->Renderbuffer); 229 assert(!att->Texture); 230 att->Type = GL_NONE; 231 } 232 } 233 234 235 /** 236 * Set *ptr to point to fb, with refcounting and locking. 237 * This is normally only called from the _mesa_reference_framebuffer() macro 238 * when there's a real pointer change. 239 */ 240 void 241 _mesa_reference_framebuffer_(struct gl_framebuffer **ptr, 242 struct gl_framebuffer *fb) 243 { 244 if (*ptr) { 245 /* unreference old renderbuffer */ 246 GLboolean deleteFlag = GL_FALSE; 247 struct gl_framebuffer *oldFb = *ptr; 248 249 simple_mtx_lock(&oldFb->Mutex); 250 assert(oldFb->RefCount > 0); 251 oldFb->RefCount--; 252 deleteFlag = (oldFb->RefCount == 0); 253 simple_mtx_unlock(&oldFb->Mutex); 254 255 if (deleteFlag) 256 oldFb->Delete(oldFb); 257 258 *ptr = NULL; 259 } 260 261 if (fb) { 262 simple_mtx_lock(&fb->Mutex); 263 fb->RefCount++; 264 simple_mtx_unlock(&fb->Mutex); 265 *ptr = fb; 266 } 267 } 268 269 270 /** 271 * Resize the given framebuffer's renderbuffers to the new width and height. 272 * This should only be used for window-system framebuffers, not 273 * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object). 274 * This will typically be called directly from a device driver. 275 * 276 * \note it's possible for ctx to be null since a window can be resized 277 * without a currently bound rendering context. 278 */ 279 void 280 _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 281 GLuint width, GLuint height) 282 { 283 GLuint i; 284 285 /* XXX I think we could check if the size is not changing 286 * and return early. 287 */ 288 289 /* Can only resize win-sys framebuffer objects */ 290 assert(_mesa_is_winsys_fbo(fb)); 291 292 for (i = 0; i < BUFFER_COUNT; i++) { 293 struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; 294 if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) { 295 struct gl_renderbuffer *rb = att->Renderbuffer; 296 /* only resize if size is changing */ 297 if (rb->Width != width || rb->Height != height) { 298 if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) { 299 assert(rb->Width == width); 300 assert(rb->Height == height); 301 } 302 else { 303 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer"); 304 /* no return */ 305 } 306 } 307 } 308 } 309 310 fb->Width = width; 311 fb->Height = height; 312 313 if (ctx) { 314 /* update scissor / window bounds */ 315 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); 316 /* Signal new buffer state so that swrast will update its clipping 317 * info (the CLIP_BIT flag). 318 */ 319 ctx->NewState |= _NEW_BUFFERS; 320 } 321 } 322 323 /** 324 * Given a bounding box, intersect the bounding box with the scissor of 325 * a specified vieport. 326 * 327 * \param ctx GL context. 328 * \param idx Index of the desired viewport 329 * \param bbox Bounding box for the scissored viewport. Stored as xmin, 330 * xmax, ymin, ymax. 331 */ 332 void 333 _mesa_intersect_scissor_bounding_box(const struct gl_context *ctx, 334 unsigned idx, int *bbox) 335 { 336 if (ctx->Scissor.EnableFlags & (1u << idx)) { 337 if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) { 338 bbox[0] = ctx->Scissor.ScissorArray[idx].X; 339 } 340 if (ctx->Scissor.ScissorArray[idx].Y > bbox[2]) { 341 bbox[2] = ctx->Scissor.ScissorArray[idx].Y; 342 } 343 if (ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width < bbox[1]) { 344 bbox[1] = ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width; 345 } 346 if (ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height < bbox[3]) { 347 bbox[3] = ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height; 348 } 349 /* finally, check for empty region */ 350 if (bbox[0] > bbox[1]) { 351 bbox[0] = bbox[1]; 352 } 353 if (bbox[2] > bbox[3]) { 354 bbox[2] = bbox[3]; 355 } 356 } 357 } 358 359 /** 360 * Calculate the inclusive bounding box for the scissor of a specific viewport 361 * 362 * \param ctx GL context. 363 * \param buffer Framebuffer to be checked against 364 * \param idx Index of the desired viewport 365 * \param bbox Bounding box for the scissored viewport. Stored as xmin, 366 * xmax, ymin, ymax. 367 * 368 * \warning This function assumes that the framebuffer dimensions are up to 369 * date. 370 * 371 * \sa _mesa_clip_to_region 372 */ 373 static void 374 scissor_bounding_box(const struct gl_context *ctx, 375 const struct gl_framebuffer *buffer, 376 unsigned idx, int *bbox) 377 { 378 bbox[0] = 0; 379 bbox[2] = 0; 380 bbox[1] = buffer->Width; 381 bbox[3] = buffer->Height; 382 383 _mesa_intersect_scissor_bounding_box(ctx, idx, bbox); 384 385 assert(bbox[0] <= bbox[1]); 386 assert(bbox[2] <= bbox[3]); 387 } 388 389 /** 390 * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields. 391 * These values are computed from the buffer's width and height and 392 * the scissor box, if it's enabled. 393 * \param ctx the GL context. 394 */ 395 void 396 _mesa_update_draw_buffer_bounds(struct gl_context *ctx, 397 struct gl_framebuffer *buffer) 398 { 399 int bbox[4]; 400 401 if (!buffer) 402 return; 403 404 /* Default to the first scissor as that's always valid */ 405 scissor_bounding_box(ctx, buffer, 0, bbox); 406 buffer->_Xmin = bbox[0]; 407 buffer->_Ymin = bbox[2]; 408 buffer->_Xmax = bbox[1]; 409 buffer->_Ymax = bbox[3]; 410 } 411 412 413 /** 414 * The glGet queries of the framebuffer red/green/blue size, stencil size, 415 * etc. are satisfied by the fields of ctx->DrawBuffer->Visual. These can 416 * change depending on the renderbuffer bindings. This function updates 417 * the given framebuffer's Visual from the current renderbuffer bindings. 418 * 419 * This may apply to user-created framebuffers or window system framebuffers. 420 * 421 * Also note: ctx->DrawBuffer->Visual.depthBits might not equal 422 * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits. 423 * The former one is used to convert floating point depth values into 424 * integer Z values. 425 */ 426 void 427 _mesa_update_framebuffer_visual(struct gl_context *ctx, 428 struct gl_framebuffer *fb) 429 { 430 GLuint i; 431 432 memset(&fb->Visual, 0, sizeof(fb->Visual)); 433 fb->Visual.rgbMode = GL_TRUE; /* assume this */ 434 435 /* find first RGB renderbuffer */ 436 for (i = 0; i < BUFFER_COUNT; i++) { 437 if (fb->Attachment[i].Renderbuffer) { 438 const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; 439 const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); 440 const mesa_format fmt = rb->Format; 441 442 /* Grab samples and sampleBuffers from any attachment point (assuming 443 * the framebuffer is complete, we'll get the same answer from all 444 * attachments). 445 */ 446 fb->Visual.samples = rb->NumSamples; 447 fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0; 448 449 if (_mesa_is_legal_color_format(ctx, baseFormat)) { 450 fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS); 451 fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS); 452 fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS); 453 fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS); 454 fb->Visual.rgbBits = fb->Visual.redBits 455 + fb->Visual.greenBits + fb->Visual.blueBits; 456 if (_mesa_get_format_color_encoding(fmt) == GL_SRGB) 457 fb->Visual.sRGBCapable = ctx->Extensions.EXT_framebuffer_sRGB; 458 break; 459 } 460 } 461 } 462 463 fb->Visual.floatMode = GL_FALSE; 464 for (i = 0; i < BUFFER_COUNT; i++) { 465 if (fb->Attachment[i].Renderbuffer) { 466 const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; 467 const mesa_format fmt = rb->Format; 468 469 if (_mesa_get_format_datatype(fmt) == GL_FLOAT) { 470 fb->Visual.floatMode = GL_TRUE; 471 break; 472 } 473 } 474 } 475 476 if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { 477 const struct gl_renderbuffer *rb = 478 fb->Attachment[BUFFER_DEPTH].Renderbuffer; 479 const mesa_format fmt = rb->Format; 480 fb->Visual.haveDepthBuffer = GL_TRUE; 481 fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS); 482 } 483 484 if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { 485 const struct gl_renderbuffer *rb = 486 fb->Attachment[BUFFER_STENCIL].Renderbuffer; 487 const mesa_format fmt = rb->Format; 488 fb->Visual.haveStencilBuffer = GL_TRUE; 489 fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS); 490 } 491 492 if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) { 493 const struct gl_renderbuffer *rb = 494 fb->Attachment[BUFFER_ACCUM].Renderbuffer; 495 const mesa_format fmt = rb->Format; 496 fb->Visual.haveAccumBuffer = GL_TRUE; 497 fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS); 498 fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS); 499 fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS); 500 fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS); 501 } 502 503 compute_depth_max(fb); 504 } 505 506 507 /* 508 * Example DrawBuffers scenarios: 509 * 510 * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to 511 * "gl_FragColor" or program writes to the "result.color" register: 512 * 513 * fragment color output renderbuffer 514 * --------------------- --------------- 515 * color[0] Front, Back 516 * 517 * 518 * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to 519 * gl_FragData[i] or program writes to result.color[i] registers: 520 * 521 * fragment color output renderbuffer 522 * --------------------- --------------- 523 * color[0] Front 524 * color[1] Aux0 525 * color[3] Aux1 526 * 527 * 528 * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to 529 * gl_FragColor, or fixed function: 530 * 531 * fragment color output renderbuffer 532 * --------------------- --------------- 533 * color[0] Front, Aux0, Aux1 534 * 535 * 536 * In either case, the list of renderbuffers is stored in the 537 * framebuffer->_ColorDrawBuffers[] array and 538 * framebuffer->_NumColorDrawBuffers indicates the number of buffers. 539 * The renderer (like swrast) has to look at the current fragment shader 540 * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine 541 * how to map color outputs to renderbuffers. 542 * 543 * Note that these two calls are equivalent (for fixed function fragment 544 * shading anyway): 545 * a) glDrawBuffer(GL_FRONT_AND_BACK); (assuming non-stereo framebuffer) 546 * b) glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]); 547 */ 548 549 550 551 552 /** 553 * Update the (derived) list of color drawing renderbuffer pointers. 554 * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers 555 * writing colors. 556 */ 557 static void 558 update_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb) 559 { 560 GLuint output; 561 562 /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */ 563 fb->_ColorDrawBuffers[0] = NULL; 564 565 for (output = 0; output < fb->_NumColorDrawBuffers; output++) { 566 gl_buffer_index buf = fb->_ColorDrawBufferIndexes[output]; 567 if (buf != BUFFER_NONE) { 568 fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer; 569 } 570 else { 571 fb->_ColorDrawBuffers[output] = NULL; 572 } 573 } 574 } 575 576 577 /** 578 * Update the (derived) color read renderbuffer pointer. 579 * Unlike the DrawBuffer, we can only read from one (or zero) color buffers. 580 */ 581 static void 582 update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) 583 { 584 (void) ctx; 585 if (fb->_ColorReadBufferIndex == BUFFER_NONE || 586 fb->DeletePending || 587 fb->Width == 0 || 588 fb->Height == 0) { 589 fb->_ColorReadBuffer = NULL; /* legal! */ 590 } 591 else { 592 assert(fb->_ColorReadBufferIndex >= 0); 593 assert(fb->_ColorReadBufferIndex < BUFFER_COUNT); 594 fb->_ColorReadBuffer 595 = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer; 596 } 597 } 598 599 600 /** 601 * Update a gl_framebuffer's derived state. 602 * 603 * Specifically, update these framebuffer fields: 604 * _ColorDrawBuffers 605 * _NumColorDrawBuffers 606 * _ColorReadBuffer 607 * 608 * If the framebuffer is user-created, make sure it's complete. 609 * 610 * The following functions (at least) can effect framebuffer state: 611 * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT, 612 * glRenderbufferStorageEXT. 613 */ 614 static void 615 update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 616 { 617 if (_mesa_is_winsys_fbo(fb)) { 618 /* This is a window-system framebuffer */ 619 /* Need to update the FB's GL_DRAW_BUFFER state to match the 620 * context state (GL_READ_BUFFER too). 621 */ 622 if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) { 623 _mesa_drawbuffers(ctx, fb, ctx->Const.MaxDrawBuffers, 624 ctx->Color.DrawBuffer, NULL); 625 } 626 } 627 else { 628 /* This is a user-created framebuffer. 629 * Completeness only matters for user-created framebuffers. 630 */ 631 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) { 632 _mesa_test_framebuffer_completeness(ctx, fb); 633 } 634 } 635 636 /* Strictly speaking, we don't need to update the draw-state 637 * if this FB is bound as ctx->ReadBuffer (and conversely, the 638 * read-state if this FB is bound as ctx->DrawBuffer), but no 639 * harm. 640 */ 641 update_color_draw_buffers(ctx, fb); 642 update_color_read_buffer(ctx, fb); 643 644 compute_depth_max(fb); 645 } 646 647 648 /** 649 * Update state related to the draw/read framebuffers. 650 */ 651 void 652 _mesa_update_framebuffer(struct gl_context *ctx, 653 struct gl_framebuffer *readFb, 654 struct gl_framebuffer *drawFb) 655 { 656 assert(ctx); 657 658 update_framebuffer(ctx, drawFb); 659 if (readFb != drawFb) 660 update_framebuffer(ctx, readFb); 661 662 _mesa_update_clamp_vertex_color(ctx, drawFb); 663 _mesa_update_clamp_fragment_color(ctx, drawFb); 664 } 665 666 667 /** 668 * Check if the renderbuffer for a read/draw operation exists. 669 * \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA, 670 * GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL. 671 * \param reading if TRUE, we're going to read from the buffer, 672 if FALSE, we're going to write to the buffer. 673 * \return GL_TRUE if buffer exists, GL_FALSE otherwise 674 */ 675 static GLboolean 676 renderbuffer_exists(struct gl_context *ctx, 677 struct gl_framebuffer *fb, 678 GLenum format, 679 GLboolean reading) 680 { 681 const struct gl_renderbuffer_attachment *att = fb->Attachment; 682 683 /* If we don't know the framebuffer status, update it now */ 684 if (fb->_Status == 0) { 685 _mesa_test_framebuffer_completeness(ctx, fb); 686 } 687 688 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 689 return GL_FALSE; 690 } 691 692 switch (format) { 693 case GL_COLOR: 694 case GL_RED: 695 case GL_GREEN: 696 case GL_BLUE: 697 case GL_ALPHA: 698 case GL_LUMINANCE: 699 case GL_LUMINANCE_ALPHA: 700 case GL_INTENSITY: 701 case GL_RG: 702 case GL_RGB: 703 case GL_BGR: 704 case GL_RGBA: 705 case GL_BGRA: 706 case GL_ABGR_EXT: 707 case GL_RED_INTEGER_EXT: 708 case GL_RG_INTEGER: 709 case GL_GREEN_INTEGER_EXT: 710 case GL_BLUE_INTEGER_EXT: 711 case GL_ALPHA_INTEGER_EXT: 712 case GL_RGB_INTEGER_EXT: 713 case GL_RGBA_INTEGER_EXT: 714 case GL_BGR_INTEGER_EXT: 715 case GL_BGRA_INTEGER_EXT: 716 case GL_LUMINANCE_INTEGER_EXT: 717 case GL_LUMINANCE_ALPHA_INTEGER_EXT: 718 if (reading) { 719 /* about to read from a color buffer */ 720 const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer; 721 if (!readBuf) { 722 return GL_FALSE; 723 } 724 assert(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 || 725 _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 || 726 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 || 727 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 || 728 _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0); 729 } 730 else { 731 /* about to draw to zero or more color buffers (none is OK) */ 732 return GL_TRUE; 733 } 734 break; 735 case GL_DEPTH: 736 case GL_DEPTH_COMPONENT: 737 if (att[BUFFER_DEPTH].Type == GL_NONE) { 738 return GL_FALSE; 739 } 740 break; 741 case GL_STENCIL: 742 case GL_STENCIL_INDEX: 743 if (att[BUFFER_STENCIL].Type == GL_NONE) { 744 return GL_FALSE; 745 } 746 break; 747 case GL_DEPTH_STENCIL_EXT: 748 if (att[BUFFER_DEPTH].Type == GL_NONE || 749 att[BUFFER_STENCIL].Type == GL_NONE) { 750 return GL_FALSE; 751 } 752 break; 753 default: 754 _mesa_problem(ctx, 755 "Unexpected format 0x%x in renderbuffer_exists", 756 format); 757 return GL_FALSE; 758 } 759 760 /* OK */ 761 return GL_TRUE; 762 } 763 764 765 /** 766 * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels, 767 * glCopyTex[Sub]Image, etc) exists. 768 * \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA, 769 * GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL. 770 * \return GL_TRUE if buffer exists, GL_FALSE otherwise 771 */ 772 GLboolean 773 _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format) 774 { 775 return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE); 776 } 777 778 779 /** 780 * As above, but for drawing operations. 781 */ 782 GLboolean 783 _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) 784 { 785 return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE); 786 } 787 788 789 /** 790 * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using 791 * GetIntegerv, GetFramebufferParameteriv, etc) 792 * 793 * If @fb is NULL, the method returns the value for the current bound 794 * framebuffer. 795 */ 796 GLenum 797 _mesa_get_color_read_format(struct gl_context *ctx, 798 struct gl_framebuffer *fb, 799 const char *caller) 800 { 801 if (ctx->NewState) 802 _mesa_update_state(ctx); 803 804 if (fb == NULL) 805 fb = ctx->ReadBuffer; 806 807 if (!fb || !fb->_ColorReadBuffer) { 808 /* 809 * From OpenGL 4.5 spec, section 18.2.2 "ReadPixels": 810 * 811 * "An INVALID_OPERATION error is generated by GetIntegerv if pname 812 * is IMPLEMENTATION_COLOR_READ_FORMAT or IMPLEMENTATION_COLOR_- 813 * READ_TYPE and any of: 814 * * the read framebuffer is not framebuffer complete. 815 * * the read framebuffer is a framebuffer object, and the selected 816 * read buffer (see section 18.2.1) has no image attached. 817 * * the selected read buffer is NONE." 818 * 819 * There is not equivalent quote for GetFramebufferParameteriv or 820 * GetNamedFramebufferParameteriv, but from section 9.2.3 "Framebuffer 821 * Object Queries": 822 * 823 * "Values of framebuffer-dependent state are identical to those that 824 * would be obtained were the framebuffer object bound and queried 825 * using the simple state queries in that table." 826 * 827 * Where "using the simple state queries" refer to use GetIntegerv. So 828 * we will assume that on that situation the same error should be 829 * triggered too. 830 */ 831 _mesa_error(ctx, GL_INVALID_OPERATION, 832 "%s(GL_IMPLEMENTATION_COLOR_READ_FORMAT: no GL_READ_BUFFER)", 833 caller); 834 return GL_NONE; 835 } 836 else { 837 const mesa_format format = fb->_ColorReadBuffer->Format; 838 const GLenum data_type = _mesa_get_format_datatype(format); 839 840 if (format == MESA_FORMAT_B8G8R8A8_UNORM) 841 return GL_BGRA; 842 else if (format == MESA_FORMAT_B5G6R5_UNORM) 843 return GL_RGB; 844 else if (format == MESA_FORMAT_R_UNORM8) 845 return GL_RED; 846 847 switch (data_type) { 848 case GL_UNSIGNED_INT: 849 case GL_INT: 850 return GL_RGBA_INTEGER; 851 default: 852 return GL_RGBA; 853 } 854 } 855 } 856 857 858 /** 859 * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES queries (using 860 * GetIntegerv, GetFramebufferParameteriv, etc) 861 * 862 * If @fb is NULL, the method returns the value for the current bound 863 * framebuffer. 864 */ 865 GLenum 866 _mesa_get_color_read_type(struct gl_context *ctx, 867 struct gl_framebuffer *fb, 868 const char *caller) 869 { 870 if (ctx->NewState) 871 _mesa_update_state(ctx); 872 873 if (fb == NULL) 874 fb = ctx->ReadBuffer; 875 876 if (!fb || !fb->_ColorReadBuffer) { 877 /* 878 * See comment on _mesa_get_color_read_format 879 */ 880 _mesa_error(ctx, GL_INVALID_OPERATION, 881 "%s(GL_IMPLEMENTATION_COLOR_READ_TYPE: no GL_READ_BUFFER)", 882 caller); 883 return GL_NONE; 884 } 885 else { 886 const GLenum format = fb->_ColorReadBuffer->Format; 887 const GLenum data_type = _mesa_get_format_datatype(format); 888 889 if (format == MESA_FORMAT_B5G6R5_UNORM) 890 return GL_UNSIGNED_SHORT_5_6_5; 891 892 if (format == MESA_FORMAT_B10G10R10A2_UNORM || 893 format == MESA_FORMAT_B10G10R10X2_UNORM) 894 return GL_UNSIGNED_INT_2_10_10_10_REV; 895 896 switch (data_type) { 897 case GL_SIGNED_NORMALIZED: 898 return GL_BYTE; 899 case GL_UNSIGNED_INT: 900 case GL_INT: 901 case GL_FLOAT: 902 return data_type; 903 case GL_UNSIGNED_NORMALIZED: 904 default: 905 return GL_UNSIGNED_BYTE; 906 } 907 } 908 } 909 910 911 /** 912 * Returns the read renderbuffer for the specified format. 913 */ 914 struct gl_renderbuffer * 915 _mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, 916 GLenum format) 917 { 918 const struct gl_framebuffer *rfb = ctx->ReadBuffer; 919 920 if (_mesa_is_color_format(format)) { 921 return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer; 922 } else if (_mesa_is_depth_format(format) || 923 _mesa_is_depthstencil_format(format)) { 924 return rfb->Attachment[BUFFER_DEPTH].Renderbuffer; 925 } else { 926 return rfb->Attachment[BUFFER_STENCIL].Renderbuffer; 927 } 928 } 929 930 931 /** 932 * Print framebuffer info to stderr, for debugging. 933 */ 934 void 935 _mesa_print_framebuffer(const struct gl_framebuffer *fb) 936 { 937 GLuint i; 938 939 fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb); 940 fprintf(stderr, " Size: %u x %u Status: %s\n", fb->Width, fb->Height, 941 _mesa_enum_to_string(fb->_Status)); 942 fprintf(stderr, " Attachments:\n"); 943 944 for (i = 0; i < BUFFER_COUNT; i++) { 945 const struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; 946 if (att->Type == GL_TEXTURE) { 947 const struct gl_texture_image *texImage = att->Renderbuffer->TexImage; 948 fprintf(stderr, 949 " %2d: Texture %u, level %u, face %u, slice %u, complete %d\n", 950 i, att->Texture->Name, att->TextureLevel, att->CubeMapFace, 951 att->Zoffset, att->Complete); 952 fprintf(stderr, " Size: %u x %u x %u Format %s\n", 953 texImage->Width, texImage->Height, texImage->Depth, 954 _mesa_get_format_name(texImage->TexFormat)); 955 } 956 else if (att->Type == GL_RENDERBUFFER) { 957 fprintf(stderr, " %2d: Renderbuffer %u, complete %d\n", 958 i, att->Renderbuffer->Name, att->Complete); 959 fprintf(stderr, " Size: %u x %u Format %s\n", 960 att->Renderbuffer->Width, att->Renderbuffer->Height, 961 _mesa_get_format_name(att->Renderbuffer->Format)); 962 } 963 else { 964 fprintf(stderr, " %2d: none\n", i); 965 } 966 } 967 } 968 969 bool 970 _mesa_is_front_buffer_reading(const struct gl_framebuffer *fb) 971 { 972 if (!fb || _mesa_is_user_fbo(fb)) 973 return false; 974 975 return fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT; 976 } 977 978 bool 979 _mesa_is_front_buffer_drawing(const struct gl_framebuffer *fb) 980 { 981 if (!fb || _mesa_is_user_fbo(fb)) 982 return false; 983 984 return (fb->_NumColorDrawBuffers >= 1 && 985 fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT); 986 } 987 988 static inline GLuint 989 _mesa_geometric_nonvalidated_samples(const struct gl_framebuffer *buffer) 990 { 991 return buffer->_HasAttachments ? 992 buffer->Visual.samples : 993 buffer->DefaultGeometry.NumSamples; 994 } 995 996 bool 997 _mesa_is_multisample_enabled(const struct gl_context *ctx) 998 { 999 /* The sample count may not be validated by the driver, but when it is set, 1000 * we know that is in a valid range and no driver should ever validate a 1001 * multisampled framebuffer to non-multisampled and vice-versa. 1002 */ 1003 return ctx->Multisample.Enabled && 1004 ctx->DrawBuffer && 1005 _mesa_geometric_nonvalidated_samples(ctx->DrawBuffer) >= 1; 1006 } 1007 1008 /** 1009 * Is alpha testing enabled and applicable to the currently bound 1010 * framebuffer? 1011 */ 1012 bool 1013 _mesa_is_alpha_test_enabled(const struct gl_context *ctx) 1014 { 1015 bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; 1016 return (ctx->Color.AlphaEnabled && !buffer0_is_integer); 1017 } 1018 1019 /** 1020 * Is alpha to coverage enabled and applicable to the currently bound 1021 * framebuffer? 1022 */ 1023 bool 1024 _mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx) 1025 { 1026 bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; 1027 return (ctx->Multisample.SampleAlphaToCoverage && 1028 _mesa_is_multisample_enabled(ctx) && 1029 !buffer0_is_integer); 1030 } 1031