fbobject.c revision 7ec681f3
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 1999-2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/* 28 * GL_EXT/ARB_framebuffer_object extensions 29 * 30 * Authors: 31 * Brian Paul 32 */ 33 34#include <stdbool.h> 35 36#include "buffers.h" 37#include "context.h" 38#include "debug_output.h" 39#include "draw_validate.h" 40#include "enums.h" 41#include "fbobject.h" 42#include "formats.h" 43#include "framebuffer.h" 44#include "glformats.h" 45#include "hash.h" 46#include "macros.h" 47#include "multisample.h" 48#include "mtypes.h" 49#include "renderbuffer.h" 50#include "state.h" 51#include "teximage.h" 52#include "texobj.h" 53 54 55/** 56 * Notes: 57 * 58 * None of the GL_EXT_framebuffer_object functions are compiled into 59 * display lists. 60 */ 61 62 63 64static void 65delete_dummy_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) 66{ 67 /* no op */ 68} 69 70static void 71delete_dummy_framebuffer(struct gl_framebuffer *fb) 72{ 73 /* no op */ 74} 75 76 77/* 78 * When glGenRender/FramebuffersEXT() is called we insert pointers to 79 * these placeholder objects into the hash table. 80 * Later, when the object ID is first bound, we replace the placeholder 81 * with the real frame/renderbuffer. 82 */ 83static struct gl_framebuffer DummyFramebuffer = { 84 .Mutex = _SIMPLE_MTX_INITIALIZER_NP, 85 .Delete = delete_dummy_framebuffer, 86}; 87static struct gl_renderbuffer DummyRenderbuffer = { 88 .Delete = delete_dummy_renderbuffer, 89}; 90 91/* We bind this framebuffer when applications pass a NULL 92 * drawable/surface in make current. */ 93static struct gl_framebuffer IncompleteFramebuffer = { 94 .Mutex = _SIMPLE_MTX_INITIALIZER_NP, 95 .Delete = delete_dummy_framebuffer, 96}; 97 98 99struct gl_framebuffer * 100_mesa_get_incomplete_framebuffer(void) 101{ 102 return &IncompleteFramebuffer; 103} 104 105/** 106 * Helper routine for getting a gl_renderbuffer. 107 */ 108struct gl_renderbuffer * 109_mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id) 110{ 111 struct gl_renderbuffer *rb; 112 113 if (id == 0) 114 return NULL; 115 116 rb = (struct gl_renderbuffer *) 117 _mesa_HashLookup(ctx->Shared->RenderBuffers, id); 118 return rb; 119} 120 121 122/** 123 * A convenience function for direct state access that throws 124 * GL_INVALID_OPERATION if the renderbuffer doesn't exist. 125 */ 126struct gl_renderbuffer * 127_mesa_lookup_renderbuffer_err(struct gl_context *ctx, GLuint id, 128 const char *func) 129{ 130 struct gl_renderbuffer *rb; 131 132 rb = _mesa_lookup_renderbuffer(ctx, id); 133 if (!rb || rb == &DummyRenderbuffer) { 134 _mesa_error(ctx, GL_INVALID_OPERATION, 135 "%s(non-existent renderbuffer %u)", func, id); 136 return NULL; 137 } 138 139 return rb; 140} 141 142 143/** 144 * Helper routine for getting a gl_framebuffer. 145 */ 146struct gl_framebuffer * 147_mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id) 148{ 149 struct gl_framebuffer *fb; 150 151 if (id == 0) 152 return NULL; 153 154 fb = (struct gl_framebuffer *) 155 _mesa_HashLookup(ctx->Shared->FrameBuffers, id); 156 157 return fb; 158} 159 160 161struct gl_framebuffer * 162_mesa_lookup_framebuffer_dsa(struct gl_context *ctx, GLuint id, 163 const char* func) 164{ 165 struct gl_framebuffer *fb; 166 167 if (id == 0) 168 return NULL; 169 170 fb = _mesa_lookup_framebuffer(ctx, id); 171 172 /* Name exists but buffer is not initialized */ 173 if (fb == &DummyFramebuffer) { 174 fb = ctx->Driver.NewFramebuffer(ctx, id); 175 _mesa_HashInsert(ctx->Shared->FrameBuffers, id, fb, true); 176 } 177 /* Name doesn't exist */ 178 else if (!fb) { 179 fb = ctx->Driver.NewFramebuffer(ctx, id); 180 if (!fb) { 181 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 182 return NULL; 183 } 184 _mesa_HashInsert(ctx->Shared->FrameBuffers, id, fb, false); 185 } 186 return fb; 187} 188 189 190/** 191 * A convenience function for direct state access that throws 192 * GL_INVALID_OPERATION if the framebuffer doesn't exist. 193 */ 194struct gl_framebuffer * 195_mesa_lookup_framebuffer_err(struct gl_context *ctx, GLuint id, 196 const char *func) 197{ 198 struct gl_framebuffer *fb; 199 200 fb = _mesa_lookup_framebuffer(ctx, id); 201 if (!fb || fb == &DummyFramebuffer) { 202 _mesa_error(ctx, GL_INVALID_OPERATION, 203 "%s(non-existent framebuffer %u)", func, id); 204 return NULL; 205 } 206 207 return fb; 208} 209 210 211/** 212 * Mark the given framebuffer as invalid. This will force the 213 * test for framebuffer completeness to be done before the framebuffer 214 * is used. 215 */ 216static void 217invalidate_framebuffer(struct gl_framebuffer *fb) 218{ 219 fb->_Status = 0; /* "indeterminate" */ 220} 221 222 223/** 224 * Return the gl_framebuffer object which corresponds to the given 225 * framebuffer target, such as GL_DRAW_FRAMEBUFFER. 226 * Check support for GL_EXT_framebuffer_blit to determine if certain 227 * targets are legal. 228 * \return gl_framebuffer pointer or NULL if target is illegal 229 */ 230static struct gl_framebuffer * 231get_framebuffer_target(struct gl_context *ctx, GLenum target) 232{ 233 bool have_fb_blit = _mesa_is_gles3(ctx) || _mesa_is_desktop_gl(ctx); 234 switch (target) { 235 case GL_DRAW_FRAMEBUFFER: 236 return have_fb_blit ? ctx->DrawBuffer : NULL; 237 case GL_READ_FRAMEBUFFER: 238 return have_fb_blit ? ctx->ReadBuffer : NULL; 239 case GL_FRAMEBUFFER_EXT: 240 return ctx->DrawBuffer; 241 default: 242 return NULL; 243 } 244} 245 246 247/** 248 * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding 249 * gl_renderbuffer_attachment object. 250 * This function is only used for user-created FB objects, not the 251 * default / window-system FB object. 252 * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to 253 * the depth buffer attachment point. 254 * Returns if the attachment is a GL_COLOR_ATTACHMENTm_EXT on 255 * is_color_attachment, because several callers would return different errors 256 * if they don't find the attachment. 257 */ 258static struct gl_renderbuffer_attachment * 259get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, 260 GLenum attachment, bool *is_color_attachment) 261{ 262 GLuint i; 263 264 assert(_mesa_is_user_fbo(fb)); 265 266 if (is_color_attachment) 267 *is_color_attachment = false; 268 269 switch (attachment) { 270 case GL_COLOR_ATTACHMENT0_EXT: 271 case GL_COLOR_ATTACHMENT1_EXT: 272 case GL_COLOR_ATTACHMENT2_EXT: 273 case GL_COLOR_ATTACHMENT3_EXT: 274 case GL_COLOR_ATTACHMENT4_EXT: 275 case GL_COLOR_ATTACHMENT5_EXT: 276 case GL_COLOR_ATTACHMENT6_EXT: 277 case GL_COLOR_ATTACHMENT7_EXT: 278 case GL_COLOR_ATTACHMENT8_EXT: 279 case GL_COLOR_ATTACHMENT9_EXT: 280 case GL_COLOR_ATTACHMENT10_EXT: 281 case GL_COLOR_ATTACHMENT11_EXT: 282 case GL_COLOR_ATTACHMENT12_EXT: 283 case GL_COLOR_ATTACHMENT13_EXT: 284 case GL_COLOR_ATTACHMENT14_EXT: 285 case GL_COLOR_ATTACHMENT15_EXT: 286 if (is_color_attachment) 287 *is_color_attachment = true; 288 /* Only OpenGL ES 1.x forbids color attachments other than 289 * GL_COLOR_ATTACHMENT0. For all other APIs the limit set by the 290 * hardware is used. 291 */ 292 i = attachment - GL_COLOR_ATTACHMENT0_EXT; 293 if (i >= ctx->Const.MaxColorAttachments 294 || (i > 0 && ctx->API == API_OPENGLES)) { 295 return NULL; 296 } 297 assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment)); 298 return &fb->Attachment[BUFFER_COLOR0 + i]; 299 case GL_DEPTH_STENCIL_ATTACHMENT: 300 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 301 return NULL; 302 FALLTHROUGH; 303 case GL_DEPTH_ATTACHMENT_EXT: 304 return &fb->Attachment[BUFFER_DEPTH]; 305 case GL_STENCIL_ATTACHMENT_EXT: 306 return &fb->Attachment[BUFFER_STENCIL]; 307 default: 308 return NULL; 309 } 310} 311 312 313/** 314 * As above, but only used for getting attachments of the default / 315 * window-system framebuffer (not user-created framebuffer objects). 316 */ 317static struct gl_renderbuffer_attachment * 318get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, 319 GLenum attachment) 320{ 321 assert(_mesa_is_winsys_fbo(fb)); 322 323 attachment = _mesa_back_to_front_if_single_buffered(fb, attachment); 324 325 if (_mesa_is_gles3(ctx)) { 326 switch (attachment) { 327 case GL_BACK: 328 /* Since there is no stereo rendering in ES 3.0, only return the 329 * LEFT bits. 330 */ 331 return &fb->Attachment[BUFFER_BACK_LEFT]; 332 case GL_FRONT: 333 /* We might get this if back_to_front triggers above */ 334 return &fb->Attachment[BUFFER_FRONT_LEFT]; 335 case GL_DEPTH: 336 return &fb->Attachment[BUFFER_DEPTH]; 337 case GL_STENCIL: 338 return &fb->Attachment[BUFFER_STENCIL]; 339 default: 340 unreachable("invalid attachment"); 341 } 342 } 343 344 switch (attachment) { 345 case GL_FRONT: 346 case GL_FRONT_LEFT: 347 /* Front buffers can be allocated on the first use, but 348 * glGetFramebufferAttachmentParameteriv must work even if that 349 * allocation hasn't happened yet. In such case, use the back buffer, 350 * which should be the same. 351 */ 352 if (fb->Attachment[BUFFER_FRONT_LEFT].Type == GL_NONE) 353 return &fb->Attachment[BUFFER_BACK_LEFT]; 354 else 355 return &fb->Attachment[BUFFER_FRONT_LEFT]; 356 case GL_FRONT_RIGHT: 357 /* Same as above. */ 358 if (fb->Attachment[BUFFER_FRONT_RIGHT].Type == GL_NONE) 359 return &fb->Attachment[BUFFER_BACK_RIGHT]; 360 else 361 return &fb->Attachment[BUFFER_FRONT_RIGHT]; 362 case GL_BACK_LEFT: 363 return &fb->Attachment[BUFFER_BACK_LEFT]; 364 case GL_BACK_RIGHT: 365 return &fb->Attachment[BUFFER_BACK_RIGHT]; 366 case GL_BACK: 367 /* The ARB_ES3_1_compatibility spec says: 368 * 369 * "Since this command can only query a single framebuffer 370 * attachment, BACK is equivalent to BACK_LEFT." 371 */ 372 if (ctx->Extensions.ARB_ES3_1_compatibility) 373 return &fb->Attachment[BUFFER_BACK_LEFT]; 374 return NULL; 375 case GL_AUX0: 376 return NULL; 377 378 /* Page 336 (page 352 of the PDF) of the OpenGL 3.0 spec says: 379 * 380 * "If the default framebuffer is bound to target, then attachment must 381 * be one of FRONT LEFT, FRONT RIGHT, BACK LEFT, BACK RIGHT, or AUXi, 382 * identifying a color buffer; DEPTH, identifying the depth buffer; or 383 * STENCIL, identifying the stencil buffer." 384 * 385 * Revision #34 of the ARB_framebuffer_object spec has essentially the same 386 * language. However, revision #33 of the ARB_framebuffer_object spec 387 * says: 388 * 389 * "If the default framebuffer is bound to <target>, then <attachment> 390 * must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, AUXi, 391 * DEPTH_BUFFER, or STENCIL_BUFFER, identifying a color buffer, the 392 * depth buffer, or the stencil buffer, and <pname> may be 393 * FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE or 394 * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME." 395 * 396 * The enum values for DEPTH_BUFFER and STENCIL_BUFFER have been removed 397 * from glext.h, so shipping apps should not use those values. 398 * 399 * Note that neither EXT_framebuffer_object nor OES_framebuffer_object 400 * support queries of the window system FBO. 401 */ 402 case GL_DEPTH: 403 return &fb->Attachment[BUFFER_DEPTH]; 404 case GL_STENCIL: 405 return &fb->Attachment[BUFFER_STENCIL]; 406 default: 407 return NULL; 408 } 409} 410 411 412 413/** 414 * Remove any texture or renderbuffer attached to the given attachment 415 * point. Update reference counts, etc. 416 */ 417static void 418remove_attachment(struct gl_context *ctx, 419 struct gl_renderbuffer_attachment *att) 420{ 421 struct gl_renderbuffer *rb = att->Renderbuffer; 422 423 /* tell driver that we're done rendering to this texture. */ 424 if (rb && rb->NeedsFinishRenderTexture) 425 ctx->Driver.FinishRenderTexture(ctx, rb); 426 427 if (att->Type == GL_TEXTURE) { 428 assert(att->Texture); 429 _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ 430 assert(!att->Texture); 431 } 432 if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) { 433 assert(!att->Texture); 434 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */ 435 assert(!att->Renderbuffer); 436 } 437 att->Type = GL_NONE; 438 att->Complete = GL_TRUE; 439} 440 441/** 442 * Verify a couple error conditions that will lead to an incomplete FBO and 443 * may cause problems for the driver's RenderTexture path. 444 */ 445static bool 446driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att) 447{ 448 const struct gl_texture_image *const texImage = 449 att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 450 451 if (!texImage || 452 texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) 453 return false; 454 455 if ((texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY 456 && att->Zoffset >= texImage->Height) 457 || (texImage->TexObject->Target != GL_TEXTURE_1D_ARRAY 458 && att->Zoffset >= texImage->Depth)) 459 return false; 460 461 return true; 462} 463 464/** 465 * Create a renderbuffer which will be set up by the driver to wrap the 466 * texture image slice. 467 * 468 * By using a gl_renderbuffer (like user-allocated renderbuffers), drivers get 469 * to share most of their framebuffer rendering code between winsys, 470 * renderbuffer, and texture attachments. 471 * 472 * The allocated renderbuffer uses a non-zero Name so that drivers can check 473 * it for determining vertical orientation, but we use ~0 to make it fairly 474 * unambiguous with actual user (non-texture) renderbuffers. 475 */ 476void 477_mesa_update_texture_renderbuffer(struct gl_context *ctx, 478 struct gl_framebuffer *fb, 479 struct gl_renderbuffer_attachment *att) 480{ 481 struct gl_texture_image *texImage; 482 struct gl_renderbuffer *rb; 483 484 texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 485 486 rb = att->Renderbuffer; 487 if (!rb) { 488 rb = ctx->Driver.NewRenderbuffer(ctx, ~0); 489 if (!rb) { 490 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()"); 491 return; 492 } 493 att->Renderbuffer = rb; 494 495 /* This can't get called on a texture renderbuffer, so set it to NULL 496 * for clarity compared to user renderbuffers. 497 */ 498 rb->AllocStorage = NULL; 499 500 rb->NeedsFinishRenderTexture = ctx->Driver.FinishRenderTexture != NULL; 501 } 502 503 if (!texImage) 504 return; 505 506 rb->_BaseFormat = texImage->_BaseFormat; 507 rb->Format = texImage->TexFormat; 508 rb->InternalFormat = texImage->InternalFormat; 509 rb->Width = texImage->Width2; 510 rb->Height = texImage->Height2; 511 rb->Depth = texImage->Depth2; 512 rb->NumSamples = texImage->NumSamples; 513 rb->NumStorageSamples = texImage->NumSamples; 514 rb->TexImage = texImage; 515 516 if (driver_RenderTexture_is_safe(att)) 517 ctx->Driver.RenderTexture(ctx, fb, att); 518} 519 520/** 521 * Bind a texture object to an attachment point. 522 * The previous binding, if any, will be removed first. 523 */ 524static void 525set_texture_attachment(struct gl_context *ctx, 526 struct gl_framebuffer *fb, 527 struct gl_renderbuffer_attachment *att, 528 struct gl_texture_object *texObj, 529 GLenum texTarget, GLuint level, GLsizei samples, 530 GLuint layer, GLboolean layered) 531{ 532 struct gl_renderbuffer *rb = att->Renderbuffer; 533 534 if (rb && rb->NeedsFinishRenderTexture) 535 ctx->Driver.FinishRenderTexture(ctx, rb); 536 537 if (att->Texture == texObj) { 538 /* re-attaching same texture */ 539 assert(att->Type == GL_TEXTURE); 540 } 541 else { 542 /* new attachment */ 543 remove_attachment(ctx, att); 544 att->Type = GL_TEXTURE; 545 assert(!att->Texture); 546 _mesa_reference_texobj(&att->Texture, texObj); 547 } 548 invalidate_framebuffer(fb); 549 550 /* always update these fields */ 551 att->TextureLevel = level; 552 att->NumSamples = samples; 553 att->CubeMapFace = _mesa_tex_target_to_face(texTarget); 554 att->Zoffset = layer; 555 att->Layered = layered; 556 att->Complete = GL_FALSE; 557 558 _mesa_update_texture_renderbuffer(ctx, fb, att); 559} 560 561 562/** 563 * Bind a renderbuffer to an attachment point. 564 * The previous binding, if any, will be removed first. 565 */ 566static void 567set_renderbuffer_attachment(struct gl_context *ctx, 568 struct gl_renderbuffer_attachment *att, 569 struct gl_renderbuffer *rb) 570{ 571 /* XXX check if re-doing same attachment, exit early */ 572 remove_attachment(ctx, att); 573 att->Type = GL_RENDERBUFFER_EXT; 574 att->Texture = NULL; /* just to be safe */ 575 att->Layered = GL_FALSE; 576 att->Complete = GL_FALSE; 577 _mesa_reference_renderbuffer(&att->Renderbuffer, rb); 578} 579 580 581/** 582 * Fallback for ctx->Driver.FramebufferRenderbuffer() 583 * Attach a renderbuffer object to a framebuffer object. 584 */ 585void 586_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx, 587 struct gl_framebuffer *fb, 588 GLenum attachment, 589 struct gl_renderbuffer *rb) 590{ 591 struct gl_renderbuffer_attachment *att; 592 593 simple_mtx_lock(&fb->Mutex); 594 595 att = get_attachment(ctx, fb, attachment, NULL); 596 assert(att); 597 if (rb) { 598 set_renderbuffer_attachment(ctx, att, rb); 599 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 600 /* do stencil attachment here (depth already done above) */ 601 att = get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT, NULL); 602 assert(att); 603 set_renderbuffer_attachment(ctx, att, rb); 604 } 605 rb->AttachedAnytime = GL_TRUE; 606 } 607 else { 608 remove_attachment(ctx, att); 609 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 610 /* detach stencil (depth was detached above) */ 611 att = get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT, NULL); 612 assert(att); 613 remove_attachment(ctx, att); 614 } 615 } 616 617 invalidate_framebuffer(fb); 618 619 simple_mtx_unlock(&fb->Mutex); 620} 621 622 623/** 624 * Fallback for ctx->Driver.ValidateFramebuffer() 625 * Check if the renderbuffer's formats are supported by the software 626 * renderer. 627 * Drivers should probably override this. 628 */ 629void 630_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 631{ 632 gl_buffer_index buf; 633 for (buf = 0; buf < BUFFER_COUNT; buf++) { 634 const struct gl_renderbuffer *rb = fb->Attachment[buf].Renderbuffer; 635 if (rb) { 636 switch (rb->_BaseFormat) { 637 case GL_ALPHA: 638 case GL_LUMINANCE_ALPHA: 639 case GL_LUMINANCE: 640 case GL_INTENSITY: 641 case GL_RED: 642 case GL_RG: 643 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 644 return; 645 646 default: 647 switch (rb->Format) { 648 /* XXX This list is likely incomplete. */ 649 case MESA_FORMAT_R9G9B9E5_FLOAT: 650 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 651 return; 652 default:; 653 /* render buffer format is supported by software rendering */ 654 } 655 } 656 } 657 } 658} 659 660 661/** 662 * Return true if the framebuffer has a combined depth/stencil 663 * renderbuffer attached. 664 */ 665GLboolean 666_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb) 667{ 668 const struct gl_renderbuffer_attachment *depth = 669 &fb->Attachment[BUFFER_DEPTH]; 670 const struct gl_renderbuffer_attachment *stencil = 671 &fb->Attachment[BUFFER_STENCIL]; 672 673 if (depth->Type == stencil->Type) { 674 if (depth->Type == GL_RENDERBUFFER_EXT && 675 depth->Renderbuffer == stencil->Renderbuffer) 676 return GL_TRUE; 677 678 if (depth->Type == GL_TEXTURE && 679 depth->Texture == stencil->Texture) 680 return GL_TRUE; 681 } 682 683 return GL_FALSE; 684} 685 686 687/** 688 * For debug only. 689 */ 690static void 691att_incomplete(const char *msg) 692{ 693 if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) { 694 _mesa_debug(NULL, "attachment incomplete: %s\n", msg); 695 } 696} 697 698 699/** 700 * For debug only. 701 */ 702static void 703fbo_incomplete(struct gl_context *ctx, const char *msg, int index) 704{ 705 static GLuint msg_id; 706 707 _mesa_gl_debugf(ctx, &msg_id, 708 MESA_DEBUG_SOURCE_API, 709 MESA_DEBUG_TYPE_OTHER, 710 MESA_DEBUG_SEVERITY_MEDIUM, 711 "FBO incomplete: %s [%d]\n", msg, index); 712 713 if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) { 714 _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index); 715 } 716 717 _mesa_update_valid_to_render_state(ctx); 718} 719 720 721/** 722 * Is the given base format a legal format for a color renderbuffer? 723 */ 724GLboolean 725_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat) 726{ 727 switch (baseFormat) { 728 case GL_RGB: 729 case GL_RGBA: 730 return GL_TRUE; 731 case GL_LUMINANCE: 732 case GL_LUMINANCE_ALPHA: 733 case GL_INTENSITY: 734 case GL_ALPHA: 735 return ctx->API == API_OPENGL_COMPAT && 736 ctx->Extensions.ARB_framebuffer_object; 737 case GL_RED: 738 case GL_RG: 739 return ctx->Extensions.ARB_texture_rg; 740 default: 741 return GL_FALSE; 742 } 743} 744 745static GLboolean 746is_float_format(GLenum internalFormat) 747{ 748 switch (internalFormat) { 749 case GL_R16F: 750 case GL_RG16F: 751 case GL_RGB16F: 752 case GL_RGBA16F: 753 case GL_R32F: 754 case GL_RG32F: 755 case GL_RGB32F: 756 case GL_RGBA32F: 757 return true; 758 default: 759 return false; 760 } 761} 762 763/** 764 * Is the given base format a legal format for a color renderbuffer? 765 */ 766static GLboolean 767is_format_color_renderable(const struct gl_context *ctx, mesa_format format, 768 GLenum internalFormat) 769{ 770 const GLenum baseFormat = 771 _mesa_get_format_base_format(format); 772 GLboolean valid; 773 774 valid = _mesa_is_legal_color_format(ctx, baseFormat); 775 if (!valid || _mesa_is_desktop_gl(ctx)) { 776 return valid; 777 } 778 779 /* Reject additional cases for GLES */ 780 switch (internalFormat) { 781 case GL_R8_SNORM: 782 case GL_RG8_SNORM: 783 case GL_RGBA8_SNORM: 784 return _mesa_has_EXT_render_snorm(ctx); 785 case GL_R16_SNORM: 786 case GL_RG16_SNORM: 787 case GL_RGBA16_SNORM: 788 return _mesa_has_EXT_texture_norm16(ctx) && 789 _mesa_has_EXT_render_snorm(ctx); 790 case GL_R: 791 case GL_RG: 792 return _mesa_has_EXT_texture_rg(ctx); 793 case GL_R16F: 794 case GL_RG16F: 795 return _mesa_is_gles3(ctx) || 796 (_mesa_has_EXT_color_buffer_half_float(ctx) && 797 _mesa_has_EXT_texture_rg(ctx)); 798 case GL_RGBA16F: 799 return _mesa_is_gles3(ctx) || 800 _mesa_has_EXT_color_buffer_half_float(ctx); 801 case GL_RGBA32F: 802 return _mesa_has_EXT_color_buffer_float(ctx); 803 case GL_RGB16F: 804 return _mesa_has_EXT_color_buffer_half_float(ctx); 805 case GL_RGB10_A2: 806 return _mesa_is_gles3(ctx); 807 case GL_RGB32F: 808 case GL_RGB32I: 809 case GL_RGB32UI: 810 case GL_RGB16I: 811 case GL_RGB16UI: 812 case GL_RGB8_SNORM: 813 case GL_RGB8I: 814 case GL_RGB8UI: 815 case GL_SRGB8: 816 case GL_RGB10: 817 case GL_RGB9_E5: 818 case GL_SR8_EXT: 819 case GL_SRG8_EXT: 820 return GL_FALSE; 821 default: 822 break; 823 } 824 825 if (internalFormat != GL_RGB10_A2 && 826 (format == MESA_FORMAT_B10G10R10A2_UNORM || 827 format == MESA_FORMAT_B10G10R10X2_UNORM || 828 format == MESA_FORMAT_R10G10B10A2_UNORM || 829 format == MESA_FORMAT_R10G10B10X2_UNORM)) { 830 return GL_FALSE; 831 } 832 833 return GL_TRUE; 834} 835 836/** 837 * Check that implements various limitations of floating point 838 * rendering extensions on OpenGL ES. 839 * 840 * Check passes if texture format is not floating point or 841 * is floating point and is color renderable. 842 * 843 * Check fails if texture format is floating point and cannot 844 * be rendered to with current context and set of supported 845 * extensions. 846 */ 847static GLboolean 848gles_check_float_renderable(const struct gl_context *ctx, 849 struct gl_renderbuffer_attachment *att) 850{ 851 /* Only check floating point texture cases. */ 852 if (!att->Texture || !is_float_format(att->Renderbuffer->InternalFormat)) 853 return true; 854 855 /* GL_RGBA with unsized GL_FLOAT type, no extension can make this 856 * color renderable. 857 */ 858 if (att->Texture->_IsFloat && att->Renderbuffer->_BaseFormat == GL_RGBA) 859 return false; 860 861 /* Unsized GL_HALF_FLOAT supported only with EXT_color_buffer_half_float. */ 862 if (att->Texture->_IsHalfFloat && !_mesa_has_EXT_color_buffer_half_float(ctx)) 863 return false; 864 865 const struct gl_texture_object *texObj = att->Texture; 866 const struct gl_texture_image *texImage = 867 texObj->Image[att->CubeMapFace][att->TextureLevel]; 868 869 return is_format_color_renderable(ctx, texImage->TexFormat, 870 att->Renderbuffer->InternalFormat); 871} 872 873/** 874 * Is the given base format a legal format for a depth/stencil renderbuffer? 875 */ 876static GLboolean 877is_legal_depth_format(const struct gl_context *ctx, GLenum baseFormat) 878{ 879 switch (baseFormat) { 880 case GL_DEPTH_COMPONENT: 881 case GL_DEPTH_STENCIL_EXT: 882 return GL_TRUE; 883 default: 884 return GL_FALSE; 885 } 886} 887 888 889/** 890 * Test if an attachment point is complete and update its Complete field. 891 * \param format if GL_COLOR, this is a color attachment point, 892 * if GL_DEPTH, this is a depth component attachment point, 893 * if GL_STENCIL, this is a stencil component attachment point. 894 */ 895static void 896test_attachment_completeness(const struct gl_context *ctx, GLenum format, 897 struct gl_renderbuffer_attachment *att) 898{ 899 assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL); 900 901 /* assume complete */ 902 att->Complete = GL_TRUE; 903 904 /* Look for reasons why the attachment might be incomplete */ 905 if (att->Type == GL_TEXTURE) { 906 const struct gl_texture_object *texObj = att->Texture; 907 const struct gl_texture_image *texImage; 908 GLenum baseFormat; 909 910 if (!texObj) { 911 att_incomplete("no texobj"); 912 att->Complete = GL_FALSE; 913 return; 914 } 915 916 texImage = texObj->Image[att->CubeMapFace][att->TextureLevel]; 917 if (!texImage) { 918 att_incomplete("no teximage"); 919 att->Complete = GL_FALSE; 920 return; 921 } 922 923 /* Mutable non base level texture as framebuffer attachment 924 * must be mipmap complete. 925 */ 926 if (texImage->Level > texObj->Attrib.BaseLevel && 927 !texObj->_MipmapComplete) { 928 /* Test if texture has become mipmap complete meanwhile. */ 929 _mesa_test_texobj_completeness(ctx, att->Texture); 930 if (!texObj->_MipmapComplete) { 931 att_incomplete("texture attachment not mipmap complete"); 932 att->Complete = GL_FALSE; 933 return; 934 } 935 } 936 937 if (texImage->Width < 1 || texImage->Height < 1) { 938 att_incomplete("teximage width/height=0"); 939 att->Complete = GL_FALSE; 940 return; 941 } 942 943 switch (texObj->Target) { 944 case GL_TEXTURE_3D: 945 if (att->Zoffset >= texImage->Depth) { 946 att_incomplete("bad z offset"); 947 att->Complete = GL_FALSE; 948 return; 949 } 950 break; 951 case GL_TEXTURE_1D_ARRAY: 952 if (att->Zoffset >= texImage->Height) { 953 att_incomplete("bad 1D-array layer"); 954 att->Complete = GL_FALSE; 955 return; 956 } 957 break; 958 case GL_TEXTURE_2D_ARRAY: 959 if (att->Zoffset >= texImage->Depth) { 960 att_incomplete("bad 2D-array layer"); 961 att->Complete = GL_FALSE; 962 return; 963 } 964 break; 965 case GL_TEXTURE_CUBE_MAP_ARRAY: 966 if (att->Zoffset >= texImage->Depth) { 967 att_incomplete("bad cube-array layer"); 968 att->Complete = GL_FALSE; 969 return; 970 } 971 break; 972 } 973 974 baseFormat = texImage->_BaseFormat; 975 976 if (format == GL_COLOR) { 977 if (!_mesa_is_legal_color_format(ctx, baseFormat)) { 978 att_incomplete("bad format"); 979 att->Complete = GL_FALSE; 980 return; 981 } 982 if (_mesa_is_format_compressed(texImage->TexFormat)) { 983 att_incomplete("compressed internalformat"); 984 att->Complete = GL_FALSE; 985 return; 986 } 987 988 /* OES_texture_float allows creation and use of floating point 989 * textures with GL_FLOAT, GL_HALF_FLOAT but it does not allow 990 * these textures to be used as a render target, this is done via 991 * GL_EXT_color_buffer(_half)_float with set of new sized types. 992 */ 993 if (_mesa_is_gles(ctx) && !gles_check_float_renderable(ctx, att)) { 994 att_incomplete("bad internal format"); 995 att->Complete = GL_FALSE; 996 return; 997 } 998 } 999 else if (format == GL_DEPTH) { 1000 if (baseFormat == GL_DEPTH_COMPONENT) { 1001 /* OK */ 1002 } 1003 else if (ctx->Extensions.ARB_depth_texture && 1004 baseFormat == GL_DEPTH_STENCIL) { 1005 /* OK */ 1006 } 1007 else { 1008 att->Complete = GL_FALSE; 1009 att_incomplete("bad depth format"); 1010 return; 1011 } 1012 } 1013 else { 1014 assert(format == GL_STENCIL); 1015 if (ctx->Extensions.ARB_depth_texture && 1016 baseFormat == GL_DEPTH_STENCIL) { 1017 /* OK */ 1018 } else if (ctx->Extensions.ARB_texture_stencil8 && 1019 baseFormat == GL_STENCIL_INDEX) { 1020 /* OK */ 1021 } else { 1022 /* no such thing as stencil-only textures */ 1023 att_incomplete("illegal stencil texture"); 1024 att->Complete = GL_FALSE; 1025 return; 1026 } 1027 } 1028 } 1029 else if (att->Type == GL_RENDERBUFFER_EXT) { 1030 const GLenum baseFormat = att->Renderbuffer->_BaseFormat; 1031 1032 assert(att->Renderbuffer); 1033 if (!att->Renderbuffer->InternalFormat || 1034 att->Renderbuffer->Width < 1 || 1035 att->Renderbuffer->Height < 1) { 1036 att_incomplete("0x0 renderbuffer"); 1037 att->Complete = GL_FALSE; 1038 return; 1039 } 1040 if (format == GL_COLOR) { 1041 if (!_mesa_is_legal_color_format(ctx, baseFormat)) { 1042 att_incomplete("bad renderbuffer color format"); 1043 att->Complete = GL_FALSE; 1044 return; 1045 } 1046 } 1047 else if (format == GL_DEPTH) { 1048 if (baseFormat == GL_DEPTH_COMPONENT) { 1049 /* OK */ 1050 } 1051 else if (baseFormat == GL_DEPTH_STENCIL) { 1052 /* OK */ 1053 } 1054 else { 1055 att_incomplete("bad renderbuffer depth format"); 1056 att->Complete = GL_FALSE; 1057 return; 1058 } 1059 } 1060 else { 1061 assert(format == GL_STENCIL); 1062 if (baseFormat == GL_STENCIL_INDEX || 1063 baseFormat == GL_DEPTH_STENCIL) { 1064 /* OK */ 1065 } 1066 else { 1067 att->Complete = GL_FALSE; 1068 att_incomplete("bad renderbuffer stencil format"); 1069 return; 1070 } 1071 } 1072 } 1073 else { 1074 assert(att->Type == GL_NONE); 1075 /* complete */ 1076 return; 1077 } 1078} 1079 1080 1081/** 1082 * Test if the given framebuffer object is complete and update its 1083 * Status field with the results. 1084 * Calls the ctx->Driver.ValidateFramebuffer() function to allow the 1085 * driver to make hardware-specific validation/completeness checks. 1086 * Also update the framebuffer's Width and Height fields if the 1087 * framebuffer is complete. 1088 */ 1089void 1090_mesa_test_framebuffer_completeness(struct gl_context *ctx, 1091 struct gl_framebuffer *fb) 1092{ 1093 GLuint numImages; 1094 GLenum intFormat = GL_NONE; /* color buffers' internal format */ 1095 GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0; 1096 GLint numColorSamples = -1; 1097 GLint numColorStorageSamples = -1; 1098 GLint numDepthSamples = -1; 1099 GLint fixedSampleLocations = -1; 1100 GLint i; 1101 GLuint j; 1102 /* Covers max_layer_count, is_layered, and layer_tex_target */ 1103 bool layer_info_valid = false; 1104 GLuint max_layer_count = 0, att_layer_count; 1105 bool is_layered = false; 1106 GLenum layer_tex_target = 0; 1107 bool has_depth_attachment = false; 1108 bool has_stencil_attachment = false; 1109 1110 assert(_mesa_is_user_fbo(fb)); 1111 1112 /* we're changing framebuffer fields here */ 1113 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 1114 1115 numImages = 0; 1116 fb->Width = 0; 1117 fb->Height = 0; 1118 fb->_AllColorBuffersFixedPoint = GL_TRUE; 1119 fb->_HasSNormOrFloatColorBuffer = GL_FALSE; 1120 fb->_HasAttachments = true; 1121 fb->_IntegerBuffers = 0; 1122 fb->_RGBBuffers = 0; 1123 fb->_FP32Buffers = 0; 1124 1125 /* Start at -2 to more easily loop over all attachment points. 1126 * -2: depth buffer 1127 * -1: stencil buffer 1128 * >=0: color buffer 1129 */ 1130 for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) { 1131 struct gl_renderbuffer_attachment *att; 1132 GLenum f; 1133 GLenum baseFormat; 1134 mesa_format attFormat; 1135 GLenum att_tex_target = GL_NONE; 1136 1137 /* 1138 * XXX for ARB_fbo, only check color buffers that are named by 1139 * GL_READ_BUFFER and GL_DRAW_BUFFERi. 1140 */ 1141 1142 /* check for attachment completeness 1143 */ 1144 if (i == -2) { 1145 att = &fb->Attachment[BUFFER_DEPTH]; 1146 test_attachment_completeness(ctx, GL_DEPTH, att); 1147 if (!att->Complete) { 1148 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; 1149 fbo_incomplete(ctx, "depth attachment incomplete", -1); 1150 return; 1151 } else if (att->Type != GL_NONE) { 1152 has_depth_attachment = true; 1153 } 1154 } 1155 else if (i == -1) { 1156 att = &fb->Attachment[BUFFER_STENCIL]; 1157 test_attachment_completeness(ctx, GL_STENCIL, att); 1158 if (!att->Complete) { 1159 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; 1160 fbo_incomplete(ctx, "stencil attachment incomplete", -1); 1161 return; 1162 } else if (att->Type != GL_NONE) { 1163 has_stencil_attachment = true; 1164 } 1165 } 1166 else { 1167 att = &fb->Attachment[BUFFER_COLOR0 + i]; 1168 test_attachment_completeness(ctx, GL_COLOR, att); 1169 if (!att->Complete) { 1170 /* With EXT_color_buffer_half_float, check if attachment was incomplete 1171 * due to invalid format. This is special case for the extension where 1172 * CTS tests expect unsupported framebuffer status instead of incomplete. 1173 */ 1174 if ((_mesa_is_gles(ctx) && _mesa_has_EXT_color_buffer_half_float(ctx)) && 1175 !gles_check_float_renderable(ctx, att)) { 1176 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 1177 return; 1178 } 1179 1180 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; 1181 fbo_incomplete(ctx, "color attachment incomplete", i); 1182 return; 1183 } 1184 } 1185 1186 /* get width, height, format of the renderbuffer/texture 1187 */ 1188 unsigned attNumSamples, attNumStorageSamples; 1189 1190 if (att->Type == GL_TEXTURE) { 1191 const struct gl_texture_image *texImg = att->Renderbuffer->TexImage; 1192 att_tex_target = att->Texture->Target; 1193 minWidth = MIN2(minWidth, texImg->Width); 1194 maxWidth = MAX2(maxWidth, texImg->Width); 1195 minHeight = MIN2(minHeight, texImg->Height); 1196 maxHeight = MAX2(maxHeight, texImg->Height); 1197 f = texImg->_BaseFormat; 1198 baseFormat = f; 1199 attFormat = texImg->TexFormat; 1200 numImages++; 1201 1202 if (!is_format_color_renderable(ctx, attFormat, 1203 texImg->InternalFormat) && 1204 !is_legal_depth_format(ctx, f) && 1205 f != GL_STENCIL_INDEX) { 1206 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1207 fbo_incomplete(ctx, "texture attachment incomplete", -1); 1208 return; 1209 } 1210 1211 if (fixedSampleLocations < 0) 1212 fixedSampleLocations = texImg->FixedSampleLocations; 1213 else if (fixedSampleLocations != texImg->FixedSampleLocations) { 1214 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1215 fbo_incomplete(ctx, "inconsistent fixed sample locations", -1); 1216 return; 1217 } 1218 1219 if (att->NumSamples > 0) 1220 attNumSamples = att->NumSamples; 1221 else 1222 attNumSamples = texImg->NumSamples; 1223 attNumStorageSamples = attNumSamples; 1224 } 1225 else if (att->Type == GL_RENDERBUFFER_EXT) { 1226 minWidth = MIN2(minWidth, att->Renderbuffer->Width); 1227 maxWidth = MAX2(maxWidth, att->Renderbuffer->Width); 1228 minHeight = MIN2(minHeight, att->Renderbuffer->Height); 1229 maxHeight = MAX2(maxHeight, att->Renderbuffer->Height); 1230 f = att->Renderbuffer->InternalFormat; 1231 baseFormat = att->Renderbuffer->_BaseFormat; 1232 attFormat = att->Renderbuffer->Format; 1233 numImages++; 1234 1235 /* RENDERBUFFER has fixedSampleLocations implicitly true */ 1236 if (fixedSampleLocations < 0) 1237 fixedSampleLocations = GL_TRUE; 1238 else if (fixedSampleLocations != GL_TRUE) { 1239 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1240 fbo_incomplete(ctx, "inconsistent fixed sample locations", -1); 1241 return; 1242 } 1243 1244 attNumSamples = att->Renderbuffer->NumSamples; 1245 attNumStorageSamples = att->Renderbuffer->NumStorageSamples; 1246 } 1247 else { 1248 assert(att->Type == GL_NONE); 1249 continue; 1250 } 1251 1252 if (i >= 0) { 1253 /* Color buffers. */ 1254 if (numColorSamples < 0) { 1255 assert(numColorStorageSamples < 0); 1256 numColorSamples = attNumSamples; 1257 numColorStorageSamples = attNumStorageSamples; 1258 } else if (numColorSamples != attNumSamples || 1259 numColorStorageSamples != attNumStorageSamples) { 1260 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1261 fbo_incomplete(ctx, "inconsistent sample counts", -1); 1262 return; 1263 } 1264 } else { 1265 /* Depth/stencil buffers. */ 1266 if (numDepthSamples < 0) { 1267 numDepthSamples = attNumSamples; 1268 } else if (numDepthSamples != attNumSamples) { 1269 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1270 fbo_incomplete(ctx, "inconsistent sample counts", -1); 1271 return; 1272 } 1273 } 1274 1275 /* Update flags describing color buffer datatypes */ 1276 if (i >= 0) { 1277 GLenum type = _mesa_get_format_datatype(attFormat); 1278 1279 /* check if integer color */ 1280 if (_mesa_is_format_integer_color(attFormat)) 1281 fb->_IntegerBuffers |= (1 << i); 1282 1283 if (baseFormat == GL_RGB) 1284 fb->_RGBBuffers |= (1 << i); 1285 1286 if (type == GL_FLOAT && _mesa_get_format_max_bits(attFormat) > 16) 1287 fb->_FP32Buffers |= (1 << i); 1288 1289 fb->_AllColorBuffersFixedPoint = 1290 fb->_AllColorBuffersFixedPoint && 1291 (type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED); 1292 1293 fb->_HasSNormOrFloatColorBuffer = 1294 fb->_HasSNormOrFloatColorBuffer || 1295 type == GL_SIGNED_NORMALIZED || type == GL_FLOAT; 1296 } 1297 1298 /* Error-check width, height, format */ 1299 if (numImages == 1) { 1300 /* save format */ 1301 if (i >= 0) { 1302 intFormat = f; 1303 } 1304 } 1305 else { 1306 if (!_mesa_has_ARB_framebuffer_object(ctx) && 1307 !_mesa_is_gles3(ctx)) { 1308 /* check that width, height, format are same */ 1309 if (minWidth != maxWidth || minHeight != maxHeight) { 1310 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; 1311 fbo_incomplete(ctx, "width or height mismatch", -1); 1312 return; 1313 } 1314 /* check that all color buffers are the same format */ 1315 if (ctx->API != API_OPENGLES2 && intFormat != GL_NONE && f != intFormat) { 1316 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; 1317 fbo_incomplete(ctx, "format mismatch", -1); 1318 return; 1319 } 1320 } 1321 } 1322 1323 /* Check that the format is valid. (MESA_FORMAT_NONE means unsupported) 1324 */ 1325 if (att->Type == GL_RENDERBUFFER && 1326 att->Renderbuffer->Format == MESA_FORMAT_NONE) { 1327 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 1328 fbo_incomplete(ctx, "unsupported renderbuffer format", i); 1329 return; 1330 } 1331 1332 /* Check that layered rendering is consistent. */ 1333 if (att->Layered) { 1334 if (att_tex_target == GL_TEXTURE_CUBE_MAP) { 1335 /* Each layer's format and size must match to the base layer. */ 1336 if (!_mesa_cube_complete(att->Texture)) { 1337 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1338 fbo_incomplete(ctx, "attachment not cube complete", i); 1339 return; 1340 } 1341 att_layer_count = 6; 1342 } else if (att_tex_target == GL_TEXTURE_1D_ARRAY) 1343 att_layer_count = att->Renderbuffer->Height; 1344 else 1345 att_layer_count = att->Renderbuffer->Depth; 1346 1347 /* From OpenGL ES 3.2 spec, chapter 9.4. FRAMEBUFFER COMPLETENESS: 1348 * 1349 * "If any framebuffer attachment is layered, all populated 1350 * attachments must be layered. Additionally, all populated color 1351 * attachments must be from textures of the same target 1352 * (three-dimensional, one- or two-dimensional array, cube map, or 1353 * cube map array textures)." 1354 * 1355 * Same text can be found from OpenGL 4.6 spec. 1356 * 1357 * Setup the checked layer target with first color attachment here 1358 * so that mismatch check below will not trigger between depth, 1359 * stencil, only between color attachments. 1360 */ 1361 if (i == 0) 1362 layer_tex_target = att_tex_target; 1363 1364 } else { 1365 att_layer_count = 0; 1366 } 1367 if (!layer_info_valid) { 1368 is_layered = att->Layered; 1369 max_layer_count = att_layer_count; 1370 layer_info_valid = true; 1371 } else if (max_layer_count > 0 && layer_tex_target && 1372 layer_tex_target != att_tex_target) { 1373 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; 1374 fbo_incomplete(ctx, "layered framebuffer has mismatched targets", i); 1375 return; 1376 } else if (is_layered != att->Layered) { 1377 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; 1378 fbo_incomplete(ctx, 1379 "framebuffer attachment layer mode is inconsistent", 1380 i); 1381 return; 1382 } else if (att_layer_count > max_layer_count) { 1383 max_layer_count = att_layer_count; 1384 } 1385 1386 /* 1387 * The extension GL_ARB_framebuffer_no_attachments places additional 1388 * requirement on each attachment. Those additional requirements are 1389 * tighter that those of previous versions of GL. In interest of better 1390 * compatibility, we will not enforce these restrictions. For the record 1391 * those additional restrictions are quoted below: 1392 * 1393 * "The width and height of image are greater than zero and less than or 1394 * equal to the values of the implementation-dependent limits 1395 * MAX_FRAMEBUFFER_WIDTH and MAX_FRAMEBUFFER_HEIGHT, respectively." 1396 * 1397 * "If <image> is a three-dimensional texture or a one- or two-dimensional 1398 * array texture and the attachment is layered, the depth or layer count 1399 * of the texture is less than or equal to the implementation-dependent 1400 * limit MAX_FRAMEBUFFER_LAYERS." 1401 * 1402 * "If image has multiple samples, its sample count is less than or equal 1403 * to the value of the implementation-dependent limit 1404 * MAX_FRAMEBUFFER_SAMPLES." 1405 * 1406 * The same requirements are also in place for GL 4.5, 1407 * Section 9.4.1 "Framebuffer Attachment Completeness", pg 310-311 1408 */ 1409 } 1410 1411 if (ctx->Extensions.AMD_framebuffer_multisample_advanced) { 1412 /* See if non-matching sample counts are supported. */ 1413 if (numColorSamples >= 0 && numDepthSamples >= 0) { 1414 bool found = false; 1415 1416 assert(numColorStorageSamples != -1); 1417 1418 numColorSamples = MAX2(numColorSamples, 1); 1419 numColorStorageSamples = MAX2(numColorStorageSamples, 1); 1420 numDepthSamples = MAX2(numDepthSamples, 1); 1421 1422 if (numColorSamples == 1 && numColorStorageSamples == 1 && 1423 numDepthSamples == 1) { 1424 found = true; 1425 } else { 1426 for (i = 0; i < ctx->Const.NumSupportedMultisampleModes; i++) { 1427 GLint *counts = 1428 &ctx->Const.SupportedMultisampleModes[i].NumColorSamples; 1429 1430 if (counts[0] == numColorSamples && 1431 counts[1] == numColorStorageSamples && 1432 counts[2] == numDepthSamples) { 1433 found = true; 1434 break; 1435 } 1436 } 1437 } 1438 1439 if (!found) { 1440 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1441 fbo_incomplete(ctx, "unsupported sample counts", -1); 1442 return; 1443 } 1444 } 1445 } else { 1446 /* If the extension is unsupported, all sample counts must be equal. */ 1447 if (numColorSamples >= 0 && 1448 (numColorSamples != numColorStorageSamples || 1449 (numDepthSamples >= 0 && numColorSamples != numDepthSamples))) { 1450 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 1451 fbo_incomplete(ctx, "inconsistent sample counts", -1); 1452 return; 1453 } 1454 } 1455 1456 fb->MaxNumLayers = max_layer_count; 1457 1458 if (numImages == 0) { 1459 fb->_HasAttachments = false; 1460 1461 if (!ctx->Extensions.ARB_framebuffer_no_attachments) { 1462 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; 1463 fbo_incomplete(ctx, "no attachments", -1); 1464 return; 1465 } 1466 1467 if (fb->DefaultGeometry.Width == 0 || fb->DefaultGeometry.Height == 0) { 1468 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; 1469 fbo_incomplete(ctx, "no attachments and default width or height is 0", -1); 1470 return; 1471 } 1472 } 1473 1474 if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { 1475 /* Check that all DrawBuffers are present */ 1476 for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { 1477 if (fb->ColorDrawBuffer[j] != GL_NONE) { 1478 const struct gl_renderbuffer_attachment *att 1479 = get_attachment(ctx, fb, fb->ColorDrawBuffer[j], NULL); 1480 assert(att); 1481 if (att->Type == GL_NONE) { 1482 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; 1483 fbo_incomplete(ctx, "missing drawbuffer", j); 1484 return; 1485 } 1486 } 1487 } 1488 1489 /* Check that the ReadBuffer is present */ 1490 if (fb->ColorReadBuffer != GL_NONE) { 1491 const struct gl_renderbuffer_attachment *att 1492 = get_attachment(ctx, fb, fb->ColorReadBuffer, NULL); 1493 assert(att); 1494 if (att->Type == GL_NONE) { 1495 fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; 1496 fbo_incomplete(ctx, "missing readbuffer", -1); 1497 return; 1498 } 1499 } 1500 } 1501 1502 /* The OpenGL ES3 spec, in chapter 9.4. FRAMEBUFFER COMPLETENESS, says: 1503 * 1504 * "Depth and stencil attachments, if present, are the same image." 1505 * 1506 * This restriction is not present in the OpenGL ES2 spec. 1507 */ 1508 if (_mesa_is_gles3(ctx) && 1509 has_stencil_attachment && has_depth_attachment && 1510 !_mesa_has_depthstencil_combined(fb)) { 1511 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 1512 fbo_incomplete(ctx, "Depth and stencil attachments must be the same image", -1); 1513 return; 1514 } 1515 1516 /* Provisionally set status = COMPLETE ... */ 1517 fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; 1518 1519 /* ... but the driver may say the FB is incomplete. 1520 * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED 1521 * if anything. 1522 */ 1523 if (ctx->Driver.ValidateFramebuffer) { 1524 ctx->Driver.ValidateFramebuffer(ctx, fb); 1525 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1526 fbo_incomplete(ctx, "driver marked FBO as incomplete", -1); 1527 return; 1528 } 1529 } 1530 1531 /* 1532 * Note that if ARB_framebuffer_object is supported and the attached 1533 * renderbuffers/textures are different sizes, the framebuffer 1534 * width/height will be set to the smallest width/height. 1535 */ 1536 if (numImages != 0) { 1537 fb->Width = minWidth; 1538 fb->Height = minHeight; 1539 } 1540 1541 /* finally, update the visual info for the framebuffer */ 1542 _mesa_update_framebuffer_visual(ctx, fb); 1543} 1544 1545 1546GLboolean GLAPIENTRY 1547_mesa_IsRenderbuffer(GLuint renderbuffer) 1548{ 1549 struct gl_renderbuffer *rb; 1550 1551 GET_CURRENT_CONTEXT(ctx); 1552 1553 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 1554 1555 rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 1556 return rb != NULL && rb != &DummyRenderbuffer; 1557} 1558 1559 1560static struct gl_renderbuffer * 1561allocate_renderbuffer_locked(struct gl_context *ctx, GLuint renderbuffer, 1562 bool isGenName, 1563 const char *func) 1564{ 1565 struct gl_renderbuffer *newRb; 1566 1567 /* create new renderbuffer object */ 1568 newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer); 1569 if (!newRb) { 1570 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 1571 return NULL; 1572 } 1573 assert(newRb->AllocStorage); 1574 _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, renderbuffer, 1575 newRb, isGenName); 1576 1577 return newRb; 1578} 1579 1580 1581static void 1582bind_renderbuffer(GLenum target, GLuint renderbuffer) 1583{ 1584 struct gl_renderbuffer *newRb; 1585 GET_CURRENT_CONTEXT(ctx); 1586 1587 if (target != GL_RENDERBUFFER_EXT) { 1588 _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)"); 1589 return; 1590 } 1591 1592 /* No need to flush here since the render buffer binding has no 1593 * effect on rendering state. 1594 */ 1595 1596 if (renderbuffer) { 1597 bool isGenName = false; 1598 newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 1599 if (newRb == &DummyRenderbuffer) { 1600 /* ID was reserved, but no real renderbuffer object made yet */ 1601 newRb = NULL; 1602 isGenName = true; 1603 } 1604 else if (!newRb && ctx->API == API_OPENGL_CORE) { 1605 /* All RB IDs must be Gen'd */ 1606 _mesa_error(ctx, GL_INVALID_OPERATION, 1607 "glBindRenderbuffer(non-gen name)"); 1608 return; 1609 } 1610 1611 if (!newRb) { 1612 _mesa_HashLockMutex(ctx->Shared->RenderBuffers); 1613 newRb = allocate_renderbuffer_locked(ctx, renderbuffer, 1614 isGenName, "glBindRenderbufferEXT"); 1615 _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); 1616 } 1617 } 1618 else { 1619 newRb = NULL; 1620 } 1621 1622 assert(newRb != &DummyRenderbuffer); 1623 1624 _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb); 1625} 1626 1627void GLAPIENTRY 1628_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer) 1629{ 1630 /* OpenGL ES glBindRenderbuffer and glBindRenderbufferOES use this same 1631 * entry point, but they allow the use of user-generated names. 1632 */ 1633 bind_renderbuffer(target, renderbuffer); 1634} 1635 1636void GLAPIENTRY 1637_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) 1638{ 1639 bind_renderbuffer(target, renderbuffer); 1640} 1641 1642/** 1643 * ARB_framebuffer_no_attachment and ARB_sample_locations - Application passes 1644 * requested param's here. NOTE: NumSamples requested need not be _NumSamples 1645 * which is what the hw supports. 1646 */ 1647static void 1648framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb, 1649 GLenum pname, GLint param, const char *func) 1650{ 1651 bool cannot_be_winsys_fbo = false; 1652 1653 switch (pname) { 1654 case GL_FRAMEBUFFER_DEFAULT_WIDTH: 1655 case GL_FRAMEBUFFER_DEFAULT_HEIGHT: 1656 case GL_FRAMEBUFFER_DEFAULT_LAYERS: 1657 case GL_FRAMEBUFFER_DEFAULT_SAMPLES: 1658 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: 1659 if (!ctx->Extensions.ARB_framebuffer_no_attachments) 1660 goto invalid_pname_enum; 1661 cannot_be_winsys_fbo = true; 1662 break; 1663 case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: 1664 case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: 1665 if (!ctx->Extensions.ARB_sample_locations) 1666 goto invalid_pname_enum; 1667 break; 1668 case GL_FRAMEBUFFER_FLIP_Y_MESA: 1669 if (!ctx->Extensions.MESA_framebuffer_flip_y) 1670 goto invalid_pname_enum; 1671 cannot_be_winsys_fbo = true; 1672 break; 1673 default: 1674 goto invalid_pname_enum; 1675 } 1676 1677 if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) { 1678 _mesa_error(ctx, GL_INVALID_OPERATION, 1679 "%s(invalid pname=0x%x for default framebuffer)", func, pname); 1680 return; 1681 } 1682 1683 switch (pname) { 1684 case GL_FRAMEBUFFER_DEFAULT_WIDTH: 1685 if (param < 0 || param > ctx->Const.MaxFramebufferWidth) 1686 _mesa_error(ctx, GL_INVALID_VALUE, "%s", func); 1687 else 1688 fb->DefaultGeometry.Width = param; 1689 break; 1690 case GL_FRAMEBUFFER_DEFAULT_HEIGHT: 1691 if (param < 0 || param > ctx->Const.MaxFramebufferHeight) 1692 _mesa_error(ctx, GL_INVALID_VALUE, "%s", func); 1693 else 1694 fb->DefaultGeometry.Height = param; 1695 break; 1696 case GL_FRAMEBUFFER_DEFAULT_LAYERS: 1697 /* 1698 * According to the OpenGL ES 3.1 specification section 9.2.1, the 1699 * GL_FRAMEBUFFER_DEFAULT_LAYERS parameter name is not supported. 1700 */ 1701 if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader) { 1702 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1703 break; 1704 } 1705 if (param < 0 || param > ctx->Const.MaxFramebufferLayers) 1706 _mesa_error(ctx, GL_INVALID_VALUE, "%s", func); 1707 else 1708 fb->DefaultGeometry.Layers = param; 1709 break; 1710 case GL_FRAMEBUFFER_DEFAULT_SAMPLES: 1711 if (param < 0 || param > ctx->Const.MaxFramebufferSamples) 1712 _mesa_error(ctx, GL_INVALID_VALUE, "%s", func); 1713 else 1714 fb->DefaultGeometry.NumSamples = param; 1715 break; 1716 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: 1717 fb->DefaultGeometry.FixedSampleLocations = param; 1718 break; 1719 case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: 1720 fb->ProgrammableSampleLocations = !!param; 1721 break; 1722 case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: 1723 fb->SampleLocationPixelGrid = !!param; 1724 break; 1725 case GL_FRAMEBUFFER_FLIP_Y_MESA: 1726 fb->FlipY = param; 1727 break; 1728 } 1729 1730 switch (pname) { 1731 case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: 1732 case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: 1733 if (fb == ctx->DrawBuffer) 1734 ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; 1735 break; 1736 default: 1737 invalidate_framebuffer(fb); 1738 ctx->NewState |= _NEW_BUFFERS; 1739 break; 1740 } 1741 1742 return; 1743 1744invalid_pname_enum: 1745 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1746} 1747 1748static bool 1749validate_framebuffer_parameter_extensions(GLenum pname, const char *func) 1750{ 1751 GET_CURRENT_CONTEXT(ctx); 1752 1753 if (!ctx->Extensions.ARB_framebuffer_no_attachments && 1754 !ctx->Extensions.ARB_sample_locations && 1755 !ctx->Extensions.MESA_framebuffer_flip_y) { 1756 _mesa_error(ctx, GL_INVALID_OPERATION, 1757 "%s not supported " 1758 "(none of ARB_framebuffer_no_attachments," 1759 " ARB_sample_locations, or" 1760 " MESA_framebuffer_flip_y extensions are available)", 1761 func); 1762 return false; 1763 } 1764 1765 /* 1766 * If only the MESA_framebuffer_flip_y extension is enabled 1767 * pname can only be GL_FRAMEBUFFER_FLIP_Y_MESA 1768 */ 1769 if (ctx->Extensions.MESA_framebuffer_flip_y && 1770 pname != GL_FRAMEBUFFER_FLIP_Y_MESA && 1771 !(ctx->Extensions.ARB_framebuffer_no_attachments || 1772 ctx->Extensions.ARB_sample_locations)) { 1773 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1774 return false; 1775 } 1776 1777 return true; 1778} 1779 1780void GLAPIENTRY 1781_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param) 1782{ 1783 GET_CURRENT_CONTEXT(ctx); 1784 struct gl_framebuffer *fb; 1785 1786 if (!validate_framebuffer_parameter_extensions(pname, 1787 "glFramebufferParameteri")) { 1788 return; 1789 } 1790 1791 fb = get_framebuffer_target(ctx, target); 1792 if (!fb) { 1793 _mesa_error(ctx, GL_INVALID_ENUM, 1794 "glFramebufferParameteri(target=0x%x)", target); 1795 return; 1796 } 1797 1798 framebuffer_parameteri(ctx, fb, pname, param, "glFramebufferParameteri"); 1799} 1800 1801void GLAPIENTRY 1802_mesa_FramebufferParameteriMESA(GLenum target, GLenum pname, GLint param) 1803{ 1804 _mesa_FramebufferParameteri(target, pname, param); 1805} 1806 1807static bool 1808validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx, 1809 struct gl_framebuffer *fb, 1810 GLuint pname, const char *func) 1811{ 1812 bool cannot_be_winsys_fbo = true; 1813 1814 switch (pname) { 1815 case GL_FRAMEBUFFER_DEFAULT_LAYERS: 1816 /* 1817 * According to the OpenGL ES 3.1 specification section 9.2.3, the 1818 * GL_FRAMEBUFFER_LAYERS parameter name is not supported. 1819 */ 1820 if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader) { 1821 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1822 return false; 1823 } 1824 break; 1825 case GL_FRAMEBUFFER_DEFAULT_WIDTH: 1826 case GL_FRAMEBUFFER_DEFAULT_HEIGHT: 1827 case GL_FRAMEBUFFER_DEFAULT_SAMPLES: 1828 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: 1829 break; 1830 case GL_DOUBLEBUFFER: 1831 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1832 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1833 case GL_SAMPLES: 1834 case GL_SAMPLE_BUFFERS: 1835 case GL_STEREO: 1836 /* From OpenGL 4.5 spec, section 9.2.3 "Framebuffer Object Queries: 1837 * 1838 * "An INVALID_OPERATION error is generated by GetFramebufferParameteriv 1839 * if the default framebuffer is bound to target and pname is not one 1840 * of the accepted values from table 23.73, other than 1841 * SAMPLE_POSITION." 1842 * 1843 * For OpenGL ES, using default framebuffer raises INVALID_OPERATION 1844 * for any pname. 1845 */ 1846 cannot_be_winsys_fbo = !_mesa_is_desktop_gl(ctx); 1847 break; 1848 case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: 1849 case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: 1850 if (!ctx->Extensions.ARB_sample_locations) 1851 goto invalid_pname_enum; 1852 cannot_be_winsys_fbo = false; 1853 break; 1854 case GL_FRAMEBUFFER_FLIP_Y_MESA: 1855 if (!ctx->Extensions.MESA_framebuffer_flip_y) { 1856 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1857 return false; 1858 } 1859 break; 1860 default: 1861 goto invalid_pname_enum; 1862 } 1863 1864 if (cannot_be_winsys_fbo && _mesa_is_winsys_fbo(fb)) { 1865 _mesa_error(ctx, GL_INVALID_OPERATION, 1866 "%s(invalid pname=0x%x for default framebuffer)", func, pname); 1867 return false; 1868 } 1869 1870 return true; 1871 1872invalid_pname_enum: 1873 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 1874 return false; 1875} 1876 1877static void 1878get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb, 1879 GLenum pname, GLint *params, const char *func) 1880{ 1881 if (!validate_get_framebuffer_parameteriv_pname(ctx, fb, pname, func)) 1882 return; 1883 1884 switch (pname) { 1885 case GL_FRAMEBUFFER_DEFAULT_WIDTH: 1886 *params = fb->DefaultGeometry.Width; 1887 break; 1888 case GL_FRAMEBUFFER_DEFAULT_HEIGHT: 1889 *params = fb->DefaultGeometry.Height; 1890 break; 1891 case GL_FRAMEBUFFER_DEFAULT_LAYERS: 1892 *params = fb->DefaultGeometry.Layers; 1893 break; 1894 case GL_FRAMEBUFFER_DEFAULT_SAMPLES: 1895 *params = fb->DefaultGeometry.NumSamples; 1896 break; 1897 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: 1898 *params = fb->DefaultGeometry.FixedSampleLocations; 1899 break; 1900 case GL_DOUBLEBUFFER: 1901 *params = fb->Visual.doubleBufferMode; 1902 break; 1903 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1904 *params = _mesa_get_color_read_format(ctx, fb, func); 1905 break; 1906 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1907 *params = _mesa_get_color_read_type(ctx, fb, func); 1908 break; 1909 case GL_SAMPLES: 1910 *params = _mesa_geometric_samples(fb); 1911 break; 1912 case GL_SAMPLE_BUFFERS: 1913 *params = _mesa_geometric_samples(fb) > 0; 1914 break; 1915 case GL_STEREO: 1916 *params = fb->Visual.stereoMode; 1917 break; 1918 case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: 1919 *params = fb->ProgrammableSampleLocations; 1920 break; 1921 case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: 1922 *params = fb->SampleLocationPixelGrid; 1923 break; 1924 case GL_FRAMEBUFFER_FLIP_Y_MESA: 1925 *params = fb->FlipY; 1926 break; 1927 } 1928} 1929 1930void GLAPIENTRY 1931_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) 1932{ 1933 GET_CURRENT_CONTEXT(ctx); 1934 struct gl_framebuffer *fb; 1935 1936 if (!validate_framebuffer_parameter_extensions(pname, 1937 "glGetFramebufferParameteriv")) { 1938 return; 1939 } 1940 1941 fb = get_framebuffer_target(ctx, target); 1942 if (!fb) { 1943 _mesa_error(ctx, GL_INVALID_ENUM, 1944 "glGetFramebufferParameteriv(target=0x%x)", target); 1945 return; 1946 } 1947 1948 get_framebuffer_parameteriv(ctx, fb, pname, params, 1949 "glGetFramebufferParameteriv"); 1950} 1951 1952void GLAPIENTRY 1953_mesa_GetFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params) 1954{ 1955 _mesa_GetFramebufferParameteriv(target, pname, params); 1956} 1957 1958/** 1959 * Remove the specified renderbuffer or texture from any attachment point in 1960 * the framebuffer. 1961 * 1962 * \returns 1963 * \c true if the renderbuffer was detached from an attachment point. \c 1964 * false otherwise. 1965 */ 1966bool 1967_mesa_detach_renderbuffer(struct gl_context *ctx, 1968 struct gl_framebuffer *fb, 1969 const void *att) 1970{ 1971 unsigned i; 1972 bool progress = false; 1973 1974 for (i = 0; i < BUFFER_COUNT; i++) { 1975 if (fb->Attachment[i].Texture == att 1976 || fb->Attachment[i].Renderbuffer == att) { 1977 remove_attachment(ctx, &fb->Attachment[i]); 1978 progress = true; 1979 } 1980 } 1981 1982 /* Section 4.4.4 (Framebuffer Completeness), subsection "Whole Framebuffer 1983 * Completeness," of the OpenGL 3.1 spec says: 1984 * 1985 * "Performing any of the following actions may change whether the 1986 * framebuffer is considered complete or incomplete: 1987 * 1988 * ... 1989 * 1990 * - Deleting, with DeleteTextures or DeleteRenderbuffers, an object 1991 * containing an image that is attached to a framebuffer object 1992 * that is bound to the framebuffer." 1993 */ 1994 if (progress) 1995 invalidate_framebuffer(fb); 1996 1997 return progress; 1998} 1999 2000 2001void GLAPIENTRY 2002_mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) 2003{ 2004 GLint i; 2005 GET_CURRENT_CONTEXT(ctx); 2006 2007 if (n < 0) { 2008 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteRenderbuffers(n < 0)"); 2009 return; 2010 } 2011 2012 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 2013 2014 for (i = 0; i < n; i++) { 2015 if (renderbuffers[i] > 0) { 2016 struct gl_renderbuffer *rb; 2017 rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]); 2018 if (rb) { 2019 /* check if deleting currently bound renderbuffer object */ 2020 if (rb == ctx->CurrentRenderbuffer) { 2021 /* bind default */ 2022 assert(rb->RefCount >= 2); 2023 _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, 0); 2024 } 2025 2026 /* Section 4.4.2 (Attaching Images to Framebuffer Objects), 2027 * subsection "Attaching Renderbuffer Images to a Framebuffer," 2028 * of the OpenGL 3.1 spec says: 2029 * 2030 * "If a renderbuffer object is deleted while its image is 2031 * attached to one or more attachment points in the currently 2032 * bound framebuffer, then it is as if FramebufferRenderbuffer 2033 * had been called, with a renderbuffer of 0, for each 2034 * attachment point to which this image was attached in the 2035 * currently bound framebuffer. In other words, this 2036 * renderbuffer image is first detached from all attachment 2037 * points in the currently bound framebuffer. Note that the 2038 * renderbuffer image is specifically not detached from any 2039 * non-bound framebuffers. Detaching the image from any 2040 * non-bound framebuffers is the responsibility of the 2041 * application. 2042 */ 2043 if (_mesa_is_user_fbo(ctx->DrawBuffer)) { 2044 _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, rb); 2045 } 2046 if (_mesa_is_user_fbo(ctx->ReadBuffer) 2047 && ctx->ReadBuffer != ctx->DrawBuffer) { 2048 _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb); 2049 } 2050 2051 /* Remove from hash table immediately, to free the ID. 2052 * But the object will not be freed until it's no longer 2053 * referenced anywhere else. 2054 */ 2055 _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); 2056 2057 if (rb != &DummyRenderbuffer) { 2058 /* no longer referenced by hash table */ 2059 _mesa_reference_renderbuffer(&rb, NULL); 2060 } 2061 } 2062 } 2063 } 2064} 2065 2066static void 2067create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers, 2068 bool dsa) 2069{ 2070 const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers"; 2071 GLint i; 2072 2073 if (!renderbuffers) 2074 return; 2075 2076 _mesa_HashLockMutex(ctx->Shared->RenderBuffers); 2077 2078 _mesa_HashFindFreeKeys(ctx->Shared->RenderBuffers, renderbuffers, n); 2079 2080 for (i = 0; i < n; i++) { 2081 if (dsa) { 2082 allocate_renderbuffer_locked(ctx, renderbuffers[i], true, func); 2083 } else { 2084 /* insert a dummy renderbuffer into the hash table */ 2085 _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, renderbuffers[i], 2086 &DummyRenderbuffer, true); 2087 } 2088 } 2089 2090 _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); 2091} 2092 2093 2094static void 2095create_render_buffers_err(struct gl_context *ctx, GLsizei n, 2096 GLuint *renderbuffers, bool dsa) 2097{ 2098 const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers"; 2099 2100 if (n < 0) { 2101 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", func); 2102 return; 2103 } 2104 2105 create_render_buffers(ctx, n, renderbuffers, dsa); 2106} 2107 2108 2109void GLAPIENTRY 2110_mesa_GenRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers) 2111{ 2112 GET_CURRENT_CONTEXT(ctx); 2113 create_render_buffers(ctx, n, renderbuffers, false); 2114} 2115 2116 2117void GLAPIENTRY 2118_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers) 2119{ 2120 GET_CURRENT_CONTEXT(ctx); 2121 create_render_buffers_err(ctx, n, renderbuffers, false); 2122} 2123 2124 2125void GLAPIENTRY 2126_mesa_CreateRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers) 2127{ 2128 GET_CURRENT_CONTEXT(ctx); 2129 create_render_buffers(ctx, n, renderbuffers, true); 2130} 2131 2132 2133void GLAPIENTRY 2134_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers) 2135{ 2136 GET_CURRENT_CONTEXT(ctx); 2137 create_render_buffers_err(ctx, n, renderbuffers, true); 2138} 2139 2140 2141/** 2142 * Given an internal format token for a render buffer, return the 2143 * corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, 2144 * GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL_EXT, GL_ALPHA, GL_LUMINANCE, 2145 * GL_LUMINANCE_ALPHA, GL_INTENSITY, etc). 2146 * 2147 * This is similar to _mesa_base_tex_format() but the set of valid 2148 * internal formats is different. 2149 * 2150 * Note that even if a format is determined to be legal here, validation 2151 * of the FBO may fail if the format is not supported by the driver/GPU. 2152 * 2153 * \param internalFormat as passed to glRenderbufferStorage() 2154 * \return the base internal format, or 0 if internalFormat is illegal 2155 */ 2156GLenum 2157_mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) 2158{ 2159 /* 2160 * Notes: some formats such as alpha, luminance, etc. were added 2161 * with GL_ARB_framebuffer_object. 2162 */ 2163 switch (internalFormat) { 2164 case GL_ALPHA: 2165 case GL_ALPHA4: 2166 case GL_ALPHA8: 2167 case GL_ALPHA12: 2168 case GL_ALPHA16: 2169 return (ctx->API == API_OPENGL_COMPAT && 2170 ctx->Extensions.ARB_framebuffer_object) ? GL_ALPHA : 0; 2171 case GL_LUMINANCE: 2172 case GL_LUMINANCE4: 2173 case GL_LUMINANCE8: 2174 case GL_LUMINANCE12: 2175 case GL_LUMINANCE16: 2176 return (ctx->API == API_OPENGL_COMPAT && 2177 ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE : 0; 2178 case GL_LUMINANCE_ALPHA: 2179 case GL_LUMINANCE4_ALPHA4: 2180 case GL_LUMINANCE6_ALPHA2: 2181 case GL_LUMINANCE8_ALPHA8: 2182 case GL_LUMINANCE12_ALPHA4: 2183 case GL_LUMINANCE12_ALPHA12: 2184 case GL_LUMINANCE16_ALPHA16: 2185 return (ctx->API == API_OPENGL_COMPAT && 2186 ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE_ALPHA : 0; 2187 case GL_INTENSITY: 2188 case GL_INTENSITY4: 2189 case GL_INTENSITY8: 2190 case GL_INTENSITY12: 2191 case GL_INTENSITY16: 2192 return (ctx->API == API_OPENGL_COMPAT && 2193 ctx->Extensions.ARB_framebuffer_object) ? GL_INTENSITY : 0; 2194 case GL_RGB8: 2195 return GL_RGB; 2196 case GL_RGB: 2197 case GL_R3_G3_B2: 2198 case GL_RGB4: 2199 case GL_RGB5: 2200 case GL_RGB10: 2201 case GL_RGB12: 2202 case GL_RGB16: 2203 return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0; 2204 case GL_SRGB8_EXT: 2205 return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0; 2206 case GL_RGBA4: 2207 case GL_RGB5_A1: 2208 case GL_RGBA8: 2209 return GL_RGBA; 2210 case GL_RGBA: 2211 case GL_RGBA2: 2212 case GL_RGBA12: 2213 return _mesa_is_desktop_gl(ctx) ? GL_RGBA : 0; 2214 case GL_RGBA16: 2215 return _mesa_is_desktop_gl(ctx) || _mesa_has_EXT_texture_norm16(ctx) 2216 ? GL_RGBA : 0; 2217 case GL_RGB10_A2: 2218 case GL_SRGB8_ALPHA8_EXT: 2219 return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGBA : 0; 2220 case GL_STENCIL_INDEX: 2221 case GL_STENCIL_INDEX1_EXT: 2222 case GL_STENCIL_INDEX4_EXT: 2223 case GL_STENCIL_INDEX16_EXT: 2224 /* There are extensions for GL_STENCIL_INDEX1 and GL_STENCIL_INDEX4 in 2225 * OpenGL ES, but Mesa does not currently support them. 2226 */ 2227 return _mesa_is_desktop_gl(ctx) ? GL_STENCIL_INDEX : 0; 2228 case GL_STENCIL_INDEX8_EXT: 2229 return GL_STENCIL_INDEX; 2230 case GL_DEPTH_COMPONENT: 2231 case GL_DEPTH_COMPONENT32: 2232 return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_COMPONENT : 0; 2233 case GL_DEPTH_COMPONENT16: 2234 case GL_DEPTH_COMPONENT24: 2235 return GL_DEPTH_COMPONENT; 2236 case GL_DEPTH_STENCIL: 2237 return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_STENCIL : 0; 2238 case GL_DEPTH24_STENCIL8: 2239 return GL_DEPTH_STENCIL; 2240 case GL_DEPTH_COMPONENT32F: 2241 return ctx->Version >= 30 2242 || (ctx->API == API_OPENGL_COMPAT && 2243 ctx->Extensions.ARB_depth_buffer_float) 2244 ? GL_DEPTH_COMPONENT : 0; 2245 case GL_DEPTH32F_STENCIL8: 2246 return ctx->Version >= 30 2247 || (ctx->API == API_OPENGL_COMPAT && 2248 ctx->Extensions.ARB_depth_buffer_float) 2249 ? GL_DEPTH_STENCIL : 0; 2250 case GL_RED: 2251 return _mesa_has_ARB_texture_rg(ctx) ? GL_RED : 0; 2252 case GL_R16: 2253 return _mesa_has_ARB_texture_rg(ctx) || _mesa_has_EXT_texture_norm16(ctx) 2254 ? GL_RED : 0; 2255 case GL_R8: 2256 return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg 2257 ? GL_RED : 0; 2258 case GL_RG: 2259 return _mesa_has_ARB_texture_rg(ctx) ? GL_RG : 0; 2260 case GL_RG16: 2261 return _mesa_has_ARB_texture_rg(ctx) || _mesa_has_EXT_texture_norm16(ctx) 2262 ? GL_RG : 0; 2263 case GL_RG8: 2264 return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg 2265 ? GL_RG : 0; 2266 /* signed normalized texture formats */ 2267 case GL_R8_SNORM: 2268 return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx) 2269 ? GL_RED : 0; 2270 case GL_RED_SNORM: 2271 return _mesa_has_EXT_texture_snorm(ctx) ? GL_RED : 0; 2272 case GL_R16_SNORM: 2273 return _mesa_has_EXT_texture_snorm(ctx) || 2274 (_mesa_has_EXT_render_snorm(ctx) && 2275 _mesa_has_EXT_texture_norm16(ctx)) 2276 ? GL_RED : 0; 2277 case GL_RG8_SNORM: 2278 return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx) 2279 ? GL_RG : 0; 2280 case GL_RG_SNORM: 2281 return _mesa_has_EXT_texture_snorm(ctx) ? GL_RG : 0; 2282 case GL_RG16_SNORM: 2283 return _mesa_has_EXT_texture_snorm(ctx) || 2284 (_mesa_has_EXT_render_snorm(ctx) && 2285 _mesa_has_EXT_texture_norm16(ctx)) 2286 ? GL_RG : 0; 2287 case GL_RGB_SNORM: 2288 case GL_RGB8_SNORM: 2289 case GL_RGB16_SNORM: 2290 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm 2291 ? GL_RGB : 0; 2292 case GL_RGBA8_SNORM: 2293 return _mesa_has_EXT_texture_snorm(ctx) || _mesa_has_EXT_render_snorm(ctx) 2294 ? GL_RGBA : 0; 2295 case GL_RGBA_SNORM: 2296 return _mesa_has_EXT_texture_snorm(ctx) ? GL_RGBA : 0; 2297 case GL_RGBA16_SNORM: 2298 return _mesa_has_EXT_texture_snorm(ctx) || 2299 (_mesa_has_EXT_render_snorm(ctx) && 2300 _mesa_has_EXT_texture_norm16(ctx)) 2301 ? GL_RGBA : 0; 2302 case GL_ALPHA_SNORM: 2303 case GL_ALPHA8_SNORM: 2304 case GL_ALPHA16_SNORM: 2305 return ctx->API == API_OPENGL_COMPAT && 2306 ctx->Extensions.EXT_texture_snorm && 2307 ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; 2308 case GL_LUMINANCE_SNORM: 2309 case GL_LUMINANCE8_SNORM: 2310 case GL_LUMINANCE16_SNORM: 2311 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm 2312 ? GL_LUMINANCE : 0; 2313 case GL_LUMINANCE_ALPHA_SNORM: 2314 case GL_LUMINANCE8_ALPHA8_SNORM: 2315 case GL_LUMINANCE16_ALPHA16_SNORM: 2316 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm 2317 ? GL_LUMINANCE_ALPHA : 0; 2318 case GL_INTENSITY_SNORM: 2319 case GL_INTENSITY8_SNORM: 2320 case GL_INTENSITY16_SNORM: 2321 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm 2322 ? GL_INTENSITY : 0; 2323 2324 case GL_R16F: 2325 return ((_mesa_is_desktop_gl(ctx) && 2326 ctx->Extensions.ARB_texture_rg && 2327 ctx->Extensions.ARB_texture_float) || 2328 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ || 2329 (_mesa_has_EXT_color_buffer_half_float(ctx) && 2330 _mesa_has_EXT_texture_rg(ctx))) 2331 ? GL_RED : 0; 2332 case GL_R32F: 2333 return ((_mesa_is_desktop_gl(ctx) && 2334 ctx->Extensions.ARB_texture_rg && 2335 ctx->Extensions.ARB_texture_float) || 2336 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ) 2337 ? GL_RED : 0; 2338 case GL_RG16F: 2339 return ((_mesa_is_desktop_gl(ctx) && 2340 ctx->Extensions.ARB_texture_rg && 2341 ctx->Extensions.ARB_texture_float) || 2342 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ || 2343 (_mesa_has_EXT_color_buffer_half_float(ctx) && 2344 _mesa_has_EXT_texture_rg(ctx))) 2345 ? GL_RG : 0; 2346 case GL_RG32F: 2347 return ((_mesa_is_desktop_gl(ctx) && 2348 ctx->Extensions.ARB_texture_rg && 2349 ctx->Extensions.ARB_texture_float) || 2350 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ) 2351 ? GL_RG : 0; 2352 case GL_RGB16F: 2353 return (_mesa_has_ARB_texture_float(ctx) || 2354 _mesa_has_EXT_color_buffer_half_float(ctx)) 2355 ? GL_RGB : 0; 2356 case GL_RGB32F: 2357 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float) 2358 ? GL_RGB : 0; 2359 case GL_RGBA16F: 2360 return (_mesa_has_ARB_texture_float(ctx) || 2361 _mesa_is_gles3(ctx) || 2362 _mesa_has_EXT_color_buffer_half_float(ctx)) 2363 ? GL_RGBA : 0; 2364 case GL_RGBA32F: 2365 return ((_mesa_is_desktop_gl(ctx) && 2366 ctx->Extensions.ARB_texture_float) || 2367 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ) 2368 ? GL_RGBA : 0; 2369 case GL_RGB9_E5: 2370 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_shared_exponent) 2371 ? GL_RGB: 0; 2372 case GL_ALPHA16F_ARB: 2373 case GL_ALPHA32F_ARB: 2374 return ctx->API == API_OPENGL_COMPAT && 2375 ctx->Extensions.ARB_texture_float && 2376 ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; 2377 case GL_LUMINANCE16F_ARB: 2378 case GL_LUMINANCE32F_ARB: 2379 return ctx->API == API_OPENGL_COMPAT && 2380 ctx->Extensions.ARB_texture_float && 2381 ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0; 2382 case GL_LUMINANCE_ALPHA16F_ARB: 2383 case GL_LUMINANCE_ALPHA32F_ARB: 2384 return ctx->API == API_OPENGL_COMPAT && 2385 ctx->Extensions.ARB_texture_float && 2386 ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0; 2387 case GL_INTENSITY16F_ARB: 2388 case GL_INTENSITY32F_ARB: 2389 return ctx->API == API_OPENGL_COMPAT && 2390 ctx->Extensions.ARB_texture_float && 2391 ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; 2392 case GL_R11F_G11F_B10F: 2393 return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float) || 2394 _mesa_is_gles3(ctx) /* EXT_color_buffer_float */ ) 2395 ? GL_RGB : 0; 2396 2397 case GL_RGBA8UI_EXT: 2398 case GL_RGBA16UI_EXT: 2399 case GL_RGBA32UI_EXT: 2400 case GL_RGBA8I_EXT: 2401 case GL_RGBA16I_EXT: 2402 case GL_RGBA32I_EXT: 2403 return ctx->Version >= 30 2404 || (_mesa_is_desktop_gl(ctx) && 2405 ctx->Extensions.EXT_texture_integer) ? GL_RGBA : 0; 2406 2407 case GL_RGB8UI_EXT: 2408 case GL_RGB16UI_EXT: 2409 case GL_RGB32UI_EXT: 2410 case GL_RGB8I_EXT: 2411 case GL_RGB16I_EXT: 2412 case GL_RGB32I_EXT: 2413 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_integer 2414 ? GL_RGB : 0; 2415 case GL_R8UI: 2416 case GL_R8I: 2417 case GL_R16UI: 2418 case GL_R16I: 2419 case GL_R32UI: 2420 case GL_R32I: 2421 return ctx->Version >= 30 2422 || (_mesa_is_desktop_gl(ctx) && 2423 ctx->Extensions.ARB_texture_rg && 2424 ctx->Extensions.EXT_texture_integer) ? GL_RED : 0; 2425 2426 case GL_RG8UI: 2427 case GL_RG8I: 2428 case GL_RG16UI: 2429 case GL_RG16I: 2430 case GL_RG32UI: 2431 case GL_RG32I: 2432 return ctx->Version >= 30 2433 || (_mesa_is_desktop_gl(ctx) && 2434 ctx->Extensions.ARB_texture_rg && 2435 ctx->Extensions.EXT_texture_integer) ? GL_RG : 0; 2436 2437 case GL_INTENSITY8I_EXT: 2438 case GL_INTENSITY8UI_EXT: 2439 case GL_INTENSITY16I_EXT: 2440 case GL_INTENSITY16UI_EXT: 2441 case GL_INTENSITY32I_EXT: 2442 case GL_INTENSITY32UI_EXT: 2443 return ctx->API == API_OPENGL_COMPAT && 2444 ctx->Extensions.EXT_texture_integer && 2445 ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; 2446 2447 case GL_LUMINANCE8I_EXT: 2448 case GL_LUMINANCE8UI_EXT: 2449 case GL_LUMINANCE16I_EXT: 2450 case GL_LUMINANCE16UI_EXT: 2451 case GL_LUMINANCE32I_EXT: 2452 case GL_LUMINANCE32UI_EXT: 2453 return ctx->API == API_OPENGL_COMPAT && 2454 ctx->Extensions.EXT_texture_integer && 2455 ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0; 2456 2457 case GL_LUMINANCE_ALPHA8I_EXT: 2458 case GL_LUMINANCE_ALPHA8UI_EXT: 2459 case GL_LUMINANCE_ALPHA16I_EXT: 2460 case GL_LUMINANCE_ALPHA16UI_EXT: 2461 case GL_LUMINANCE_ALPHA32I_EXT: 2462 case GL_LUMINANCE_ALPHA32UI_EXT: 2463 return ctx->API == API_OPENGL_COMPAT && 2464 ctx->Extensions.EXT_texture_integer && 2465 ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0; 2466 2467 case GL_ALPHA8I_EXT: 2468 case GL_ALPHA8UI_EXT: 2469 case GL_ALPHA16I_EXT: 2470 case GL_ALPHA16UI_EXT: 2471 case GL_ALPHA32I_EXT: 2472 case GL_ALPHA32UI_EXT: 2473 return ctx->API == API_OPENGL_COMPAT && 2474 ctx->Extensions.EXT_texture_integer && 2475 ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; 2476 2477 case GL_RGB10_A2UI: 2478 return (_mesa_is_desktop_gl(ctx) && 2479 ctx->Extensions.ARB_texture_rgb10_a2ui) 2480 || _mesa_is_gles3(ctx) ? GL_RGBA : 0; 2481 2482 case GL_RGB565: 2483 return _mesa_is_gles(ctx) || ctx->Extensions.ARB_ES2_compatibility 2484 ? GL_RGB : 0; 2485 default: 2486 return 0; 2487 } 2488} 2489 2490 2491/** 2492 * Invalidate a renderbuffer attachment. Called from _mesa_HashWalk(). 2493 */ 2494static void 2495invalidate_rb(void *data, void *userData) 2496{ 2497 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2498 struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData; 2499 2500 /* If this is a user-created FBO */ 2501 if (_mesa_is_user_fbo(fb)) { 2502 GLuint i; 2503 for (i = 0; i < BUFFER_COUNT; i++) { 2504 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2505 if (att->Type == GL_RENDERBUFFER && 2506 att->Renderbuffer == rb) { 2507 /* Mark fb status as indeterminate to force re-validation */ 2508 fb->_Status = 0; 2509 return; 2510 } 2511 } 2512 } 2513} 2514 2515 2516/** sentinal value, see below */ 2517#define NO_SAMPLES 1000 2518 2519void 2520_mesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 2521 GLenum internalFormat, GLsizei width, 2522 GLsizei height, GLsizei samples, 2523 GLsizei storageSamples) 2524{ 2525 const GLenum baseFormat = _mesa_base_fbo_format(ctx, internalFormat); 2526 2527 assert(baseFormat != 0); 2528 assert(width >= 0 && width <= (GLsizei) ctx->Const.MaxRenderbufferSize); 2529 assert(height >= 0 && height <= (GLsizei) ctx->Const.MaxRenderbufferSize); 2530 assert(samples != NO_SAMPLES); 2531 if (samples != 0) { 2532 assert(samples > 0); 2533 assert(_mesa_check_sample_count(ctx, GL_RENDERBUFFER, 2534 internalFormat, samples, 2535 storageSamples) == GL_NO_ERROR); 2536 } 2537 2538 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 2539 2540 if (rb->InternalFormat == internalFormat && 2541 rb->Width == (GLuint) width && 2542 rb->Height == (GLuint) height && 2543 rb->NumSamples == samples && 2544 rb->NumStorageSamples == storageSamples) { 2545 /* no change in allocation needed */ 2546 return; 2547 } 2548 2549 /* These MUST get set by the AllocStorage func */ 2550 rb->Format = MESA_FORMAT_NONE; 2551 rb->NumSamples = samples; 2552 rb->NumStorageSamples = storageSamples; 2553 2554 /* Now allocate the storage */ 2555 assert(rb->AllocStorage); 2556 if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) { 2557 /* No error - check/set fields now */ 2558 /* If rb->Format == MESA_FORMAT_NONE, the format is unsupported. */ 2559 assert(rb->Width == (GLuint) width); 2560 assert(rb->Height == (GLuint) height); 2561 rb->InternalFormat = internalFormat; 2562 rb->_BaseFormat = baseFormat; 2563 assert(rb->_BaseFormat != 0); 2564 } 2565 else { 2566 /* Probably ran out of memory - clear the fields */ 2567 rb->Width = 0; 2568 rb->Height = 0; 2569 rb->Format = MESA_FORMAT_NONE; 2570 rb->InternalFormat = GL_NONE; 2571 rb->_BaseFormat = GL_NONE; 2572 rb->NumSamples = 0; 2573 rb->NumStorageSamples = 0; 2574 } 2575 2576 /* Invalidate the framebuffers the renderbuffer is attached in. */ 2577 if (rb->AttachedAnytime) { 2578 _mesa_HashWalk(ctx->Shared->FrameBuffers, invalidate_rb, rb); 2579 } 2580} 2581 2582/** 2583 * Helper function used by renderbuffer_storage_direct() and 2584 * renderbuffer_storage_target(). 2585 * samples will be NO_SAMPLES if called by a non-multisample function. 2586 */ 2587static void 2588renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 2589 GLenum internalFormat, GLsizei width, 2590 GLsizei height, GLsizei samples, GLsizei storageSamples, 2591 const char *func) 2592{ 2593 GLenum baseFormat; 2594 GLenum sample_count_error; 2595 2596 baseFormat = _mesa_base_fbo_format(ctx, internalFormat); 2597 if (baseFormat == 0) { 2598 _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat=%s)", 2599 func, _mesa_enum_to_string(internalFormat)); 2600 return; 2601 } 2602 2603 if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) { 2604 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid width %d)", func, 2605 width); 2606 return; 2607 } 2608 2609 if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) { 2610 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid height %d)", func, 2611 height); 2612 return; 2613 } 2614 2615 if (samples == NO_SAMPLES) { 2616 /* NumSamples == 0 indicates non-multisampling */ 2617 samples = 0; 2618 storageSamples = 0; 2619 } 2620 else { 2621 /* check the sample count; 2622 * note: driver may choose to use more samples than what's requested 2623 */ 2624 sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER, 2625 internalFormat, samples, storageSamples); 2626 2627 /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16: 2628 * 2629 * "If a negative number is provided where an argument of type sizei or 2630 * sizeiptr is specified, the error INVALID VALUE is generated." 2631 */ 2632 if (samples < 0 || storageSamples < 0) { 2633 sample_count_error = GL_INVALID_VALUE; 2634 } 2635 2636 if (sample_count_error != GL_NO_ERROR) { 2637 _mesa_error(ctx, sample_count_error, 2638 "%s(samples=%d, storageSamples=%d)", func, samples, 2639 storageSamples); 2640 return; 2641 } 2642 } 2643 2644 _mesa_renderbuffer_storage(ctx, rb, internalFormat, width, height, samples, 2645 storageSamples); 2646} 2647 2648/** 2649 * Helper function used by _mesa_NamedRenderbufferStorage*(). 2650 * samples will be NO_SAMPLES if called by a non-multisample function. 2651 */ 2652static void 2653renderbuffer_storage_named(GLuint renderbuffer, GLenum internalFormat, 2654 GLsizei width, GLsizei height, GLsizei samples, 2655 GLsizei storageSamples, const char *func) 2656{ 2657 GET_CURRENT_CONTEXT(ctx); 2658 2659 if (MESA_VERBOSE & VERBOSE_API) { 2660 if (samples == NO_SAMPLES) 2661 _mesa_debug(ctx, "%s(%u, %s, %d, %d)\n", 2662 func, renderbuffer, 2663 _mesa_enum_to_string(internalFormat), 2664 width, height); 2665 else 2666 _mesa_debug(ctx, "%s(%u, %s, %d, %d, %d)\n", 2667 func, renderbuffer, 2668 _mesa_enum_to_string(internalFormat), 2669 width, height, samples); 2670 } 2671 2672 struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 2673 if (!rb || rb == &DummyRenderbuffer) { 2674 /* ID was reserved, but no real renderbuffer object made yet */ 2675 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid renderbuffer %u)", 2676 func, renderbuffer); 2677 return; 2678 } 2679 2680 renderbuffer_storage(ctx, rb, internalFormat, width, height, samples, 2681 storageSamples, func); 2682} 2683 2684/** 2685 * Helper function used by _mesa_RenderbufferStorage() and 2686 * _mesa_RenderbufferStorageMultisample(). 2687 * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage(). 2688 */ 2689static void 2690renderbuffer_storage_target(GLenum target, GLenum internalFormat, 2691 GLsizei width, GLsizei height, GLsizei samples, 2692 GLsizei storageSamples, const char *func) 2693{ 2694 GET_CURRENT_CONTEXT(ctx); 2695 2696 if (MESA_VERBOSE & VERBOSE_API) { 2697 if (samples == NO_SAMPLES) 2698 _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n", 2699 func, 2700 _mesa_enum_to_string(target), 2701 _mesa_enum_to_string(internalFormat), 2702 width, height); 2703 else 2704 _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n", 2705 func, 2706 _mesa_enum_to_string(target), 2707 _mesa_enum_to_string(internalFormat), 2708 width, height, samples); 2709 } 2710 2711 if (target != GL_RENDERBUFFER_EXT) { 2712 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); 2713 return; 2714 } 2715 2716 if (!ctx->CurrentRenderbuffer) { 2717 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no renderbuffer bound)", 2718 func); 2719 return; 2720 } 2721 2722 renderbuffer_storage(ctx, ctx->CurrentRenderbuffer, internalFormat, width, 2723 height, samples, storageSamples, func); 2724} 2725 2726 2727void GLAPIENTRY 2728_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) 2729{ 2730 struct gl_renderbuffer *rb; 2731 GET_CURRENT_CONTEXT(ctx); 2732 2733 if (!ctx->Extensions.OES_EGL_image) { 2734 _mesa_error(ctx, GL_INVALID_OPERATION, 2735 "glEGLImageTargetRenderbufferStorageOES(unsupported)"); 2736 return; 2737 } 2738 2739 if (target != GL_RENDERBUFFER) { 2740 _mesa_error(ctx, GL_INVALID_ENUM, 2741 "EGLImageTargetRenderbufferStorageOES"); 2742 return; 2743 } 2744 2745 rb = ctx->CurrentRenderbuffer; 2746 if (!rb) { 2747 _mesa_error(ctx, GL_INVALID_OPERATION, 2748 "EGLImageTargetRenderbufferStorageOES"); 2749 return; 2750 } 2751 2752 if (!image || (ctx->Driver.ValidateEGLImage && 2753 !ctx->Driver.ValidateEGLImage(ctx, image))) { 2754 _mesa_error(ctx, GL_INVALID_VALUE, 2755 "EGLImageTargetRenderbufferStorageOES"); 2756 return; 2757 } 2758 2759 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 2760 2761 ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image); 2762} 2763 2764 2765/** 2766 * Helper function for _mesa_GetRenderbufferParameteriv() and 2767 * _mesa_GetFramebufferAttachmentParameteriv() 2768 * We have to be careful to respect the base format. For example, if a 2769 * renderbuffer/texture was created with internalFormat=GL_RGB but the 2770 * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE 2771 * we need to return zero. 2772 */ 2773static GLint 2774get_component_bits(GLenum pname, GLenum baseFormat, mesa_format format) 2775{ 2776 if (_mesa_base_format_has_channel(baseFormat, pname)) 2777 return _mesa_get_format_bits(format, pname); 2778 else 2779 return 0; 2780} 2781 2782 2783 2784void GLAPIENTRY 2785_mesa_RenderbufferStorage(GLenum target, GLenum internalFormat, 2786 GLsizei width, GLsizei height) 2787{ 2788 /* GL_ARB_fbo says calling this function is equivalent to calling 2789 * glRenderbufferStorageMultisample() with samples=0. We pass in 2790 * a token value here just for error reporting purposes. 2791 */ 2792 renderbuffer_storage_target(target, internalFormat, width, height, 2793 NO_SAMPLES, 0, "glRenderbufferStorage"); 2794} 2795 2796 2797void GLAPIENTRY 2798_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, 2799 GLenum internalFormat, 2800 GLsizei width, GLsizei height) 2801{ 2802 renderbuffer_storage_target(target, internalFormat, width, height, 2803 samples, samples, 2804 "glRenderbufferStorageMultisample"); 2805} 2806 2807 2808void GLAPIENTRY 2809_mesa_RenderbufferStorageMultisampleAdvancedAMD( 2810 GLenum target, GLsizei samples, GLsizei storageSamples, 2811 GLenum internalFormat, GLsizei width, GLsizei height) 2812{ 2813 renderbuffer_storage_target(target, internalFormat, width, height, 2814 samples, storageSamples, 2815 "glRenderbufferStorageMultisampleAdvancedAMD"); 2816} 2817 2818 2819/** 2820 * OpenGL ES version of glRenderBufferStorage. 2821 */ 2822void GLAPIENTRY 2823_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, 2824 GLsizei width, GLsizei height) 2825{ 2826 switch (internalFormat) { 2827 case GL_RGB565: 2828 /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */ 2829 /* choose a closest format */ 2830 internalFormat = GL_RGB5; 2831 break; 2832 default: 2833 break; 2834 } 2835 2836 renderbuffer_storage_target(target, internalFormat, width, height, 0, 0, 2837 "glRenderbufferStorageEXT"); 2838} 2839 2840void GLAPIENTRY 2841_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, 2842 GLsizei width, GLsizei height) 2843{ 2844 /* GL_ARB_fbo says calling this function is equivalent to calling 2845 * glRenderbufferStorageMultisample() with samples=0. We pass in 2846 * a token value here just for error reporting purposes. 2847 */ 2848 renderbuffer_storage_named(renderbuffer, internalformat, width, height, 2849 NO_SAMPLES, 0, "glNamedRenderbufferStorage"); 2850} 2851 2852void GLAPIENTRY 2853_mesa_NamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, 2854 GLsizei width, GLsizei height) 2855{ 2856 GET_CURRENT_CONTEXT(ctx); 2857 struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 2858 if (!rb || rb == &DummyRenderbuffer) { 2859 _mesa_HashLockMutex(ctx->Shared->RenderBuffers); 2860 rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, 2861 "glNamedRenderbufferStorageEXT"); 2862 _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); 2863 } 2864 renderbuffer_storage(ctx, rb, internalformat, width, height, NO_SAMPLES, 2865 0, "glNamedRenderbufferStorageEXT"); 2866} 2867 2868 2869void GLAPIENTRY 2870_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, 2871 GLenum internalformat, 2872 GLsizei width, GLsizei height) 2873{ 2874 renderbuffer_storage_named(renderbuffer, internalformat, width, height, 2875 samples, samples, 2876 "glNamedRenderbufferStorageMultisample"); 2877} 2878 2879 2880void GLAPIENTRY 2881_mesa_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, 2882 GLenum internalformat, 2883 GLsizei width, GLsizei height) 2884{ 2885 GET_CURRENT_CONTEXT(ctx); 2886 struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 2887 if (!rb || rb == &DummyRenderbuffer) { 2888 _mesa_HashLockMutex(ctx->Shared->RenderBuffers); 2889 rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, 2890 "glNamedRenderbufferStorageMultisampleEXT"); 2891 _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); 2892 } 2893 renderbuffer_storage(ctx, rb, internalformat, width, height, 2894 samples, samples, 2895 "glNamedRenderbufferStorageMultisample"); 2896} 2897 2898 2899void GLAPIENTRY 2900_mesa_NamedRenderbufferStorageMultisampleAdvancedAMD( 2901 GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, 2902 GLenum internalformat, GLsizei width, GLsizei height) 2903{ 2904 renderbuffer_storage_named(renderbuffer, internalformat, width, height, 2905 samples, storageSamples, 2906 "glNamedRenderbufferStorageMultisampleAdvancedAMD"); 2907} 2908 2909 2910static void 2911get_render_buffer_parameteriv(struct gl_context *ctx, 2912 struct gl_renderbuffer *rb, GLenum pname, 2913 GLint *params, const char *func) 2914{ 2915 /* No need to flush here since we're just quering state which is 2916 * not effected by rendering. 2917 */ 2918 2919 switch (pname) { 2920 case GL_RENDERBUFFER_WIDTH_EXT: 2921 *params = rb->Width; 2922 return; 2923 case GL_RENDERBUFFER_HEIGHT_EXT: 2924 *params = rb->Height; 2925 return; 2926 case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT: 2927 *params = rb->InternalFormat; 2928 return; 2929 case GL_RENDERBUFFER_RED_SIZE_EXT: 2930 case GL_RENDERBUFFER_GREEN_SIZE_EXT: 2931 case GL_RENDERBUFFER_BLUE_SIZE_EXT: 2932 case GL_RENDERBUFFER_ALPHA_SIZE_EXT: 2933 case GL_RENDERBUFFER_DEPTH_SIZE_EXT: 2934 case GL_RENDERBUFFER_STENCIL_SIZE_EXT: 2935 *params = get_component_bits(pname, rb->_BaseFormat, rb->Format); 2936 return; 2937 case GL_RENDERBUFFER_SAMPLES: 2938 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_framebuffer_object) 2939 || _mesa_is_gles3(ctx)) { 2940 *params = rb->NumSamples; 2941 return; 2942 } 2943 break; 2944 case GL_RENDERBUFFER_STORAGE_SAMPLES_AMD: 2945 if (ctx->Extensions.AMD_framebuffer_multisample_advanced) { 2946 *params = rb->NumStorageSamples; 2947 return; 2948 } 2949 break; 2950 } 2951 2952 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname=%s)", func, 2953 _mesa_enum_to_string(pname)); 2954} 2955 2956 2957void GLAPIENTRY 2958_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) 2959{ 2960 GET_CURRENT_CONTEXT(ctx); 2961 2962 if (target != GL_RENDERBUFFER_EXT) { 2963 _mesa_error(ctx, GL_INVALID_ENUM, 2964 "glGetRenderbufferParameterivEXT(target)"); 2965 return; 2966 } 2967 2968 if (!ctx->CurrentRenderbuffer) { 2969 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetRenderbufferParameterivEXT" 2970 "(no renderbuffer bound)"); 2971 return; 2972 } 2973 2974 get_render_buffer_parameteriv(ctx, ctx->CurrentRenderbuffer, pname, 2975 params, "glGetRenderbufferParameteriv"); 2976} 2977 2978 2979void GLAPIENTRY 2980_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, 2981 GLint *params) 2982{ 2983 GET_CURRENT_CONTEXT(ctx); 2984 2985 struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 2986 if (!rb || rb == &DummyRenderbuffer) { 2987 /* ID was reserved, but no real renderbuffer object made yet */ 2988 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetNamedRenderbufferParameteriv" 2989 "(invalid renderbuffer %i)", renderbuffer); 2990 return; 2991 } 2992 2993 get_render_buffer_parameteriv(ctx, rb, pname, params, 2994 "glGetNamedRenderbufferParameteriv"); 2995} 2996 2997 2998void GLAPIENTRY 2999_mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, 3000 GLint *params) 3001{ 3002 GET_CURRENT_CONTEXT(ctx); 3003 3004 struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 3005 if (!rb || rb == &DummyRenderbuffer) { 3006 _mesa_HashLockMutex(ctx->Shared->RenderBuffers); 3007 rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, 3008 "glGetNamedRenderbufferParameterivEXT"); 3009 _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); 3010 } 3011 3012 get_render_buffer_parameteriv(ctx, rb, pname, params, 3013 "glGetNamedRenderbufferParameterivEXT"); 3014} 3015 3016 3017GLboolean GLAPIENTRY 3018_mesa_IsFramebuffer(GLuint framebuffer) 3019{ 3020 GET_CURRENT_CONTEXT(ctx); 3021 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 3022 if (framebuffer) { 3023 struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer); 3024 if (rb != NULL && rb != &DummyFramebuffer) 3025 return GL_TRUE; 3026 } 3027 return GL_FALSE; 3028} 3029 3030 3031/** 3032 * Check if any of the attachments of the given framebuffer are textures 3033 * (render to texture). Call ctx->Driver.RenderTexture() for such 3034 * attachments. 3035 */ 3036static void 3037check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) 3038{ 3039 GLuint i; 3040 assert(ctx->Driver.RenderTexture); 3041 3042 if (_mesa_is_winsys_fbo(fb)) 3043 return; /* can't render to texture with winsys framebuffers */ 3044 3045 for (i = 0; i < BUFFER_COUNT; i++) { 3046 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 3047 if (att->Texture && att->Renderbuffer->TexImage 3048 && driver_RenderTexture_is_safe(att)) { 3049 ctx->Driver.RenderTexture(ctx, fb, att); 3050 } 3051 } 3052} 3053 3054 3055/** 3056 * Examine all the framebuffer's attachments to see if any are textures. 3057 * If so, call ctx->Driver.FinishRenderTexture() for each texture to 3058 * notify the device driver that the texture image may have changed. 3059 */ 3060static void 3061check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) 3062{ 3063 /* Skip if we know NeedsFinishRenderTexture won't be set. */ 3064 if (_mesa_is_winsys_fbo(fb) && !ctx->Driver.BindRenderbufferTexImage) 3065 return; 3066 3067 if (ctx->Driver.FinishRenderTexture) { 3068 GLuint i; 3069 for (i = 0; i < BUFFER_COUNT; i++) { 3070 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 3071 struct gl_renderbuffer *rb = att->Renderbuffer; 3072 if (rb && rb->NeedsFinishRenderTexture) { 3073 ctx->Driver.FinishRenderTexture(ctx, rb); 3074 } 3075 } 3076 } 3077} 3078 3079 3080static void 3081bind_framebuffer(GLenum target, GLuint framebuffer) 3082{ 3083 struct gl_framebuffer *newDrawFb, *newReadFb; 3084 GLboolean bindReadBuf, bindDrawBuf; 3085 GET_CURRENT_CONTEXT(ctx); 3086 3087 switch (target) { 3088 case GL_DRAW_FRAMEBUFFER_EXT: 3089 bindDrawBuf = GL_TRUE; 3090 bindReadBuf = GL_FALSE; 3091 break; 3092 case GL_READ_FRAMEBUFFER_EXT: 3093 bindDrawBuf = GL_FALSE; 3094 bindReadBuf = GL_TRUE; 3095 break; 3096 case GL_FRAMEBUFFER_EXT: 3097 bindDrawBuf = GL_TRUE; 3098 bindReadBuf = GL_TRUE; 3099 break; 3100 default: 3101 _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)"); 3102 return; 3103 } 3104 3105 if (framebuffer) { 3106 bool isGenName = false; 3107 /* Binding a user-created framebuffer object */ 3108 newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer); 3109 if (newDrawFb == &DummyFramebuffer) { 3110 /* ID was reserved, but no real framebuffer object made yet */ 3111 newDrawFb = NULL; 3112 isGenName = true; 3113 } 3114 else if (!newDrawFb && ctx->API == API_OPENGL_CORE) { 3115 /* All FBO IDs must be Gen'd */ 3116 _mesa_error(ctx, GL_INVALID_OPERATION, 3117 "glBindFramebuffer(non-gen name)"); 3118 return; 3119 } 3120 3121 if (!newDrawFb) { 3122 /* create new framebuffer object */ 3123 newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer); 3124 if (!newDrawFb) { 3125 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT"); 3126 return; 3127 } 3128 _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb, isGenName); 3129 } 3130 newReadFb = newDrawFb; 3131 } 3132 else { 3133 /* Binding the window system framebuffer (which was originally set 3134 * with MakeCurrent). 3135 */ 3136 newDrawFb = ctx->WinSysDrawBuffer; 3137 newReadFb = ctx->WinSysReadBuffer; 3138 } 3139 3140 _mesa_bind_framebuffers(ctx, 3141 bindDrawBuf ? newDrawFb : ctx->DrawBuffer, 3142 bindReadBuf ? newReadFb : ctx->ReadBuffer); 3143} 3144 3145void 3146_mesa_bind_framebuffers(struct gl_context *ctx, 3147 struct gl_framebuffer *newDrawFb, 3148 struct gl_framebuffer *newReadFb) 3149{ 3150 struct gl_framebuffer *const oldDrawFb = ctx->DrawBuffer; 3151 struct gl_framebuffer *const oldReadFb = ctx->ReadBuffer; 3152 const bool bindDrawBuf = oldDrawFb != newDrawFb; 3153 const bool bindReadBuf = oldReadFb != newReadFb; 3154 3155 assert(newDrawFb); 3156 assert(newDrawFb != &DummyFramebuffer); 3157 3158 /* 3159 * OK, now bind the new Draw/Read framebuffers, if they're changing. 3160 * 3161 * We also check if we're beginning and/or ending render-to-texture. 3162 * When a framebuffer with texture attachments is unbound, call 3163 * ctx->Driver.FinishRenderTexture(). 3164 * When a framebuffer with texture attachments is bound, call 3165 * ctx->Driver.RenderTexture(). 3166 * 3167 * Note that if the ReadBuffer has texture attachments we don't consider 3168 * that a render-to-texture case. 3169 */ 3170 if (bindReadBuf) { 3171 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 3172 3173 _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb); 3174 } 3175 3176 if (bindDrawBuf) { 3177 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 3178 ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; 3179 3180 /* check if old framebuffer had any texture attachments */ 3181 if (oldDrawFb) 3182 check_end_texture_render(ctx, oldDrawFb); 3183 3184 /* check if newly bound framebuffer has any texture attachments */ 3185 check_begin_texture_render(ctx, newDrawFb); 3186 3187 _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb); 3188 _mesa_update_allow_draw_out_of_order(ctx); 3189 _mesa_update_valid_to_render_state(ctx); 3190 } 3191 3192 if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) { 3193 /* The few classic drivers that actually hook this function really only 3194 * want to know if the draw framebuffer changed. 3195 */ 3196 ctx->Driver.BindFramebuffer(ctx, 3197 bindDrawBuf ? GL_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 3198 newDrawFb, newReadFb); 3199 } 3200} 3201 3202void GLAPIENTRY 3203_mesa_BindFramebuffer(GLenum target, GLuint framebuffer) 3204{ 3205 /* OpenGL ES glBindFramebuffer and glBindFramebufferOES use this same entry 3206 * point, but they allow the use of user-generated names. 3207 */ 3208 bind_framebuffer(target, framebuffer); 3209} 3210 3211 3212void GLAPIENTRY 3213_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) 3214{ 3215 bind_framebuffer(target, framebuffer); 3216} 3217 3218 3219void GLAPIENTRY 3220_mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) 3221{ 3222 GLint i; 3223 GET_CURRENT_CONTEXT(ctx); 3224 3225 if (n < 0) { 3226 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteFramebuffers(n < 0)"); 3227 return; 3228 } 3229 3230 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 3231 3232 for (i = 0; i < n; i++) { 3233 if (framebuffers[i] > 0) { 3234 struct gl_framebuffer *fb; 3235 fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]); 3236 if (fb) { 3237 assert(fb == &DummyFramebuffer || fb->Name == framebuffers[i]); 3238 3239 /* check if deleting currently bound framebuffer object */ 3240 if (fb == ctx->DrawBuffer) { 3241 /* bind default */ 3242 assert(fb->RefCount >= 2); 3243 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 3244 } 3245 if (fb == ctx->ReadBuffer) { 3246 /* bind default */ 3247 assert(fb->RefCount >= 2); 3248 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); 3249 } 3250 3251 /* remove from hash table immediately, to free the ID */ 3252 _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]); 3253 3254 if (fb != &DummyFramebuffer) { 3255 /* But the object will not be freed until it's no longer 3256 * bound in any context. 3257 */ 3258 _mesa_reference_framebuffer(&fb, NULL); 3259 } 3260 } 3261 } 3262 } 3263} 3264 3265 3266/** 3267 * This is the implementation for glGenFramebuffers and glCreateFramebuffers. 3268 * It is not exposed to the rest of Mesa to encourage the use of 3269 * nameless buffers in driver internals. 3270 */ 3271static void 3272create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) 3273{ 3274 GET_CURRENT_CONTEXT(ctx); 3275 GLint i; 3276 struct gl_framebuffer *fb; 3277 3278 const char *func = dsa ? "glCreateFramebuffers" : "glGenFramebuffers"; 3279 3280 if (n < 0) { 3281 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func); 3282 return; 3283 } 3284 3285 if (!framebuffers) 3286 return; 3287 3288 _mesa_HashLockMutex(ctx->Shared->FrameBuffers); 3289 3290 _mesa_HashFindFreeKeys(ctx->Shared->FrameBuffers, framebuffers, n); 3291 3292 for (i = 0; i < n; i++) { 3293 if (dsa) { 3294 fb = ctx->Driver.NewFramebuffer(ctx, framebuffers[i]); 3295 if (!fb) { 3296 _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); 3297 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 3298 return; 3299 } 3300 } 3301 else 3302 fb = &DummyFramebuffer; 3303 3304 _mesa_HashInsertLocked(ctx->Shared->FrameBuffers, framebuffers[i], 3305 fb, true); 3306 } 3307 3308 _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); 3309} 3310 3311 3312void GLAPIENTRY 3313_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers) 3314{ 3315 create_framebuffers(n, framebuffers, false); 3316} 3317 3318 3319void GLAPIENTRY 3320_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers) 3321{ 3322 create_framebuffers(n, framebuffers, true); 3323} 3324 3325 3326GLenum 3327_mesa_check_framebuffer_status(struct gl_context *ctx, 3328 struct gl_framebuffer *buffer) 3329{ 3330 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 3331 3332 if (_mesa_is_winsys_fbo(buffer)) { 3333 /* EGL_KHR_surfaceless_context allows the winsys FBO to be incomplete. */ 3334 if (buffer != &IncompleteFramebuffer) { 3335 return GL_FRAMEBUFFER_COMPLETE_EXT; 3336 } else { 3337 return GL_FRAMEBUFFER_UNDEFINED; 3338 } 3339 } 3340 3341 /* No need to flush here */ 3342 3343 if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) { 3344 _mesa_test_framebuffer_completeness(ctx, buffer); 3345 } 3346 3347 return buffer->_Status; 3348} 3349 3350 3351GLenum GLAPIENTRY 3352_mesa_CheckFramebufferStatus_no_error(GLenum target) 3353{ 3354 GET_CURRENT_CONTEXT(ctx); 3355 3356 struct gl_framebuffer *fb = get_framebuffer_target(ctx, target); 3357 return _mesa_check_framebuffer_status(ctx, fb); 3358} 3359 3360 3361GLenum GLAPIENTRY 3362_mesa_CheckFramebufferStatus(GLenum target) 3363{ 3364 struct gl_framebuffer *fb; 3365 GET_CURRENT_CONTEXT(ctx); 3366 3367 if (MESA_VERBOSE & VERBOSE_API) 3368 _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n", 3369 _mesa_enum_to_string(target)); 3370 3371 fb = get_framebuffer_target(ctx, target); 3372 if (!fb) { 3373 _mesa_error(ctx, GL_INVALID_ENUM, 3374 "glCheckFramebufferStatus(invalid target %s)", 3375 _mesa_enum_to_string(target)); 3376 return 0; 3377 } 3378 3379 return _mesa_check_framebuffer_status(ctx, fb); 3380} 3381 3382 3383GLenum GLAPIENTRY 3384_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target) 3385{ 3386 struct gl_framebuffer *fb; 3387 GET_CURRENT_CONTEXT(ctx); 3388 3389 /* Validate the target (for conformance's sake) and grab a reference to the 3390 * default framebuffer in case framebuffer = 0. 3391 * Section 9.4 Framebuffer Completeness of the OpenGL 4.5 core spec 3392 * (30.10.2014, PDF page 336) says: 3393 * "If framebuffer is zero, then the status of the default read or 3394 * draw framebuffer (as determined by target) is returned." 3395 */ 3396 switch (target) { 3397 case GL_DRAW_FRAMEBUFFER: 3398 case GL_FRAMEBUFFER: 3399 fb = ctx->WinSysDrawBuffer; 3400 break; 3401 case GL_READ_FRAMEBUFFER: 3402 fb = ctx->WinSysReadBuffer; 3403 break; 3404 default: 3405 _mesa_error(ctx, GL_INVALID_ENUM, 3406 "glCheckNamedFramebufferStatus(invalid target %s)", 3407 _mesa_enum_to_string(target)); 3408 return 0; 3409 } 3410 3411 if (framebuffer) { 3412 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 3413 "glCheckNamedFramebufferStatus"); 3414 if (!fb) 3415 return 0; 3416 } 3417 3418 return _mesa_check_framebuffer_status(ctx, fb); 3419} 3420 3421 3422GLenum GLAPIENTRY 3423_mesa_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target) 3424{ 3425 struct gl_framebuffer *fb; 3426 GET_CURRENT_CONTEXT(ctx); 3427 3428 switch (target) { 3429 case GL_DRAW_FRAMEBUFFER: 3430 case GL_FRAMEBUFFER: 3431 case GL_READ_FRAMEBUFFER: 3432 break; 3433 default: 3434 _mesa_error(ctx, GL_INVALID_ENUM, 3435 "glCheckNamedFramebufferStatusEXT(invalid target %s)", 3436 _mesa_enum_to_string(target)); 3437 return 0; 3438 } 3439 3440 if (framebuffer == 0) { 3441 return _mesa_CheckNamedFramebufferStatus(0, target); 3442 } 3443 3444 fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, 3445 "glCheckNamedFramebufferStatusEXT"); 3446 if (!fb) 3447 return 0; 3448 3449 return _mesa_check_framebuffer_status(ctx, fb); 3450} 3451 3452 3453/** 3454 * Replicate the src attachment point. Used by framebuffer_texture() when 3455 * the same texture is attached at GL_DEPTH_ATTACHMENT and 3456 * GL_STENCIL_ATTACHMENT. 3457 */ 3458static void 3459reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb, 3460 gl_buffer_index dst, 3461 gl_buffer_index src) 3462{ 3463 struct gl_renderbuffer_attachment *dst_att = &fb->Attachment[dst]; 3464 struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src]; 3465 3466 assert(src_att->Texture != NULL); 3467 assert(src_att->Renderbuffer != NULL); 3468 3469 _mesa_reference_texobj(&dst_att->Texture, src_att->Texture); 3470 _mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer); 3471 dst_att->Type = src_att->Type; 3472 dst_att->Complete = src_att->Complete; 3473 dst_att->TextureLevel = src_att->TextureLevel; 3474 dst_att->CubeMapFace = src_att->CubeMapFace; 3475 dst_att->Zoffset = src_att->Zoffset; 3476 dst_att->Layered = src_att->Layered; 3477} 3478 3479 3480static struct gl_texture_object * 3481get_texture_for_framebuffer(struct gl_context *ctx, GLuint texture) 3482{ 3483 if (!texture) 3484 return NULL; 3485 3486 return _mesa_lookup_texture(ctx, texture); 3487} 3488 3489 3490/** 3491 * Common code called by gl*FramebufferTexture*() to retrieve the correct 3492 * texture object pointer. 3493 * 3494 * \param texObj where the pointer to the texture object is returned. Note 3495 * that a successful call may return texObj = NULL. 3496 * 3497 * \return true if no errors, false if errors 3498 */ 3499static bool 3500get_texture_for_framebuffer_err(struct gl_context *ctx, GLuint texture, 3501 bool layered, const char *caller, 3502 struct gl_texture_object **texObj) 3503{ 3504 *texObj = NULL; /* This will get returned if texture = 0. */ 3505 3506 if (!texture) 3507 return true; 3508 3509 *texObj = _mesa_lookup_texture(ctx, texture); 3510 if (*texObj == NULL || (*texObj)->Target == 0) { 3511 /* Can't render to a non-existent texture object. 3512 * 3513 * The OpenGL 4.5 core spec (02.02.2015) in Section 9.2 Binding and 3514 * Managing Framebuffer Objects specifies a different error 3515 * depending upon the calling function (PDF pages 325-328). 3516 * *FramebufferTexture (where layered = GL_TRUE) throws invalid 3517 * value, while the other commands throw invalid operation (where 3518 * layered = GL_FALSE). 3519 */ 3520 const GLenum error = layered ? GL_INVALID_VALUE : 3521 GL_INVALID_OPERATION; 3522 _mesa_error(ctx, error, 3523 "%s(non-existent texture %u)", caller, texture); 3524 return false; 3525 } 3526 3527 return true; 3528} 3529 3530 3531/** 3532 * Common code called by gl*FramebufferTexture() to verify the texture target 3533 * and decide whether or not the attachment should truly be considered 3534 * layered. 3535 * 3536 * \param layered true if attachment should be considered layered, false if 3537 * not 3538 * 3539 * \return true if no errors, false if errors 3540 */ 3541static bool 3542check_layered_texture_target(struct gl_context *ctx, GLenum target, 3543 const char *caller, GLboolean *layered) 3544{ 3545 *layered = GL_TRUE; 3546 3547 switch (target) { 3548 case GL_TEXTURE_3D: 3549 case GL_TEXTURE_1D_ARRAY_EXT: 3550 case GL_TEXTURE_2D_ARRAY_EXT: 3551 case GL_TEXTURE_CUBE_MAP: 3552 case GL_TEXTURE_CUBE_MAP_ARRAY: 3553 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3554 return true; 3555 case GL_TEXTURE_1D: 3556 case GL_TEXTURE_2D: 3557 case GL_TEXTURE_RECTANGLE: 3558 case GL_TEXTURE_2D_MULTISAMPLE: 3559 /* These texture types are valid to pass to 3560 * glFramebufferTexture(), but since they aren't layered, it 3561 * is equivalent to calling glFramebufferTexture{1D,2D}(). 3562 */ 3563 *layered = GL_FALSE; 3564 return true; 3565 } 3566 3567 _mesa_error(ctx, GL_INVALID_OPERATION, 3568 "%s(invalid texture target %s)", caller, 3569 _mesa_enum_to_string(target)); 3570 return false; 3571} 3572 3573 3574/** 3575 * Common code called by gl*FramebufferTextureLayer() to verify the texture 3576 * target. 3577 * 3578 * \return true if no errors, false if errors 3579 */ 3580static bool 3581check_texture_target(struct gl_context *ctx, GLenum target, 3582 const char *caller) 3583{ 3584 /* We're being called by glFramebufferTextureLayer(). 3585 * The only legal texture types for that function are 3D, 3586 * cube-map, and 1D/2D/cube-map array textures. 3587 * 3588 * We don't need to check for GL_ARB_texture_cube_map_array because the 3589 * application wouldn't have been able to create a texture with a 3590 * GL_TEXTURE_CUBE_MAP_ARRAY target if the extension were not enabled. 3591 */ 3592 switch (target) { 3593 case GL_TEXTURE_3D: 3594 case GL_TEXTURE_1D_ARRAY: 3595 case GL_TEXTURE_2D_ARRAY: 3596 case GL_TEXTURE_CUBE_MAP_ARRAY: 3597 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3598 return true; 3599 case GL_TEXTURE_CUBE_MAP: 3600 /* GL_TEXTURE_CUBE_MAP is only allowed by OpenGL 4.5 here, which 3601 * includes the DSA API. 3602 * 3603 * Because DSA is only enabled for GL 3.1+ and this can be called 3604 * from _mesa_FramebufferTextureLayer in compatibility profile, 3605 * we need to check the version. 3606 */ 3607 return _mesa_is_desktop_gl(ctx) && ctx->Version >= 31; 3608 } 3609 3610 _mesa_error(ctx, GL_INVALID_OPERATION, 3611 "%s(invalid texture target %s)", caller, 3612 _mesa_enum_to_string(target)); 3613 return false; 3614} 3615 3616 3617/** 3618 * Common code called by glFramebufferTexture*D() to verify the texture 3619 * target. 3620 * 3621 * \return true if no errors, false if errors 3622 */ 3623static bool 3624check_textarget(struct gl_context *ctx, int dims, GLenum target, 3625 GLenum textarget, const char *caller) 3626{ 3627 bool err = false; 3628 3629 switch (textarget) { 3630 case GL_TEXTURE_1D: 3631 err = dims != 1; 3632 break; 3633 case GL_TEXTURE_1D_ARRAY: 3634 err = dims != 1 || !ctx->Extensions.EXT_texture_array; 3635 break; 3636 case GL_TEXTURE_2D: 3637 err = dims != 2; 3638 break; 3639 case GL_TEXTURE_2D_ARRAY: 3640 err = dims != 2 || !ctx->Extensions.EXT_texture_array || 3641 (_mesa_is_gles(ctx) && ctx->Version < 30); 3642 break; 3643 case GL_TEXTURE_2D_MULTISAMPLE: 3644 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3645 err = dims != 2 || 3646 !ctx->Extensions.ARB_texture_multisample || 3647 (_mesa_is_gles(ctx) && ctx->Version < 31); 3648 break; 3649 case GL_TEXTURE_RECTANGLE: 3650 err = dims != 2 || _mesa_is_gles(ctx) || 3651 !ctx->Extensions.NV_texture_rectangle; 3652 break; 3653 case GL_TEXTURE_CUBE_MAP: 3654 case GL_TEXTURE_CUBE_MAP_ARRAY: 3655 err = true; 3656 break; 3657 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 3658 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 3659 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 3660 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 3661 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 3662 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 3663 err = dims != 2 || !ctx->Extensions.ARB_texture_cube_map; 3664 break; 3665 case GL_TEXTURE_3D: 3666 err = dims != 3; 3667 break; 3668 default: 3669 _mesa_error(ctx, GL_INVALID_ENUM, 3670 "%s(unknown textarget 0x%x)", caller, textarget); 3671 return false; 3672 } 3673 3674 if (err) { 3675 _mesa_error(ctx, GL_INVALID_OPERATION, 3676 "%s(invalid textarget %s)", 3677 caller, _mesa_enum_to_string(textarget)); 3678 return false; 3679 } 3680 3681 /* Make sure textarget is consistent with the texture's type */ 3682 err = (target == GL_TEXTURE_CUBE_MAP) ? 3683 !_mesa_is_cube_face(textarget): (target != textarget); 3684 3685 if (err) { 3686 _mesa_error(ctx, GL_INVALID_OPERATION, 3687 "%s(mismatched texture target)", caller); 3688 return false; 3689 } 3690 3691 return true; 3692} 3693 3694 3695/** 3696 * Common code called by gl*FramebufferTextureLayer() and 3697 * glFramebufferTexture3D() to validate the layer. 3698 * 3699 * \return true if no errors, false if errors 3700 */ 3701static bool 3702check_layer(struct gl_context *ctx, GLenum target, GLint layer, 3703 const char *caller) 3704{ 3705 /* Page 306 (page 328 of the PDF) of the OpenGL 4.5 (Core Profile) 3706 * spec says: 3707 * 3708 * "An INVALID_VALUE error is generated if texture is non-zero 3709 * and layer is negative." 3710 */ 3711 if (layer < 0) { 3712 _mesa_error(ctx, GL_INVALID_VALUE, "%s(layer %d < 0)", caller, layer); 3713 return false; 3714 } 3715 3716 if (target == GL_TEXTURE_3D) { 3717 const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 3718 if (layer >= maxSize) { 3719 _mesa_error(ctx, GL_INVALID_VALUE, 3720 "%s(invalid layer %u)", caller, layer); 3721 return false; 3722 } 3723 } 3724 else if ((target == GL_TEXTURE_1D_ARRAY) || 3725 (target == GL_TEXTURE_2D_ARRAY) || 3726 (target == GL_TEXTURE_CUBE_MAP_ARRAY) || 3727 (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) { 3728 if (layer >= ctx->Const.MaxArrayTextureLayers) { 3729 _mesa_error(ctx, GL_INVALID_VALUE, 3730 "%s(layer %u >= GL_MAX_ARRAY_TEXTURE_LAYERS)", 3731 caller, layer); 3732 return false; 3733 } 3734 } 3735 else if (target == GL_TEXTURE_CUBE_MAP) { 3736 if (layer >= 6) { 3737 _mesa_error(ctx, GL_INVALID_VALUE, 3738 "%s(layer %u >= 6)", caller, layer); 3739 return false; 3740 } 3741 } 3742 3743 return true; 3744} 3745 3746 3747/** 3748 * Common code called by all gl*FramebufferTexture*() entry points to verify 3749 * the level. 3750 * 3751 * \return true if no errors, false if errors 3752 */ 3753static bool 3754check_level(struct gl_context *ctx, struct gl_texture_object *texObj, 3755 GLenum target, GLint level, const char *caller) 3756{ 3757 /* Section 9.2.8 of the OpenGL 4.6 specification says: 3758 * 3759 * "If texture refers to an immutable-format texture, level must be 3760 * greater than or equal to zero and smaller than the value of 3761 * TEXTURE_VIEW_NUM_LEVELS for texture." 3762 */ 3763 const int max_levels = texObj->Immutable ? texObj->Attrib.ImmutableLevels : 3764 _mesa_max_texture_levels(ctx, target); 3765 3766 if (level < 0 || level >= max_levels) { 3767 _mesa_error(ctx, GL_INVALID_VALUE, 3768 "%s(invalid level %d)", caller, level); 3769 return false; 3770 } 3771 3772 return true; 3773} 3774 3775 3776struct gl_renderbuffer_attachment * 3777_mesa_get_and_validate_attachment(struct gl_context *ctx, 3778 struct gl_framebuffer *fb, 3779 GLenum attachment, const char *caller) 3780{ 3781 /* The window-system framebuffer object is immutable */ 3782 if (_mesa_is_winsys_fbo(fb)) { 3783 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(window-system framebuffer)", 3784 caller); 3785 return NULL; 3786 } 3787 3788 /* Not a hash lookup, so we can afford to get the attachment here. */ 3789 bool is_color_attachment; 3790 struct gl_renderbuffer_attachment *att = 3791 get_attachment(ctx, fb, attachment, &is_color_attachment); 3792 if (att == NULL) { 3793 if (is_color_attachment) { 3794 _mesa_error(ctx, GL_INVALID_OPERATION, 3795 "%s(invalid color attachment %s)", caller, 3796 _mesa_enum_to_string(attachment)); 3797 } else { 3798 _mesa_error(ctx, GL_INVALID_ENUM, 3799 "%s(invalid attachment %s)", caller, 3800 _mesa_enum_to_string(attachment)); 3801 } 3802 return NULL; 3803 } 3804 3805 return att; 3806} 3807 3808 3809void 3810_mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb, 3811 GLenum attachment, 3812 struct gl_renderbuffer_attachment *att, 3813 struct gl_texture_object *texObj, GLenum textarget, 3814 GLint level, GLsizei samples, 3815 GLuint layer, GLboolean layered) 3816{ 3817 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 3818 3819 simple_mtx_lock(&fb->Mutex); 3820 if (texObj) { 3821 if (attachment == GL_DEPTH_ATTACHMENT && 3822 texObj == fb->Attachment[BUFFER_STENCIL].Texture && 3823 level == fb->Attachment[BUFFER_STENCIL].TextureLevel && 3824 _mesa_tex_target_to_face(textarget) == 3825 fb->Attachment[BUFFER_STENCIL].CubeMapFace && 3826 samples == fb->Attachment[BUFFER_STENCIL].NumSamples && 3827 layer == fb->Attachment[BUFFER_STENCIL].Zoffset) { 3828 /* The texture object is already attached to the stencil attachment 3829 * point. Don't create a new renderbuffer; just reuse the stencil 3830 * attachment's. This is required to prevent a GL error in 3831 * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL). 3832 */ 3833 reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH, 3834 BUFFER_STENCIL); 3835 } else if (attachment == GL_STENCIL_ATTACHMENT && 3836 texObj == fb->Attachment[BUFFER_DEPTH].Texture && 3837 level == fb->Attachment[BUFFER_DEPTH].TextureLevel && 3838 _mesa_tex_target_to_face(textarget) == 3839 fb->Attachment[BUFFER_DEPTH].CubeMapFace && 3840 samples == fb->Attachment[BUFFER_DEPTH].NumSamples && 3841 layer == fb->Attachment[BUFFER_DEPTH].Zoffset) { 3842 /* As above, but with depth and stencil transposed. */ 3843 reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL, 3844 BUFFER_DEPTH); 3845 } else { 3846 set_texture_attachment(ctx, fb, att, texObj, textarget, 3847 level, samples, layer, layered); 3848 3849 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 3850 /* Above we created a new renderbuffer and attached it to the 3851 * depth attachment point. Now attach it to the stencil attachment 3852 * point too. 3853 */ 3854 assert(att == &fb->Attachment[BUFFER_DEPTH]); 3855 reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL, 3856 BUFFER_DEPTH); 3857 } 3858 } 3859 3860 /* Set the render-to-texture flag. We'll check this flag in 3861 * glTexImage() and friends to determine if we need to revalidate 3862 * any FBOs that might be rendering into this texture. 3863 * This flag never gets cleared since it's non-trivial to determine 3864 * when all FBOs might be done rendering to this texture. That's OK 3865 * though since it's uncommon to render to a texture then repeatedly 3866 * call glTexImage() to change images in the texture. 3867 */ 3868 texObj->_RenderToTexture = GL_TRUE; 3869 } 3870 else { 3871 remove_attachment(ctx, att); 3872 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 3873 assert(att == &fb->Attachment[BUFFER_DEPTH]); 3874 remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]); 3875 } 3876 } 3877 3878 invalidate_framebuffer(fb); 3879 3880 simple_mtx_unlock(&fb->Mutex); 3881} 3882 3883 3884static void 3885framebuffer_texture_with_dims_no_error(GLenum target, GLenum attachment, 3886 GLenum textarget, GLuint texture, 3887 GLint level, GLint layer) 3888{ 3889 GET_CURRENT_CONTEXT(ctx); 3890 3891 /* Get the framebuffer object */ 3892 struct gl_framebuffer *fb = get_framebuffer_target(ctx, target); 3893 3894 /* Get the texture object */ 3895 struct gl_texture_object *texObj = 3896 get_texture_for_framebuffer(ctx, texture); 3897 3898 struct gl_renderbuffer_attachment *att = 3899 get_attachment(ctx, fb, attachment, NULL); 3900 3901 _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget, 3902 level, 0, layer, GL_FALSE); 3903} 3904 3905 3906static void 3907framebuffer_texture_with_dims(int dims, GLenum target, GLuint framebuffer, 3908 GLenum attachment, GLenum textarget, 3909 GLuint texture, GLint level, GLsizei samples, 3910 GLint layer, const char *caller, bool dsa) 3911{ 3912 GET_CURRENT_CONTEXT(ctx); 3913 struct gl_framebuffer *fb; 3914 struct gl_texture_object *texObj; 3915 3916 /* Get the framebuffer object */ 3917 if (dsa) { 3918 fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, caller); 3919 } else { 3920 fb = get_framebuffer_target(ctx, target); 3921 } 3922 if (!fb) { 3923 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller, 3924 _mesa_enum_to_string(target)); 3925 return; 3926 } 3927 3928 /* Get the texture object */ 3929 if (!get_texture_for_framebuffer_err(ctx, texture, false, caller, &texObj)) 3930 return; 3931 3932 if (texObj) { 3933 if (!check_textarget(ctx, dims, texObj->Target, textarget, caller)) 3934 return; 3935 3936 if ((dims == 3) && !check_layer(ctx, texObj->Target, layer, caller)) 3937 return; 3938 3939 if (!check_level(ctx, texObj, textarget, level, caller)) 3940 return; 3941 } 3942 3943 struct gl_renderbuffer_attachment *att = 3944 _mesa_get_and_validate_attachment(ctx, fb, attachment, caller); 3945 if (!att) 3946 return; 3947 3948 _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget, 3949 level, samples, layer, GL_FALSE); 3950} 3951 3952 3953void GLAPIENTRY 3954_mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment, 3955 GLenum textarget, GLuint texture, 3956 GLint level) 3957{ 3958 framebuffer_texture_with_dims_no_error(target, attachment, textarget, 3959 texture, level, 0); 3960} 3961 3962 3963void GLAPIENTRY 3964_mesa_FramebufferTexture1D(GLenum target, GLenum attachment, 3965 GLenum textarget, GLuint texture, GLint level) 3966{ 3967 framebuffer_texture_with_dims(1, target, 0, attachment, textarget, texture, 3968 level, 0, 0, "glFramebufferTexture1D", false); 3969} 3970 3971 3972void GLAPIENTRY 3973_mesa_FramebufferTexture2D_no_error(GLenum target, GLenum attachment, 3974 GLenum textarget, GLuint texture, 3975 GLint level) 3976{ 3977 framebuffer_texture_with_dims_no_error(target, attachment, textarget, 3978 texture, level, 0); 3979} 3980 3981 3982void GLAPIENTRY 3983_mesa_FramebufferTexture2D(GLenum target, GLenum attachment, 3984 GLenum textarget, GLuint texture, GLint level) 3985{ 3986 framebuffer_texture_with_dims(2, target, 0, attachment, textarget, texture, 3987 level, 0, 0, "glFramebufferTexture2D", false); 3988} 3989 3990 3991void GLAPIENTRY 3992_mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, 3993 GLenum textarget, GLuint texture, 3994 GLint level, GLsizei samples) 3995{ 3996 framebuffer_texture_with_dims(2, target, 0, attachment, textarget, texture, 3997 level, samples, 0, 3998 "glFramebufferTexture2DMultisampleEXT", 3999 false); 4000} 4001 4002 4003void GLAPIENTRY 4004_mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment, 4005 GLenum textarget, GLuint texture, 4006 GLint level, GLint layer) 4007{ 4008 framebuffer_texture_with_dims_no_error(target, attachment, textarget, 4009 texture, level, layer); 4010} 4011 4012 4013void GLAPIENTRY 4014_mesa_FramebufferTexture3D(GLenum target, GLenum attachment, 4015 GLenum textarget, GLuint texture, 4016 GLint level, GLint layer) 4017{ 4018 framebuffer_texture_with_dims(3, target, 0, attachment, textarget, texture, 4019 level, 0, layer, "glFramebufferTexture3D", false); 4020} 4021 4022 4023static ALWAYS_INLINE void 4024frame_buffer_texture(GLuint framebuffer, GLenum target, 4025 GLenum attachment, GLuint texture, 4026 GLint level, GLint layer, const char *func, 4027 bool dsa, bool no_error, bool check_layered) 4028{ 4029 GET_CURRENT_CONTEXT(ctx); 4030 GLboolean layered = GL_FALSE; 4031 4032 if (!no_error && check_layered) { 4033 if (!_mesa_has_geometry_shaders(ctx)) { 4034 _mesa_error(ctx, GL_INVALID_OPERATION, 4035 "unsupported function (%s) called", func); 4036 return; 4037 } 4038 } 4039 4040 /* Get the framebuffer object */ 4041 struct gl_framebuffer *fb; 4042 if (no_error) { 4043 if (dsa) { 4044 fb = _mesa_lookup_framebuffer(ctx, framebuffer); 4045 } else { 4046 fb = get_framebuffer_target(ctx, target); 4047 } 4048 } else { 4049 if (dsa) { 4050 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func); 4051 if (!fb) 4052 return; 4053 } else { 4054 fb = get_framebuffer_target(ctx, target); 4055 if (!fb) { 4056 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", 4057 func, _mesa_enum_to_string(target)); 4058 return; 4059 } 4060 } 4061 } 4062 4063 /* Get the texture object and framebuffer attachment*/ 4064 struct gl_renderbuffer_attachment *att; 4065 struct gl_texture_object *texObj; 4066 if (no_error) { 4067 texObj = get_texture_for_framebuffer(ctx, texture); 4068 att = get_attachment(ctx, fb, attachment, NULL); 4069 } else { 4070 if (!get_texture_for_framebuffer_err(ctx, texture, check_layered, func, 4071 &texObj)) 4072 return; 4073 4074 att = _mesa_get_and_validate_attachment(ctx, fb, attachment, func); 4075 if (!att) 4076 return; 4077 } 4078 4079 GLenum textarget = 0; 4080 if (texObj) { 4081 if (check_layered) { 4082 /* We do this regardless of no_error because this sets layered */ 4083 if (!check_layered_texture_target(ctx, texObj->Target, func, 4084 &layered)) 4085 return; 4086 } 4087 4088 if (!no_error) { 4089 if (!check_layered) { 4090 if (!check_texture_target(ctx, texObj->Target, func)) 4091 return; 4092 4093 if (!check_layer(ctx, texObj->Target, layer, func)) 4094 return; 4095 } 4096 4097 if (!check_level(ctx, texObj, texObj->Target, level, func)) 4098 return; 4099 } 4100 4101 if (!check_layered && texObj->Target == GL_TEXTURE_CUBE_MAP) { 4102 assert(layer >= 0 && layer < 6); 4103 textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; 4104 layer = 0; 4105 } 4106 } 4107 4108 _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, textarget, 4109 level, 0, layer, layered); 4110} 4111 4112void GLAPIENTRY 4113_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment, 4114 GLuint texture, GLint level, 4115 GLint layer) 4116{ 4117 frame_buffer_texture(0, target, attachment, texture, level, layer, 4118 "glFramebufferTextureLayer", false, true, false); 4119} 4120 4121 4122void GLAPIENTRY 4123_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment, 4124 GLuint texture, GLint level, GLint layer) 4125{ 4126 frame_buffer_texture(0, target, attachment, texture, level, layer, 4127 "glFramebufferTextureLayer", false, false, false); 4128} 4129 4130 4131void GLAPIENTRY 4132_mesa_NamedFramebufferTextureLayer_no_error(GLuint framebuffer, 4133 GLenum attachment, 4134 GLuint texture, GLint level, 4135 GLint layer) 4136{ 4137 frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer, 4138 "glNamedFramebufferTextureLayer", true, true, false); 4139} 4140 4141 4142void GLAPIENTRY 4143_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment, 4144 GLuint texture, GLint level, GLint layer) 4145{ 4146 frame_buffer_texture(framebuffer, 0, attachment, texture, level, layer, 4147 "glNamedFramebufferTextureLayer", true, false, false); 4148} 4149 4150 4151void GLAPIENTRY 4152_mesa_FramebufferTexture_no_error(GLenum target, GLenum attachment, 4153 GLuint texture, GLint level) 4154{ 4155 frame_buffer_texture(0, target, attachment, texture, level, 0, 4156 "glFramebufferTexture", false, true, true); 4157} 4158 4159 4160void GLAPIENTRY 4161_mesa_FramebufferTexture(GLenum target, GLenum attachment, 4162 GLuint texture, GLint level) 4163{ 4164 frame_buffer_texture(0, target, attachment, texture, level, 0, 4165 "glFramebufferTexture", false, false, true); 4166} 4167 4168void GLAPIENTRY 4169_mesa_NamedFramebufferTexture_no_error(GLuint framebuffer, GLenum attachment, 4170 GLuint texture, GLint level) 4171{ 4172 frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0, 4173 "glNamedFramebufferTexture", true, true, true); 4174} 4175 4176 4177void GLAPIENTRY 4178_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment, 4179 GLuint texture, GLint level) 4180{ 4181 frame_buffer_texture(framebuffer, 0, attachment, texture, level, 0, 4182 "glNamedFramebufferTexture", true, false, true); 4183} 4184 4185 4186void GLAPIENTRY 4187_mesa_NamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, 4188 GLenum textarget, GLuint texture, GLint level) 4189{ 4190 framebuffer_texture_with_dims(1, GL_FRAMEBUFFER, framebuffer, attachment, 4191 textarget, texture, level, 0, 0, 4192 "glNamedFramebufferTexture1DEXT", true); 4193} 4194 4195 4196void GLAPIENTRY 4197_mesa_NamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, 4198 GLenum textarget, GLuint texture, GLint level) 4199{ 4200 framebuffer_texture_with_dims(2, GL_FRAMEBUFFER, framebuffer, attachment, 4201 textarget, texture, level, 0, 0, 4202 "glNamedFramebufferTexture2DEXT", true); 4203} 4204 4205 4206void GLAPIENTRY 4207_mesa_NamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, 4208 GLenum textarget, GLuint texture, 4209 GLint level, GLint zoffset) 4210{ 4211 framebuffer_texture_with_dims(3, GL_FRAMEBUFFER, framebuffer, attachment, 4212 textarget, texture, level, 0, zoffset, 4213 "glNamedFramebufferTexture3DEXT", true); 4214} 4215 4216 4217void 4218_mesa_framebuffer_renderbuffer(struct gl_context *ctx, 4219 struct gl_framebuffer *fb, 4220 GLenum attachment, 4221 struct gl_renderbuffer *rb) 4222{ 4223 assert(!_mesa_is_winsys_fbo(fb)); 4224 4225 FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); 4226 4227 assert(ctx->Driver.FramebufferRenderbuffer); 4228 ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb); 4229 4230 /* Some subsequent GL commands may depend on the framebuffer's visual 4231 * after the binding is updated. Update visual info now. 4232 */ 4233 _mesa_update_framebuffer_visual(ctx, fb); 4234} 4235 4236static ALWAYS_INLINE void 4237framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 4238 GLenum attachment, GLenum renderbuffertarget, 4239 GLuint renderbuffer, const char *func, bool no_error) 4240{ 4241 struct gl_renderbuffer_attachment *att; 4242 struct gl_renderbuffer *rb; 4243 bool is_color_attachment; 4244 4245 if (!no_error && renderbuffertarget != GL_RENDERBUFFER) { 4246 _mesa_error(ctx, GL_INVALID_ENUM, 4247 "%s(renderbuffertarget is not GL_RENDERBUFFER)", func); 4248 return; 4249 } 4250 4251 if (renderbuffer) { 4252 if (!no_error) { 4253 rb = _mesa_lookup_renderbuffer_err(ctx, renderbuffer, func); 4254 if (!rb) 4255 return; 4256 } else { 4257 rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); 4258 } 4259 } else { 4260 /* remove renderbuffer attachment */ 4261 rb = NULL; 4262 } 4263 4264 if (!no_error) { 4265 if (_mesa_is_winsys_fbo(fb)) { 4266 /* Can't attach new renderbuffers to a window system framebuffer */ 4267 _mesa_error(ctx, GL_INVALID_OPERATION, 4268 "%s(window-system framebuffer)", func); 4269 return; 4270 } 4271 4272 att = get_attachment(ctx, fb, attachment, &is_color_attachment); 4273 if (att == NULL) { 4274 /* 4275 * From OpenGL 4.5 spec, section 9.2.7 "Attaching Renderbuffer Images 4276 * to a Framebuffer": 4277 * 4278 * "An INVALID_OPERATION error is generated if attachment is 4279 * COLOR_- ATTACHMENTm where m is greater than or equal to the 4280 * value of MAX_COLOR_- ATTACHMENTS ." 4281 * 4282 * If we are at this point, is because the attachment is not valid, so 4283 * if is_color_attachment is true, is because of the previous reason. 4284 */ 4285 if (is_color_attachment) { 4286 _mesa_error(ctx, GL_INVALID_OPERATION, 4287 "%s(invalid color attachment %s)", func, 4288 _mesa_enum_to_string(attachment)); 4289 } else { 4290 _mesa_error(ctx, GL_INVALID_ENUM, 4291 "%s(invalid attachment %s)", func, 4292 _mesa_enum_to_string(attachment)); 4293 } 4294 4295 return; 4296 } 4297 4298 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT && 4299 rb && rb->Format != MESA_FORMAT_NONE) { 4300 /* make sure the renderbuffer is a depth/stencil format */ 4301 const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); 4302 if (baseFormat != GL_DEPTH_STENCIL) { 4303 _mesa_error(ctx, GL_INVALID_OPERATION, 4304 "%s(renderbuffer is not DEPTH_STENCIL format)", func); 4305 return; 4306 } 4307 } 4308 } 4309 4310 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); 4311} 4312 4313static void 4314framebuffer_renderbuffer_error(struct gl_context *ctx, 4315 struct gl_framebuffer *fb, GLenum attachment, 4316 GLenum renderbuffertarget, 4317 GLuint renderbuffer, const char *func) 4318{ 4319 framebuffer_renderbuffer(ctx, fb, attachment, renderbuffertarget, 4320 renderbuffer, func, false); 4321} 4322 4323static void 4324framebuffer_renderbuffer_no_error(struct gl_context *ctx, 4325 struct gl_framebuffer *fb, GLenum attachment, 4326 GLenum renderbuffertarget, 4327 GLuint renderbuffer, const char *func) 4328{ 4329 framebuffer_renderbuffer(ctx, fb, attachment, renderbuffertarget, 4330 renderbuffer, func, true); 4331} 4332 4333void GLAPIENTRY 4334_mesa_FramebufferRenderbuffer_no_error(GLenum target, GLenum attachment, 4335 GLenum renderbuffertarget, 4336 GLuint renderbuffer) 4337{ 4338 GET_CURRENT_CONTEXT(ctx); 4339 4340 struct gl_framebuffer *fb = get_framebuffer_target(ctx, target); 4341 framebuffer_renderbuffer_no_error(ctx, fb, attachment, renderbuffertarget, 4342 renderbuffer, "glFramebufferRenderbuffer"); 4343} 4344 4345void GLAPIENTRY 4346_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment, 4347 GLenum renderbuffertarget, 4348 GLuint renderbuffer) 4349{ 4350 struct gl_framebuffer *fb; 4351 GET_CURRENT_CONTEXT(ctx); 4352 4353 fb = get_framebuffer_target(ctx, target); 4354 if (!fb) { 4355 _mesa_error(ctx, GL_INVALID_ENUM, 4356 "glFramebufferRenderbuffer(invalid target %s)", 4357 _mesa_enum_to_string(target)); 4358 return; 4359 } 4360 4361 framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget, 4362 renderbuffer, "glFramebufferRenderbuffer"); 4363} 4364 4365void GLAPIENTRY 4366_mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer, 4367 GLenum attachment, 4368 GLenum renderbuffertarget, 4369 GLuint renderbuffer) 4370{ 4371 GET_CURRENT_CONTEXT(ctx); 4372 4373 struct gl_framebuffer *fb = _mesa_lookup_framebuffer(ctx, framebuffer); 4374 framebuffer_renderbuffer_no_error(ctx, fb, attachment, renderbuffertarget, 4375 renderbuffer, 4376 "glNamedFramebufferRenderbuffer"); 4377} 4378 4379void GLAPIENTRY 4380_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, 4381 GLenum renderbuffertarget, 4382 GLuint renderbuffer) 4383{ 4384 struct gl_framebuffer *fb; 4385 GET_CURRENT_CONTEXT(ctx); 4386 4387 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 4388 "glNamedFramebufferRenderbuffer"); 4389 if (!fb) 4390 return; 4391 4392 framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget, 4393 renderbuffer, 4394 "glNamedFramebufferRenderbuffer"); 4395} 4396 4397 4398void GLAPIENTRY 4399_mesa_NamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, 4400 GLenum renderbuffertarget, 4401 GLuint renderbuffer) 4402{ 4403 struct gl_framebuffer *fb; 4404 GET_CURRENT_CONTEXT(ctx); 4405 4406 fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, 4407 "glNamedFramebufferRenderbufferEXT"); 4408 if (!fb) 4409 return; 4410 4411 framebuffer_renderbuffer_error(ctx, fb, attachment, renderbuffertarget, 4412 renderbuffer, 4413 "glNamedFramebufferRenderbuffer"); 4414} 4415 4416 4417static void 4418get_framebuffer_attachment_parameter(struct gl_context *ctx, 4419 struct gl_framebuffer *buffer, 4420 GLenum attachment, GLenum pname, 4421 GLint *params, const char *caller) 4422{ 4423 const struct gl_renderbuffer_attachment *att; 4424 bool is_color_attachment = false; 4425 GLenum err; 4426 4427 /* The error code for an attachment type of GL_NONE differs between APIs. 4428 * 4429 * From the ES 2.0.25 specification, page 127: 4430 * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then 4431 * querying any other pname will generate INVALID_ENUM." 4432 * 4433 * From the OpenGL 3.0 specification, page 337, or identically, 4434 * the OpenGL ES 3.0.4 specification, page 240: 4435 * 4436 * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, no 4437 * framebuffer is bound to target. In this case querying pname 4438 * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero, and all other 4439 * queries will generate an INVALID_OPERATION error." 4440 */ 4441 err = ctx->API == API_OPENGLES2 && ctx->Version < 30 ? 4442 GL_INVALID_ENUM : GL_INVALID_OPERATION; 4443 4444 if (_mesa_is_winsys_fbo(buffer)) { 4445 /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec 4446 * says: 4447 * 4448 * "If the framebuffer currently bound to target is zero, then 4449 * INVALID_OPERATION is generated." 4450 * 4451 * The EXT_framebuffer_object spec has the same wording, and the 4452 * OES_framebuffer_object spec refers to the EXT_framebuffer_object 4453 * spec. 4454 */ 4455 if ((!_mesa_is_desktop_gl(ctx) || 4456 !ctx->Extensions.ARB_framebuffer_object) 4457 && !_mesa_is_gles3(ctx)) { 4458 _mesa_error(ctx, GL_INVALID_OPERATION, 4459 "%s(window-system framebuffer)", caller); 4460 return; 4461 } 4462 4463 if (_mesa_is_gles3(ctx) && attachment != GL_BACK && 4464 attachment != GL_DEPTH && attachment != GL_STENCIL) { 4465 _mesa_error(ctx, GL_INVALID_ENUM, 4466 "%s(invalid attachment %s)", caller, 4467 _mesa_enum_to_string(attachment)); 4468 return; 4469 } 4470 4471 /* The specs are not clear about how to handle 4472 * GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME with the default framebuffer, 4473 * but dEQP-GLES3 expects an INVALID_ENUM error. This has also been 4474 * discussed in: 4475 * 4476 * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=12928#c1 4477 * and https://bugs.freedesktop.org/show_bug.cgi?id=31947 4478 */ 4479 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 4480 _mesa_error(ctx, GL_INVALID_ENUM, 4481 "%s(requesting GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME " 4482 "when GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is " 4483 "GL_FRAMEBUFFER_DEFAULT is not allowed)", caller); 4484 return; 4485 } 4486 4487 /* the default / window-system FBO */ 4488 att = get_fb0_attachment(ctx, buffer, attachment); 4489 } 4490 else { 4491 /* user-created framebuffer FBO */ 4492 att = get_attachment(ctx, buffer, attachment, &is_color_attachment); 4493 } 4494 4495 if (att == NULL) { 4496 /* 4497 * From OpenGL 4.5 spec, section 9.2.3 "Framebuffer Object Queries": 4498 * 4499 * "An INVALID_OPERATION error is generated if a framebuffer object 4500 * is bound to target and attachment is COLOR_ATTACHMENTm where m is 4501 * greater than or equal to the value of MAX_COLOR_ATTACHMENTS." 4502 * 4503 * If we are at this point, is because the attachment is not valid, so 4504 * if is_color_attachment is true, is because of the previous reason. 4505 */ 4506 if (is_color_attachment) { 4507 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid color attachment %s)", 4508 caller, _mesa_enum_to_string(attachment)); 4509 } else { 4510 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", caller, 4511 _mesa_enum_to_string(attachment)); 4512 } 4513 return; 4514 } 4515 4516 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 4517 const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt; 4518 if (pname == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) { 4519 /* This behavior is first specified in OpenGL 4.4 specification. 4520 * 4521 * From the OpenGL 4.4 spec page 275: 4522 * "This query cannot be performed for a combined depth+stencil 4523 * attachment, since it does not have a single format." 4524 */ 4525 _mesa_error(ctx, GL_INVALID_OPERATION, 4526 "%s(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE" 4527 " is invalid for depth+stencil attachment)", caller); 4528 return; 4529 } 4530 /* the depth and stencil attachments must point to the same buffer */ 4531 depthAtt = get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT, NULL); 4532 stencilAtt = get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT, NULL); 4533 if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) { 4534 _mesa_error(ctx, GL_INVALID_OPERATION, 4535 "%s(DEPTH/STENCIL attachments differ)", caller); 4536 return; 4537 } 4538 } 4539 4540 /* No need to flush here */ 4541 4542 switch (pname) { 4543 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: 4544 /* From the OpenGL spec, 9.2. Binding and Managing Framebuffer Objects: 4545 * 4546 * "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, then 4547 * either no framebuffer is bound to target; or the default framebuffer 4548 * is bound, attachment is DEPTH or STENCIL, and the number of depth or 4549 * stencil bits, respectively, is zero." 4550 * 4551 * Note that we don't need explicit checks on DEPTH and STENCIL, because 4552 * on the case the spec is pointing, att->Type is already NONE, so we 4553 * just need to check att->Type. 4554 */ 4555 *params = (_mesa_is_winsys_fbo(buffer) && att->Type != GL_NONE) ? 4556 GL_FRAMEBUFFER_DEFAULT : att->Type; 4557 return; 4558 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: 4559 if (att->Type == GL_RENDERBUFFER_EXT) { 4560 *params = att->Renderbuffer->Name; 4561 } 4562 else if (att->Type == GL_TEXTURE) { 4563 *params = att->Texture->Name; 4564 } 4565 else { 4566 assert(att->Type == GL_NONE); 4567 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 4568 *params = 0; 4569 } else { 4570 goto invalid_pname_enum; 4571 } 4572 } 4573 return; 4574 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: 4575 if (att->Type == GL_TEXTURE) { 4576 *params = att->TextureLevel; 4577 } 4578 else if (att->Type == GL_NONE) { 4579 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4580 _mesa_enum_to_string(pname)); 4581 } 4582 else { 4583 goto invalid_pname_enum; 4584 } 4585 return; 4586 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT: 4587 if (att->Type == GL_TEXTURE) { 4588 if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) { 4589 *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace; 4590 } 4591 else { 4592 *params = 0; 4593 } 4594 } 4595 else if (att->Type == GL_NONE) { 4596 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4597 _mesa_enum_to_string(pname)); 4598 } 4599 else { 4600 goto invalid_pname_enum; 4601 } 4602 return; 4603 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: 4604 if (ctx->API == API_OPENGLES) { 4605 goto invalid_pname_enum; 4606 } else if (att->Type == GL_NONE) { 4607 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4608 _mesa_enum_to_string(pname)); 4609 } else if (att->Type == GL_TEXTURE) { 4610 if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D || 4611 att->Texture->Target == GL_TEXTURE_2D_ARRAY)) { 4612 *params = att->Zoffset; 4613 } 4614 else { 4615 *params = 0; 4616 } 4617 } 4618 else { 4619 goto invalid_pname_enum; 4620 } 4621 return; 4622 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 4623 if ((!_mesa_is_desktop_gl(ctx) || 4624 !ctx->Extensions.ARB_framebuffer_object) 4625 && !_mesa_is_gles3(ctx)) { 4626 goto invalid_pname_enum; 4627 } 4628 else if (att->Type == GL_NONE) { 4629 if (_mesa_is_winsys_fbo(buffer) && 4630 (attachment == GL_DEPTH || attachment == GL_STENCIL)) { 4631 *params = GL_LINEAR; 4632 } else { 4633 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4634 _mesa_enum_to_string(pname)); 4635 } 4636 } 4637 else { 4638 if (ctx->Extensions.EXT_sRGB) { 4639 *params = (_mesa_is_format_srgb(att->Renderbuffer->Format) ? 4640 GL_SRGB : GL_LINEAR); 4641 } 4642 else { 4643 /* According to ARB_framebuffer_sRGB, we should return LINEAR 4644 * if the sRGB conversion is unsupported. */ 4645 *params = GL_LINEAR; 4646 } 4647 } 4648 return; 4649 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 4650 if ((ctx->API != API_OPENGL_COMPAT || 4651 !ctx->Extensions.ARB_framebuffer_object) 4652 && ctx->API != API_OPENGL_CORE 4653 && !_mesa_is_gles3(ctx)) { 4654 goto invalid_pname_enum; 4655 } 4656 else if (att->Type == GL_NONE) { 4657 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4658 _mesa_enum_to_string(pname)); 4659 } 4660 else { 4661 mesa_format format = att->Renderbuffer->Format; 4662 4663 /* Page 235 (page 247 of the PDF) in section 6.1.13 of the OpenGL ES 4664 * 3.0.1 spec says: 4665 * 4666 * "If pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.... If 4667 * attachment is DEPTH_STENCIL_ATTACHMENT the query will fail and 4668 * generate an INVALID_OPERATION error. 4669 */ 4670 if (_mesa_is_gles3(ctx) && 4671 attachment == GL_DEPTH_STENCIL_ATTACHMENT) { 4672 _mesa_error(ctx, GL_INVALID_OPERATION, 4673 "%s(cannot query " 4674 "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE of " 4675 "GL_DEPTH_STENCIL_ATTACHMENT)", caller); 4676 return; 4677 } 4678 4679 if (format == MESA_FORMAT_S_UINT8) { 4680 /* special cases */ 4681 *params = GL_INDEX; 4682 } 4683 else if (format == MESA_FORMAT_Z32_FLOAT_S8X24_UINT) { 4684 /* depends on the attachment parameter */ 4685 if (attachment == GL_STENCIL_ATTACHMENT) { 4686 *params = GL_INDEX; 4687 } 4688 else { 4689 *params = GL_FLOAT; 4690 } 4691 } 4692 else { 4693 *params = _mesa_get_format_datatype(format); 4694 } 4695 } 4696 return; 4697 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 4698 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 4699 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 4700 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 4701 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 4702 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 4703 if ((!_mesa_is_desktop_gl(ctx) || 4704 !ctx->Extensions.ARB_framebuffer_object) 4705 && !_mesa_is_gles3(ctx)) { 4706 goto invalid_pname_enum; 4707 } 4708 else if (att->Texture) { 4709 const struct gl_texture_image *texImage = 4710 _mesa_select_tex_image(att->Texture, att->Texture->Target, 4711 att->TextureLevel); 4712 if (texImage) { 4713 *params = get_component_bits(pname, texImage->_BaseFormat, 4714 texImage->TexFormat); 4715 } 4716 else { 4717 *params = 0; 4718 } 4719 } 4720 else if (att->Renderbuffer) { 4721 *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat, 4722 att->Renderbuffer->Format); 4723 } 4724 else { 4725 assert(att->Type == GL_NONE); 4726 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4727 _mesa_enum_to_string(pname)); 4728 } 4729 return; 4730 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED: 4731 if (!_mesa_has_geometry_shaders(ctx)) { 4732 goto invalid_pname_enum; 4733 } else if (att->Type == GL_TEXTURE) { 4734 *params = att->Layered; 4735 } else if (att->Type == GL_NONE) { 4736 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4737 _mesa_enum_to_string(pname)); 4738 } else { 4739 goto invalid_pname_enum; 4740 } 4741 return; 4742 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: 4743 if (!ctx->Extensions.EXT_multisampled_render_to_texture) { 4744 goto invalid_pname_enum; 4745 } else if (att->Type == GL_TEXTURE) { 4746 *params = att->NumSamples; 4747 } else if (att->Type == GL_NONE) { 4748 _mesa_error(ctx, err, "%s(invalid pname %s)", caller, 4749 _mesa_enum_to_string(pname)); 4750 } else { 4751 goto invalid_pname_enum; 4752 } 4753 return; 4754 default: 4755 goto invalid_pname_enum; 4756 } 4757 4758 return; 4759 4760invalid_pname_enum: 4761 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname %s)", caller, 4762 _mesa_enum_to_string(pname)); 4763 return; 4764} 4765 4766 4767void GLAPIENTRY 4768_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, 4769 GLenum pname, GLint *params) 4770{ 4771 GET_CURRENT_CONTEXT(ctx); 4772 struct gl_framebuffer *buffer; 4773 4774 buffer = get_framebuffer_target(ctx, target); 4775 if (!buffer) { 4776 _mesa_error(ctx, GL_INVALID_ENUM, 4777 "glGetFramebufferAttachmentParameteriv(invalid target %s)", 4778 _mesa_enum_to_string(target)); 4779 return; 4780 } 4781 4782 get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname, 4783 params, 4784 "glGetFramebufferAttachmentParameteriv"); 4785} 4786 4787 4788void GLAPIENTRY 4789_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, 4790 GLenum attachment, 4791 GLenum pname, GLint *params) 4792{ 4793 GET_CURRENT_CONTEXT(ctx); 4794 struct gl_framebuffer *buffer; 4795 4796 if (framebuffer) { 4797 buffer = _mesa_lookup_framebuffer_err(ctx, framebuffer, 4798 "glGetNamedFramebufferAttachmentParameteriv"); 4799 if (!buffer) 4800 return; 4801 } 4802 else { 4803 /* 4804 * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL 4805 * 4.5 core spec (30.10.2014, PDF page 314): 4806 * "If framebuffer is zero, then the default draw framebuffer is 4807 * queried." 4808 */ 4809 buffer = ctx->WinSysDrawBuffer; 4810 } 4811 4812 get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname, 4813 params, 4814 "glGetNamedFramebufferAttachmentParameteriv"); 4815} 4816 4817 4818void GLAPIENTRY 4819_mesa_GetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, 4820 GLenum attachment, 4821 GLenum pname, GLint *params) 4822{ 4823 GET_CURRENT_CONTEXT(ctx); 4824 struct gl_framebuffer *buffer; 4825 4826 if (framebuffer) { 4827 buffer = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, 4828 "glGetNamedFramebufferAttachmentParameterivEXT"); 4829 if (!buffer) 4830 return; 4831 } 4832 else { 4833 /* 4834 * Section 9.2 Binding and Managing Framebuffer Objects of the OpenGL 4835 * 4.5 core spec (30.10.2014, PDF page 314): 4836 * "If framebuffer is zero, then the default draw framebuffer is 4837 * queried." 4838 */ 4839 buffer = ctx->WinSysDrawBuffer; 4840 } 4841 4842 get_framebuffer_attachment_parameter(ctx, buffer, attachment, pname, 4843 params, 4844 "glGetNamedFramebufferAttachmentParameterivEXT"); 4845} 4846 4847 4848void GLAPIENTRY 4849_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname, 4850 GLint param) 4851{ 4852 GET_CURRENT_CONTEXT(ctx); 4853 struct gl_framebuffer *fb = NULL; 4854 4855 if (!ctx->Extensions.ARB_framebuffer_no_attachments && 4856 !ctx->Extensions.ARB_sample_locations) { 4857 _mesa_error(ctx, GL_INVALID_OPERATION, 4858 "glNamedFramebufferParameteri(" 4859 "neither ARB_framebuffer_no_attachments nor " 4860 "ARB_sample_locations is available)"); 4861 return; 4862 } 4863 4864 if (framebuffer) { 4865 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 4866 "glNamedFramebufferParameteri"); 4867 } else { 4868 fb = ctx->WinSysDrawBuffer; 4869 } 4870 4871 if (fb) { 4872 framebuffer_parameteri(ctx, fb, pname, param, 4873 "glNamedFramebufferParameteriv"); 4874 } 4875} 4876 4877 4878/* Helper function for ARB_framebuffer_no_attachments functions interacting with EXT_direct_state_access */ 4879static struct gl_framebuffer * 4880lookup_named_framebuffer_ext_dsa(struct gl_context *ctx, GLuint framebuffer, const char* caller) 4881{ 4882 struct gl_framebuffer *fb = NULL; 4883 4884 if (framebuffer) { 4885 /* The ARB_framebuffer_no_attachments spec says: 4886 * 4887 * "The error INVALID_VALUE is generated if <framebuffer> is not 4888 * a name returned by GenFramebuffers. If a framebuffer object 4889 * named <framebuffer> does not yet exist, it will be created." 4890 * 4891 * This is different from the EXT_direct_state_access spec which says: 4892 * 4893 * "If the framebuffer object named by the framebuffer parameter has not 4894 * been previously bound or has been deleted since the last binding, 4895 * the GL first creates a new state vector in the same manner as when 4896 * BindFramebuffer creates a new framebuffer object" 4897 * 4898 * So first we verify that the name exists. 4899 */ 4900 fb = _mesa_lookup_framebuffer(ctx, framebuffer); 4901 if (!fb) { 4902 _mesa_error(ctx, GL_INVALID_VALUE, "%s(frameBuffer)", caller); 4903 return NULL; 4904 } 4905 /* Then, make sure it's initialized */ 4906 if (fb == &DummyFramebuffer) { 4907 fb = ctx->Driver.NewFramebuffer(ctx, framebuffer); 4908 _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, fb, true); 4909 } 4910 } 4911 else 4912 fb = ctx->WinSysDrawBuffer; 4913 4914 return fb; 4915} 4916 4917 4918void GLAPIENTRY 4919_mesa_NamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, 4920 GLint param) 4921{ 4922 GET_CURRENT_CONTEXT(ctx); 4923 struct gl_framebuffer *fb = 4924 lookup_named_framebuffer_ext_dsa(ctx, framebuffer, 4925 "glNamedFramebufferParameteriEXT"); 4926 4927 if (!fb) 4928 return; 4929 4930 framebuffer_parameteri(ctx, fb, pname, param, 4931 "glNamedFramebufferParameteriEXT"); 4932} 4933 4934 4935void GLAPIENTRY 4936_mesa_GetFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, 4937 GLint *param) 4938{ 4939 GET_CURRENT_CONTEXT(ctx); 4940 struct gl_framebuffer *fb; 4941 4942 if (framebuffer) 4943 fb = _mesa_lookup_framebuffer_dsa(ctx, framebuffer, 4944 "glGetFramebufferParameterivEXT"); 4945 else 4946 fb = ctx->WinSysDrawBuffer; 4947 4948 if (fb) { 4949 /* The GL_EXT_direct_state_access says: 4950 * 4951 * The pname parameter must be one of framebuffer dependent values 4952 * listed in either table 4.nnn (namely DRAW_BUFFER, READ_BUFFER, 4953 * or DRAW_BUFFER0 through DRAW_BUFFER15). 4954 */ 4955 if (pname == GL_DRAW_BUFFER) { 4956 *param = fb->ColorDrawBuffer[0]; 4957 4958 } 4959 else if (pname == GL_READ_BUFFER) { 4960 *param = fb->ColorReadBuffer; 4961 } 4962 else if (GL_DRAW_BUFFER0 <= pname && pname <= GL_DRAW_BUFFER15) { 4963 unsigned buffer = pname - GL_DRAW_BUFFER0; 4964 if (buffer < ARRAY_SIZE(fb->ColorDrawBuffer)) 4965 *param = fb->ColorDrawBuffer[buffer]; 4966 else 4967 _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferParameterivEXT(pname)"); 4968 } 4969 else { 4970 _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferParameterivEXT(pname)"); 4971 } 4972 } 4973} 4974 4975 4976void GLAPIENTRY 4977_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, 4978 GLint *param) 4979{ 4980 GET_CURRENT_CONTEXT(ctx); 4981 struct gl_framebuffer *fb; 4982 4983 if (!ctx->Extensions.ARB_framebuffer_no_attachments) { 4984 _mesa_error(ctx, GL_INVALID_OPERATION, 4985 "glNamedFramebufferParameteriv(" 4986 "neither ARB_framebuffer_no_attachments nor ARB_sample_locations" 4987 " is available)"); 4988 return; 4989 } 4990 4991 if (framebuffer) 4992 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 4993 "glGetNamedFramebufferParameteriv"); 4994 else 4995 fb = ctx->WinSysDrawBuffer; 4996 4997 if (fb) { 4998 get_framebuffer_parameteriv(ctx, fb, pname, param, 4999 "glGetNamedFramebufferParameteriv"); 5000 } 5001} 5002 5003 5004void GLAPIENTRY 5005_mesa_GetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, 5006 GLint *param) 5007{ 5008 GET_CURRENT_CONTEXT(ctx); 5009 struct gl_framebuffer *fb = 5010 lookup_named_framebuffer_ext_dsa(ctx, framebuffer, 5011 "glGetNamedFramebufferParameterivEXT"); 5012 5013 if (!fb) 5014 return; 5015 5016 get_framebuffer_parameteriv(ctx, fb, pname, param, 5017 "glGetNamedFramebufferParameterivEXT"); 5018} 5019 5020 5021static void 5022invalidate_framebuffer_storage(struct gl_context *ctx, 5023 struct gl_framebuffer *fb, 5024 GLsizei numAttachments, 5025 const GLenum *attachments, GLint x, GLint y, 5026 GLsizei width, GLsizei height, const char *name) 5027{ 5028 int i; 5029 5030 /* Section 17.4 Whole Framebuffer Operations of the OpenGL 4.5 Core 5031 * Spec (2.2.2015, PDF page 522) says: 5032 * "An INVALID_VALUE error is generated if numAttachments, width, or 5033 * height is negative." 5034 */ 5035 if (numAttachments < 0) { 5036 _mesa_error(ctx, GL_INVALID_VALUE, 5037 "%s(numAttachments < 0)", name); 5038 return; 5039 } 5040 5041 if (width < 0) { 5042 _mesa_error(ctx, GL_INVALID_VALUE, 5043 "%s(width < 0)", name); 5044 return; 5045 } 5046 5047 if (height < 0) { 5048 _mesa_error(ctx, GL_INVALID_VALUE, 5049 "%s(height < 0)", name); 5050 return; 5051 } 5052 5053 /* The GL_ARB_invalidate_subdata spec says: 5054 * 5055 * "If an attachment is specified that does not exist in the 5056 * framebuffer bound to <target>, it is ignored." 5057 * 5058 * It also says: 5059 * 5060 * "If <attachments> contains COLOR_ATTACHMENTm and m is greater than 5061 * or equal to the value of MAX_COLOR_ATTACHMENTS, then the error 5062 * INVALID_OPERATION is generated." 5063 * 5064 * No mention is made of GL_AUXi being out of range. Therefore, we allow 5065 * any enum that can be allowed by the API (OpenGL ES 3.0 has a different 5066 * set of retrictions). 5067 */ 5068 for (i = 0; i < numAttachments; i++) { 5069 if (_mesa_is_winsys_fbo(fb)) { 5070 switch (attachments[i]) { 5071 case GL_ACCUM: 5072 case GL_AUX0: 5073 case GL_AUX1: 5074 case GL_AUX2: 5075 case GL_AUX3: 5076 /* Accumulation buffers and auxilary buffers were removed in 5077 * OpenGL 3.1, and they never existed in OpenGL ES. 5078 */ 5079 if (ctx->API != API_OPENGL_COMPAT) 5080 goto invalid_enum; 5081 break; 5082 case GL_COLOR: 5083 case GL_DEPTH: 5084 case GL_STENCIL: 5085 break; 5086 case GL_BACK_LEFT: 5087 case GL_BACK_RIGHT: 5088 case GL_FRONT_LEFT: 5089 case GL_FRONT_RIGHT: 5090 if (!_mesa_is_desktop_gl(ctx)) 5091 goto invalid_enum; 5092 break; 5093 default: 5094 goto invalid_enum; 5095 } 5096 } else { 5097 switch (attachments[i]) { 5098 case GL_DEPTH_ATTACHMENT: 5099 case GL_STENCIL_ATTACHMENT: 5100 break; 5101 case GL_DEPTH_STENCIL_ATTACHMENT: 5102 /* GL_DEPTH_STENCIL_ATTACHMENT is a valid attachment point only 5103 * in desktop and ES 3.0 profiles. Note that OES_packed_depth_stencil 5104 * extension does not make this attachment point valid on ES 2.0. 5105 */ 5106 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) 5107 break; 5108 FALLTHROUGH; 5109 case GL_COLOR_ATTACHMENT0: 5110 case GL_COLOR_ATTACHMENT1: 5111 case GL_COLOR_ATTACHMENT2: 5112 case GL_COLOR_ATTACHMENT3: 5113 case GL_COLOR_ATTACHMENT4: 5114 case GL_COLOR_ATTACHMENT5: 5115 case GL_COLOR_ATTACHMENT6: 5116 case GL_COLOR_ATTACHMENT7: 5117 case GL_COLOR_ATTACHMENT8: 5118 case GL_COLOR_ATTACHMENT9: 5119 case GL_COLOR_ATTACHMENT10: 5120 case GL_COLOR_ATTACHMENT11: 5121 case GL_COLOR_ATTACHMENT12: 5122 case GL_COLOR_ATTACHMENT13: 5123 case GL_COLOR_ATTACHMENT14: 5124 case GL_COLOR_ATTACHMENT15: { 5125 unsigned k = attachments[i] - GL_COLOR_ATTACHMENT0; 5126 if (k >= ctx->Const.MaxColorAttachments) { 5127 _mesa_error(ctx, GL_INVALID_OPERATION, 5128 "%s(attachment >= max. color attachments)", name); 5129 return; 5130 } 5131 break; 5132 } 5133 default: 5134 goto invalid_enum; 5135 } 5136 } 5137 } 5138 5139 /* We don't actually do anything for this yet. Just return after 5140 * validating the parameters and generating the required errors. 5141 */ 5142 return; 5143 5144invalid_enum: 5145 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid attachment %s)", name, 5146 _mesa_enum_to_string(attachments[i])); 5147 return; 5148} 5149 5150static struct gl_renderbuffer_attachment * 5151get_fb_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, 5152 const GLenum attachment) 5153{ 5154 switch (attachment) { 5155 case GL_COLOR: 5156 return &fb->Attachment[BUFFER_BACK_LEFT]; 5157 case GL_COLOR_ATTACHMENT0: 5158 case GL_COLOR_ATTACHMENT1: 5159 case GL_COLOR_ATTACHMENT2: 5160 case GL_COLOR_ATTACHMENT3: 5161 case GL_COLOR_ATTACHMENT4: 5162 case GL_COLOR_ATTACHMENT5: 5163 case GL_COLOR_ATTACHMENT6: 5164 case GL_COLOR_ATTACHMENT7: 5165 case GL_COLOR_ATTACHMENT8: 5166 case GL_COLOR_ATTACHMENT9: 5167 case GL_COLOR_ATTACHMENT10: 5168 case GL_COLOR_ATTACHMENT11: 5169 case GL_COLOR_ATTACHMENT12: 5170 case GL_COLOR_ATTACHMENT13: 5171 case GL_COLOR_ATTACHMENT14: 5172 case GL_COLOR_ATTACHMENT15: { 5173 const unsigned i = attachment - GL_COLOR_ATTACHMENT0; 5174 if (i >= ctx->Const.MaxColorAttachments) 5175 return NULL; 5176 assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment)); 5177 return &fb->Attachment[BUFFER_COLOR0 + i]; 5178 } 5179 case GL_DEPTH: 5180 case GL_DEPTH_ATTACHMENT: 5181 case GL_DEPTH_STENCIL_ATTACHMENT: 5182 return &fb->Attachment[BUFFER_DEPTH]; 5183 case GL_STENCIL: 5184 case GL_STENCIL_ATTACHMENT: 5185 return &fb->Attachment[BUFFER_STENCIL]; 5186 default: 5187 return NULL; 5188 } 5189} 5190 5191static void 5192discard_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 5193 GLsizei numAttachments, const GLenum *attachments) 5194{ 5195 if (!ctx->Driver.DiscardFramebuffer) 5196 return; 5197 5198 for (int i = 0; i < numAttachments; i++) { 5199 struct gl_renderbuffer_attachment *att = 5200 get_fb_attachment(ctx, fb, attachments[i]); 5201 5202 if (!att) 5203 continue; 5204 5205 /* If we're asked to invalidate just depth or just stencil, but the 5206 * attachment is packed depth/stencil, then we can only use 5207 * Driver.DiscardFramebuffer if the attachments list includes both depth 5208 * and stencil and they both point at the same renderbuffer. 5209 */ 5210 if ((attachments[i] == GL_DEPTH_ATTACHMENT || 5211 attachments[i] == GL_STENCIL_ATTACHMENT) && 5212 (!att->Renderbuffer || 5213 att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL)) { 5214 GLenum other_format = (attachments[i] == GL_DEPTH_ATTACHMENT ? 5215 GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT); 5216 bool has_both = false; 5217 for (int j = 0; j < numAttachments; j++) { 5218 if (attachments[j] == other_format) { 5219 has_both = true; 5220 break; 5221 } 5222 } 5223 5224 if (fb->Attachment[BUFFER_DEPTH].Renderbuffer != 5225 fb->Attachment[BUFFER_STENCIL].Renderbuffer || !has_both) 5226 continue; 5227 } 5228 5229 ctx->Driver.DiscardFramebuffer(ctx, fb, att); 5230 } 5231} 5232 5233void GLAPIENTRY 5234_mesa_InvalidateSubFramebuffer_no_error(GLenum target, GLsizei numAttachments, 5235 const GLenum *attachments, GLint x, 5236 GLint y, GLsizei width, GLsizei height) 5237{ 5238 /* no-op */ 5239} 5240 5241 5242void GLAPIENTRY 5243_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, 5244 const GLenum *attachments, GLint x, GLint y, 5245 GLsizei width, GLsizei height) 5246{ 5247 struct gl_framebuffer *fb; 5248 GET_CURRENT_CONTEXT(ctx); 5249 5250 fb = get_framebuffer_target(ctx, target); 5251 if (!fb) { 5252 _mesa_error(ctx, GL_INVALID_ENUM, 5253 "glInvalidateSubFramebuffer(invalid target %s)", 5254 _mesa_enum_to_string(target)); 5255 return; 5256 } 5257 5258 invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments, 5259 x, y, width, height, 5260 "glInvalidateSubFramebuffer"); 5261} 5262 5263 5264void GLAPIENTRY 5265_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer, 5266 GLsizei numAttachments, 5267 const GLenum *attachments, 5268 GLint x, GLint y, 5269 GLsizei width, GLsizei height) 5270{ 5271 struct gl_framebuffer *fb; 5272 GET_CURRENT_CONTEXT(ctx); 5273 5274 /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole 5275 * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the 5276 * default draw framebuffer is affected." 5277 */ 5278 if (framebuffer) { 5279 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 5280 "glInvalidateNamedFramebufferSubData"); 5281 if (!fb) 5282 return; 5283 } 5284 else 5285 fb = ctx->WinSysDrawBuffer; 5286 5287 invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments, 5288 x, y, width, height, 5289 "glInvalidateNamedFramebufferSubData"); 5290} 5291 5292void GLAPIENTRY 5293_mesa_InvalidateFramebuffer_no_error(GLenum target, GLsizei numAttachments, 5294 const GLenum *attachments) 5295{ 5296 struct gl_framebuffer *fb; 5297 GET_CURRENT_CONTEXT(ctx); 5298 5299 fb = get_framebuffer_target(ctx, target); 5300 if (!fb) 5301 return; 5302 5303 discard_framebuffer(ctx, fb, numAttachments, attachments); 5304} 5305 5306 5307void GLAPIENTRY 5308_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments, 5309 const GLenum *attachments) 5310{ 5311 struct gl_framebuffer *fb; 5312 GET_CURRENT_CONTEXT(ctx); 5313 5314 fb = get_framebuffer_target(ctx, target); 5315 if (!fb) { 5316 _mesa_error(ctx, GL_INVALID_ENUM, 5317 "glInvalidateFramebuffer(invalid target %s)", 5318 _mesa_enum_to_string(target)); 5319 return; 5320 } 5321 5322 /* The GL_ARB_invalidate_subdata spec says: 5323 * 5324 * "The command 5325 * 5326 * void InvalidateFramebuffer(enum target, 5327 * sizei numAttachments, 5328 * const enum *attachments); 5329 * 5330 * is equivalent to the command InvalidateSubFramebuffer with <x>, <y>, 5331 * <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>, 5332 * <MAX_VIEWPORT_DIMS[1]> respectively." 5333 */ 5334 invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments, 5335 0, 0, 5336 ctx->Const.MaxViewportWidth, 5337 ctx->Const.MaxViewportHeight, 5338 "glInvalidateFramebuffer"); 5339 5340 discard_framebuffer(ctx, fb, numAttachments, attachments); 5341} 5342 5343 5344void GLAPIENTRY 5345_mesa_InvalidateNamedFramebufferData(GLuint framebuffer, 5346 GLsizei numAttachments, 5347 const GLenum *attachments) 5348{ 5349 struct gl_framebuffer *fb; 5350 GET_CURRENT_CONTEXT(ctx); 5351 5352 /* The OpenGL 4.5 core spec (02.02.2015) says (in Section 17.4 Whole 5353 * Framebuffer Operations, PDF page 522): "If framebuffer is zero, the 5354 * default draw framebuffer is affected." 5355 */ 5356 if (framebuffer) { 5357 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 5358 "glInvalidateNamedFramebufferData"); 5359 if (!fb) 5360 return; 5361 } 5362 else 5363 fb = ctx->WinSysDrawBuffer; 5364 5365 /* The GL_ARB_invalidate_subdata spec says: 5366 * 5367 * "The command 5368 * 5369 * void InvalidateFramebuffer(enum target, 5370 * sizei numAttachments, 5371 * const enum *attachments); 5372 * 5373 * is equivalent to the command InvalidateSubFramebuffer with <x>, <y>, 5374 * <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>, 5375 * <MAX_VIEWPORT_DIMS[1]> respectively." 5376 */ 5377 invalidate_framebuffer_storage(ctx, fb, numAttachments, attachments, 5378 0, 0, 5379 ctx->Const.MaxViewportWidth, 5380 ctx->Const.MaxViewportHeight, 5381 "glInvalidateNamedFramebufferData"); 5382} 5383 5384 5385void GLAPIENTRY 5386_mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, 5387 const GLenum *attachments) 5388{ 5389 struct gl_framebuffer *fb; 5390 GLint i; 5391 5392 GET_CURRENT_CONTEXT(ctx); 5393 5394 fb = get_framebuffer_target(ctx, target); 5395 if (!fb) { 5396 _mesa_error(ctx, GL_INVALID_ENUM, 5397 "glDiscardFramebufferEXT(target %s)", 5398 _mesa_enum_to_string(target)); 5399 return; 5400 } 5401 5402 if (numAttachments < 0) { 5403 _mesa_error(ctx, GL_INVALID_VALUE, 5404 "glDiscardFramebufferEXT(numAttachments < 0)"); 5405 return; 5406 } 5407 5408 for (i = 0; i < numAttachments; i++) { 5409 switch (attachments[i]) { 5410 case GL_COLOR: 5411 case GL_DEPTH: 5412 case GL_STENCIL: 5413 if (_mesa_is_user_fbo(fb)) 5414 goto invalid_enum; 5415 break; 5416 case GL_COLOR_ATTACHMENT0: 5417 case GL_DEPTH_ATTACHMENT: 5418 case GL_STENCIL_ATTACHMENT: 5419 if (_mesa_is_winsys_fbo(fb)) 5420 goto invalid_enum; 5421 break; 5422 default: 5423 goto invalid_enum; 5424 } 5425 } 5426 5427 discard_framebuffer(ctx, fb, numAttachments, attachments); 5428 5429 return; 5430 5431invalid_enum: 5432 _mesa_error(ctx, GL_INVALID_ENUM, 5433 "glDiscardFramebufferEXT(attachment %s)", 5434 _mesa_enum_to_string(attachments[i])); 5435} 5436 5437static void 5438sample_locations(struct gl_context *ctx, struct gl_framebuffer *fb, 5439 GLuint start, GLsizei count, const GLfloat *v, bool no_error, 5440 const char *name) 5441{ 5442 GLsizei i; 5443 5444 if (!no_error) { 5445 if (!ctx->Extensions.ARB_sample_locations) { 5446 _mesa_error(ctx, GL_INVALID_OPERATION, 5447 "%s not supported " 5448 "(ARB_sample_locations not available)", name); 5449 return; 5450 } 5451 5452 if (start + count > MAX_SAMPLE_LOCATION_TABLE_SIZE) { 5453 _mesa_error(ctx, GL_INVALID_VALUE, 5454 "%s(start+size > sample location table size)", name); 5455 return; 5456 } 5457 } 5458 5459 if (!fb->SampleLocationTable) { 5460 size_t size = MAX_SAMPLE_LOCATION_TABLE_SIZE * 2 * sizeof(GLfloat); 5461 fb->SampleLocationTable = malloc(size); 5462 if (!fb->SampleLocationTable) { 5463 _mesa_error(ctx, GL_OUT_OF_MEMORY, 5464 "Cannot allocate sample location table"); 5465 return; 5466 } 5467 for (i = 0; i < MAX_SAMPLE_LOCATION_TABLE_SIZE * 2; i++) 5468 fb->SampleLocationTable[i] = 0.5f; 5469 } 5470 5471 for (i = 0; i < count * 2; i++) { 5472 /* The ARB_sample_locations spec says: 5473 * 5474 * Sample locations outside of [0,1] result in undefined 5475 * behavior. 5476 * 5477 * To simplify driver implementations, we choose to clamp to 5478 * [0,1] and change NaN into 0.5. 5479 */ 5480 if (isnan(v[i]) || v[i] < 0.0f || v[i] > 1.0f) { 5481 static GLuint msg_id = 0; 5482 static const char* msg = "Invalid sample location specified"; 5483 _mesa_debug_get_id(&msg_id); 5484 5485 _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_UNDEFINED, 5486 msg_id, MESA_DEBUG_SEVERITY_HIGH, strlen(msg), msg); 5487 } 5488 5489 if (isnan(v[i])) 5490 fb->SampleLocationTable[start * 2 + i] = 0.5f; 5491 else 5492 fb->SampleLocationTable[start * 2 + i] = SATURATE(v[i]); 5493 } 5494 5495 if (fb == ctx->DrawBuffer) 5496 ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; 5497} 5498 5499void GLAPIENTRY 5500_mesa_FramebufferSampleLocationsfvARB(GLenum target, GLuint start, 5501 GLsizei count, const GLfloat *v) 5502{ 5503 struct gl_framebuffer *fb; 5504 5505 GET_CURRENT_CONTEXT(ctx); 5506 5507 fb = get_framebuffer_target(ctx, target); 5508 if (!fb) { 5509 _mesa_error(ctx, GL_INVALID_ENUM, 5510 "glFramebufferSampleLocationsfvARB(target %s)", 5511 _mesa_enum_to_string(target)); 5512 return; 5513 } 5514 5515 sample_locations(ctx, fb, start, count, v, false, 5516 "glFramebufferSampleLocationsfvARB"); 5517} 5518 5519void GLAPIENTRY 5520_mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer, GLuint start, 5521 GLsizei count, const GLfloat *v) 5522{ 5523 struct gl_framebuffer *fb; 5524 5525 GET_CURRENT_CONTEXT(ctx); 5526 5527 if (framebuffer) { 5528 fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, 5529 "glNamedFramebufferSampleLocationsfvARB"); 5530 if (!fb) 5531 return; 5532 } 5533 else 5534 fb = ctx->WinSysDrawBuffer; 5535 5536 sample_locations(ctx, fb, start, count, v, false, 5537 "glNamedFramebufferSampleLocationsfvARB"); 5538} 5539 5540void GLAPIENTRY 5541_mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target, GLuint start, 5542 GLsizei count, const GLfloat *v) 5543{ 5544 GET_CURRENT_CONTEXT(ctx); 5545 sample_locations(ctx, get_framebuffer_target(ctx, target), start, 5546 count, v, true, "glFramebufferSampleLocationsfvARB"); 5547} 5548 5549void GLAPIENTRY 5550_mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer, 5551 GLuint start, GLsizei count, 5552 const GLfloat *v) 5553{ 5554 GET_CURRENT_CONTEXT(ctx); 5555 sample_locations(ctx, _mesa_lookup_framebuffer(ctx, framebuffer), start, 5556 count, v, true, "glNamedFramebufferSampleLocationsfvARB"); 5557} 5558 5559void GLAPIENTRY 5560_mesa_EvaluateDepthValuesARB(void) 5561{ 5562 GET_CURRENT_CONTEXT(ctx); 5563 5564 if (!ctx->Extensions.ARB_sample_locations) { 5565 _mesa_error(ctx, GL_INVALID_OPERATION, 5566 "EvaluateDepthValuesARB not supported (neither " 5567 "ARB_sample_locations nor NV_sample_locations is available)"); 5568 return; 5569 } 5570 5571 if (ctx->Driver.EvaluateDepthValues) 5572 ctx->Driver.EvaluateDepthValues(ctx); 5573} 5574