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