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