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