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