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