Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.1
      4  *
      5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      6  * Copyright (C) 1999-2009  VMware, Inc.  All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice shall be included
     16  * in all copies or substantial portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     23  * CONNECTION WITH THE SOFTWARE OR THE USE OR 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 
     35 #include "buffers.h"
     36 #include "context.h"
     37 #include "enums.h"
     38 #include "fbobject.h"
     39 #include "formats.h"
     40 #include "framebuffer.h"
     41 #include "glformats.h"
     42 #include "hash.h"
     43 #include "macros.h"
     44 #include "mfeatures.h"
     45 #include "mtypes.h"
     46 #include "renderbuffer.h"
     47 #include "state.h"
     48 #include "teximage.h"
     49 #include "texobj.h"
     50 
     51 
     52 /** Set this to 1 to debug/log glBlitFramebuffer() calls */
     53 #define DEBUG_BLIT 0
     54 
     55 
     56 /**
     57  * Notes:
     58  *
     59  * None of the GL_EXT_framebuffer_object functions are compiled into
     60  * display lists.
     61  */
     62 
     63 
     64 
     65 /*
     66  * When glGenRender/FramebuffersEXT() is called we insert pointers to
     67  * these placeholder objects into the hash table.
     68  * Later, when the object ID is first bound, we replace the placeholder
     69  * with the real frame/renderbuffer.
     70  */
     71 static struct gl_framebuffer DummyFramebuffer;
     72 static struct gl_renderbuffer DummyRenderbuffer;
     73 
     74 /* We bind this framebuffer when applications pass a NULL
     75  * drawable/surface in make current. */
     76 static struct gl_framebuffer IncompleteFramebuffer;
     77 
     78 
     79 static void
     80 delete_dummy_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
     81 {
     82    /* no op */
     83 }
     84 
     85 static void
     86 delete_dummy_framebuffer(struct gl_framebuffer *fb)
     87 {
     88    /* no op */
     89 }
     90 
     91 
     92 void
     93 _mesa_init_fbobjects(struct gl_context *ctx)
     94 {
     95    _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
     96    _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
     97    _glthread_INIT_MUTEX(IncompleteFramebuffer.Mutex);
     98    DummyFramebuffer.Delete = delete_dummy_framebuffer;
     99    DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
    100    IncompleteFramebuffer.Delete = delete_dummy_framebuffer;
    101 }
    102 
    103 struct gl_framebuffer *
    104 _mesa_get_incomplete_framebuffer(void)
    105 {
    106    return &IncompleteFramebuffer;
    107 }
    108 
    109 /**
    110  * Helper routine for getting a gl_renderbuffer.
    111  */
    112 struct gl_renderbuffer *
    113 _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id)
    114 {
    115    struct gl_renderbuffer *rb;
    116 
    117    if (id == 0)
    118       return NULL;
    119 
    120    rb = (struct gl_renderbuffer *)
    121       _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
    122    return rb;
    123 }
    124 
    125 
    126 /**
    127  * Helper routine for getting a gl_framebuffer.
    128  */
    129 struct gl_framebuffer *
    130 _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id)
    131 {
    132    struct gl_framebuffer *fb;
    133 
    134    if (id == 0)
    135       return NULL;
    136 
    137    fb = (struct gl_framebuffer *)
    138       _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
    139    return fb;
    140 }
    141 
    142 
    143 /**
    144  * Mark the given framebuffer as invalid.  This will force the
    145  * test for framebuffer completeness to be done before the framebuffer
    146  * is used.
    147  */
    148 static void
    149 invalidate_framebuffer(struct gl_framebuffer *fb)
    150 {
    151    fb->_Status = 0; /* "indeterminate" */
    152 }
    153 
    154 
    155 /**
    156  * Return the gl_framebuffer object which corresponds to the given
    157  * framebuffer target, such as GL_DRAW_FRAMEBUFFER.
    158  * Check support for GL_EXT_framebuffer_blit to determine if certain
    159  * targets are legal.
    160  * \return gl_framebuffer pointer or NULL if target is illegal
    161  */
    162 static struct gl_framebuffer *
    163 get_framebuffer_target(struct gl_context *ctx, GLenum target)
    164 {
    165    switch (target) {
    166    case GL_DRAW_FRAMEBUFFER:
    167       return ctx->Extensions.EXT_framebuffer_blit && _mesa_is_desktop_gl(ctx)
    168 	 ? ctx->DrawBuffer : NULL;
    169    case GL_READ_FRAMEBUFFER:
    170       return ctx->Extensions.EXT_framebuffer_blit && _mesa_is_desktop_gl(ctx)
    171 	 ? ctx->ReadBuffer : NULL;
    172    case GL_FRAMEBUFFER_EXT:
    173       return ctx->DrawBuffer;
    174    default:
    175       return NULL;
    176    }
    177 }
    178 
    179 
    180 /**
    181  * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
    182  * gl_renderbuffer_attachment object.
    183  * This function is only used for user-created FB objects, not the
    184  * default / window-system FB object.
    185  * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
    186  * the depth buffer attachment point.
    187  */
    188 struct gl_renderbuffer_attachment *
    189 _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
    190                      GLenum attachment)
    191 {
    192    GLuint i;
    193 
    194    assert(_mesa_is_user_fbo(fb));
    195 
    196    switch (attachment) {
    197    case GL_COLOR_ATTACHMENT0_EXT:
    198    case GL_COLOR_ATTACHMENT1_EXT:
    199    case GL_COLOR_ATTACHMENT2_EXT:
    200    case GL_COLOR_ATTACHMENT3_EXT:
    201    case GL_COLOR_ATTACHMENT4_EXT:
    202    case GL_COLOR_ATTACHMENT5_EXT:
    203    case GL_COLOR_ATTACHMENT6_EXT:
    204    case GL_COLOR_ATTACHMENT7_EXT:
    205    case GL_COLOR_ATTACHMENT8_EXT:
    206    case GL_COLOR_ATTACHMENT9_EXT:
    207    case GL_COLOR_ATTACHMENT10_EXT:
    208    case GL_COLOR_ATTACHMENT11_EXT:
    209    case GL_COLOR_ATTACHMENT12_EXT:
    210    case GL_COLOR_ATTACHMENT13_EXT:
    211    case GL_COLOR_ATTACHMENT14_EXT:
    212    case GL_COLOR_ATTACHMENT15_EXT:
    213       /* Only OpenGL ES 1.x forbids color attachments other than
    214        * GL_COLOR_ATTACHMENT0.  For all other APIs the limit set by the
    215        * hardware is used.
    216        */
    217       i = attachment - GL_COLOR_ATTACHMENT0_EXT;
    218       if (i >= ctx->Const.MaxColorAttachments
    219 	  || (i > 0 && ctx->API == API_OPENGLES)) {
    220 	 return NULL;
    221       }
    222       return &fb->Attachment[BUFFER_COLOR0 + i];
    223    case GL_DEPTH_STENCIL_ATTACHMENT:
    224       if (!_mesa_is_desktop_gl(ctx))
    225 	 return NULL;
    226       /* fall-through */
    227    case GL_DEPTH_ATTACHMENT_EXT:
    228       return &fb->Attachment[BUFFER_DEPTH];
    229    case GL_STENCIL_ATTACHMENT_EXT:
    230       return &fb->Attachment[BUFFER_STENCIL];
    231    default:
    232       return NULL;
    233    }
    234 }
    235 
    236 
    237 /**
    238  * As above, but only used for getting attachments of the default /
    239  * window-system framebuffer (not user-created framebuffer objects).
    240  */
    241 static struct gl_renderbuffer_attachment *
    242 _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
    243                          GLenum attachment)
    244 {
    245    assert(_mesa_is_winsys_fbo(fb));
    246 
    247    switch (attachment) {
    248    case GL_FRONT_LEFT:
    249       return &fb->Attachment[BUFFER_FRONT_LEFT];
    250    case GL_FRONT_RIGHT:
    251       return &fb->Attachment[BUFFER_FRONT_RIGHT];
    252    case GL_BACK_LEFT:
    253       return &fb->Attachment[BUFFER_BACK_LEFT];
    254    case GL_BACK_RIGHT:
    255       return &fb->Attachment[BUFFER_BACK_RIGHT];
    256    case GL_AUX0:
    257       if (fb->Visual.numAuxBuffers == 1) {
    258          return &fb->Attachment[BUFFER_AUX0];
    259       }
    260       return NULL;
    261 
    262    /* Page 336 (page 352 of the PDF) of the OpenGL 3.0 spec says:
    263     *
    264     *     "If the default framebuffer is bound to target, then attachment must
    265     *     be one of FRONT LEFT, FRONT RIGHT, BACK LEFT, BACK RIGHT, or AUXi,
    266     *     identifying a color buffer; DEPTH, identifying the depth buffer; or
    267     *     STENCIL, identifying the stencil buffer."
    268     *
    269     * Revision #34 of the ARB_framebuffer_object spec has essentially the same
    270     * language.  However, revision #33 of the ARB_framebuffer_object spec
    271     * says:
    272     *
    273     *     "If the default framebuffer is bound to <target>, then <attachment>
    274     *     must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, AUXi,
    275     *     DEPTH_BUFFER, or STENCIL_BUFFER, identifying a color buffer, the
    276     *     depth buffer, or the stencil buffer, and <pname> may be
    277     *     FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE or
    278     *     FRAMEBUFFER_ATTACHMENT_OBJECT_NAME."
    279     *
    280     * The enum values for DEPTH_BUFFER and STENCIL_BUFFER have been removed
    281     * from glext.h, so shipping apps should not use those values.
    282     *
    283     * Note that neither EXT_framebuffer_object nor OES_framebuffer_object
    284     * support queries of the window system FBO.
    285     */
    286    case GL_DEPTH:
    287       return &fb->Attachment[BUFFER_DEPTH];
    288    case GL_STENCIL:
    289       return &fb->Attachment[BUFFER_STENCIL];
    290    default:
    291       return NULL;
    292    }
    293 }
    294 
    295 
    296 
    297 /**
    298  * Remove any texture or renderbuffer attached to the given attachment
    299  * point.  Update reference counts, etc.
    300  */
    301 void
    302 _mesa_remove_attachment(struct gl_context *ctx,
    303                         struct gl_renderbuffer_attachment *att)
    304 {
    305    if (att->Type == GL_TEXTURE) {
    306       ASSERT(att->Texture);
    307       if (ctx->Driver.FinishRenderTexture) {
    308          /* tell driver that we're done rendering to this texture. */
    309          ctx->Driver.FinishRenderTexture(ctx, att);
    310       }
    311       _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
    312       ASSERT(!att->Texture);
    313    }
    314    if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
    315       ASSERT(!att->Texture);
    316       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
    317       ASSERT(!att->Renderbuffer);
    318    }
    319    att->Type = GL_NONE;
    320    att->Complete = GL_TRUE;
    321 }
    322 
    323 
    324 /**
    325  * Bind a texture object to an attachment point.
    326  * The previous binding, if any, will be removed first.
    327  */
    328 void
    329 _mesa_set_texture_attachment(struct gl_context *ctx,
    330                              struct gl_framebuffer *fb,
    331                              struct gl_renderbuffer_attachment *att,
    332                              struct gl_texture_object *texObj,
    333                              GLenum texTarget, GLuint level, GLuint zoffset)
    334 {
    335    if (att->Texture == texObj) {
    336       /* re-attaching same texture */
    337       ASSERT(att->Type == GL_TEXTURE);
    338       if (ctx->Driver.FinishRenderTexture)
    339 	 ctx->Driver.FinishRenderTexture(ctx, att);
    340    }
    341    else {
    342       /* new attachment */
    343       if (ctx->Driver.FinishRenderTexture && att->Texture)
    344 	 ctx->Driver.FinishRenderTexture(ctx, att);
    345       _mesa_remove_attachment(ctx, att);
    346       att->Type = GL_TEXTURE;
    347       assert(!att->Texture);
    348       _mesa_reference_texobj(&att->Texture, texObj);
    349    }
    350 
    351    /* always update these fields */
    352    att->TextureLevel = level;
    353    att->CubeMapFace = _mesa_tex_target_to_face(texTarget);
    354    att->Zoffset = zoffset;
    355    att->Complete = GL_FALSE;
    356 
    357    if (_mesa_get_attachment_teximage(att)) {
    358       ctx->Driver.RenderTexture(ctx, fb, att);
    359    }
    360 
    361    invalidate_framebuffer(fb);
    362 }
    363 
    364 
    365 /**
    366  * Bind a renderbuffer to an attachment point.
    367  * The previous binding, if any, will be removed first.
    368  */
    369 void
    370 _mesa_set_renderbuffer_attachment(struct gl_context *ctx,
    371                                   struct gl_renderbuffer_attachment *att,
    372                                   struct gl_renderbuffer *rb)
    373 {
    374    /* XXX check if re-doing same attachment, exit early */
    375    _mesa_remove_attachment(ctx, att);
    376    att->Type = GL_RENDERBUFFER_EXT;
    377    att->Texture = NULL; /* just to be safe */
    378    att->Complete = GL_FALSE;
    379    _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
    380 }
    381 
    382 
    383 /**
    384  * Fallback for ctx->Driver.FramebufferRenderbuffer()
    385  * Attach a renderbuffer object to a framebuffer object.
    386  */
    387 void
    388 _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
    389                                struct gl_framebuffer *fb,
    390                                GLenum attachment, struct gl_renderbuffer *rb)
    391 {
    392    struct gl_renderbuffer_attachment *att;
    393 
    394    _glthread_LOCK_MUTEX(fb->Mutex);
    395 
    396    att = _mesa_get_attachment(ctx, fb, attachment);
    397    ASSERT(att);
    398    if (rb) {
    399       _mesa_set_renderbuffer_attachment(ctx, att, rb);
    400       if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
    401          /* do stencil attachment here (depth already done above) */
    402          att = _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
    403          assert(att);
    404          _mesa_set_renderbuffer_attachment(ctx, att, rb);
    405       }
    406       rb->AttachedAnytime = GL_TRUE;
    407    }
    408    else {
    409       _mesa_remove_attachment(ctx, att);
    410    }
    411 
    412    invalidate_framebuffer(fb);
    413 
    414    _glthread_UNLOCK_MUTEX(fb->Mutex);
    415 }
    416 
    417 
    418 /**
    419  * Fallback for ctx->Driver.ValidateFramebuffer()
    420  * Check if the renderbuffer's formats are supported by the software
    421  * renderer.
    422  * Drivers should probably override this.
    423  */
    424 void
    425 _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
    426 {
    427    gl_buffer_index buf;
    428    for (buf = 0; buf < BUFFER_COUNT; buf++) {
    429       const struct gl_renderbuffer *rb = fb->Attachment[buf].Renderbuffer;
    430       if (rb) {
    431          switch (rb->_BaseFormat) {
    432          case GL_ALPHA:
    433          case GL_LUMINANCE_ALPHA:
    434          case GL_LUMINANCE:
    435          case GL_INTENSITY:
    436          case GL_RED:
    437          case GL_RG:
    438             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
    439             return;
    440 
    441          default:
    442             switch (rb->Format) {
    443             /* XXX This list is likely incomplete. */
    444             case MESA_FORMAT_RGB9_E5_FLOAT:
    445                fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
    446                return;
    447             default:;
    448                /* render buffer format is supported by software rendering */
    449             }
    450          }
    451       }
    452    }
    453 }
    454 
    455 
    456 /**
    457  * For debug only.
    458  */
    459 static void
    460 att_incomplete(const char *msg)
    461 {
    462    if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
    463       _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
    464    }
    465 }
    466 
    467 
    468 /**
    469  * For debug only.
    470  */
    471 static void
    472 fbo_incomplete(const char *msg, int index)
    473 {
    474    if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
    475       _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
    476    }
    477 }
    478 
    479 
    480 /**
    481  * Is the given base format a legal format for a color renderbuffer?
    482  */
    483 GLboolean
    484 _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
    485 {
    486    switch (baseFormat) {
    487    case GL_RGB:
    488    case GL_RGBA:
    489       return GL_TRUE;
    490    case GL_LUMINANCE:
    491    case GL_LUMINANCE_ALPHA:
    492    case GL_INTENSITY:
    493    case GL_ALPHA:
    494       return ctx->Extensions.ARB_framebuffer_object;
    495    case GL_RED:
    496    case GL_RG:
    497       return ctx->Extensions.ARB_texture_rg;
    498    default:
    499       return GL_FALSE;
    500    }
    501 }
    502 
    503 
    504 /**
    505  * Is the given base format a legal format for a depth/stencil renderbuffer?
    506  */
    507 static GLboolean
    508 is_legal_depth_format(const struct gl_context *ctx, GLenum baseFormat)
    509 {
    510    switch (baseFormat) {
    511    case GL_DEPTH_COMPONENT:
    512    case GL_DEPTH_STENCIL_EXT:
    513       return GL_TRUE;
    514    default:
    515       return GL_FALSE;
    516    }
    517 }
    518 
    519 
    520 /**
    521  * Test if an attachment point is complete and update its Complete field.
    522  * \param format if GL_COLOR, this is a color attachment point,
    523  *               if GL_DEPTH, this is a depth component attachment point,
    524  *               if GL_STENCIL, this is a stencil component attachment point.
    525  */
    526 static void
    527 test_attachment_completeness(const struct gl_context *ctx, GLenum format,
    528                              struct gl_renderbuffer_attachment *att)
    529 {
    530    assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
    531 
    532    /* assume complete */
    533    att->Complete = GL_TRUE;
    534 
    535    /* Look for reasons why the attachment might be incomplete */
    536    if (att->Type == GL_TEXTURE) {
    537       const struct gl_texture_object *texObj = att->Texture;
    538       struct gl_texture_image *texImage;
    539       GLenum baseFormat;
    540 
    541       if (!texObj) {
    542          att_incomplete("no texobj");
    543          att->Complete = GL_FALSE;
    544          return;
    545       }
    546 
    547       texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
    548       if (!texImage) {
    549          att_incomplete("no teximage");
    550          att->Complete = GL_FALSE;
    551          return;
    552       }
    553       if (texImage->Width < 1 || texImage->Height < 1) {
    554          att_incomplete("teximage width/height=0");
    555          printf("texobj = %u\n", texObj->Name);
    556          printf("level = %d\n", att->TextureLevel);
    557          att->Complete = GL_FALSE;
    558          return;
    559       }
    560       if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
    561          att_incomplete("bad z offset");
    562          att->Complete = GL_FALSE;
    563          return;
    564       }
    565 
    566       baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
    567 
    568       if (format == GL_COLOR) {
    569          if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
    570             att_incomplete("bad format");
    571             att->Complete = GL_FALSE;
    572             return;
    573          }
    574          if (_mesa_is_format_compressed(texImage->TexFormat)) {
    575             att_incomplete("compressed internalformat");
    576             att->Complete = GL_FALSE;
    577             return;
    578          }
    579       }
    580       else if (format == GL_DEPTH) {
    581          if (baseFormat == GL_DEPTH_COMPONENT) {
    582             /* OK */
    583          }
    584          else if (ctx->Extensions.EXT_packed_depth_stencil &&
    585                   ctx->Extensions.ARB_depth_texture &&
    586                   baseFormat == GL_DEPTH_STENCIL_EXT) {
    587             /* OK */
    588          }
    589          else {
    590             att->Complete = GL_FALSE;
    591             att_incomplete("bad depth format");
    592             return;
    593          }
    594       }
    595       else {
    596          ASSERT(format == GL_STENCIL);
    597          if (ctx->Extensions.EXT_packed_depth_stencil &&
    598              ctx->Extensions.ARB_depth_texture &&
    599              baseFormat == GL_DEPTH_STENCIL_EXT) {
    600             /* OK */
    601          }
    602          else {
    603             /* no such thing as stencil-only textures */
    604             att_incomplete("illegal stencil texture");
    605             att->Complete = GL_FALSE;
    606             return;
    607          }
    608       }
    609    }
    610    else if (att->Type == GL_RENDERBUFFER_EXT) {
    611       const GLenum baseFormat =
    612          _mesa_get_format_base_format(att->Renderbuffer->Format);
    613 
    614       ASSERT(att->Renderbuffer);
    615       if (!att->Renderbuffer->InternalFormat ||
    616           att->Renderbuffer->Width < 1 ||
    617           att->Renderbuffer->Height < 1) {
    618          att_incomplete("0x0 renderbuffer");
    619          att->Complete = GL_FALSE;
    620          return;
    621       }
    622       if (format == GL_COLOR) {
    623          if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
    624             att_incomplete("bad renderbuffer color format");
    625             att->Complete = GL_FALSE;
    626             return;
    627          }
    628       }
    629       else if (format == GL_DEPTH) {
    630          if (baseFormat == GL_DEPTH_COMPONENT) {
    631             /* OK */
    632          }
    633          else if (ctx->Extensions.EXT_packed_depth_stencil &&
    634                   baseFormat == GL_DEPTH_STENCIL_EXT) {
    635             /* OK */
    636          }
    637          else {
    638             att_incomplete("bad renderbuffer depth format");
    639             att->Complete = GL_FALSE;
    640             return;
    641          }
    642       }
    643       else {
    644          assert(format == GL_STENCIL);
    645          if (baseFormat == GL_STENCIL_INDEX) {
    646             /* OK */
    647          }
    648          else if (ctx->Extensions.EXT_packed_depth_stencil &&
    649                   baseFormat == GL_DEPTH_STENCIL_EXT) {
    650             /* OK */
    651          }
    652          else {
    653             att->Complete = GL_FALSE;
    654             att_incomplete("bad renderbuffer stencil format");
    655             return;
    656          }
    657       }
    658    }
    659    else {
    660       ASSERT(att->Type == GL_NONE);
    661       /* complete */
    662       return;
    663    }
    664 }
    665 
    666 
    667 /**
    668  * Test if the given framebuffer object is complete and update its
    669  * Status field with the results.
    670  * Calls the ctx->Driver.ValidateFramebuffer() function to allow the
    671  * driver to make hardware-specific validation/completeness checks.
    672  * Also update the framebuffer's Width and Height fields if the
    673  * framebuffer is complete.
    674  */
    675 void
    676 _mesa_test_framebuffer_completeness(struct gl_context *ctx,
    677                                     struct gl_framebuffer *fb)
    678 {
    679    GLuint numImages;
    680    GLenum intFormat = GL_NONE; /* color buffers' internal format */
    681    GLuint minWidth = ~0, minHeight = ~0, maxWidth = 0, maxHeight = 0;
    682    GLint numSamples = -1;
    683    GLint i;
    684    GLuint j;
    685 
    686    assert(_mesa_is_user_fbo(fb));
    687 
    688    /* we're changing framebuffer fields here */
    689    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
    690 
    691    numImages = 0;
    692    fb->Width = 0;
    693    fb->Height = 0;
    694 
    695    /* Start at -2 to more easily loop over all attachment points.
    696     *  -2: depth buffer
    697     *  -1: stencil buffer
    698     * >=0: color buffer
    699     */
    700    for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
    701       struct gl_renderbuffer_attachment *att;
    702       GLenum f;
    703       gl_format attFormat;
    704 
    705       /*
    706        * XXX for ARB_fbo, only check color buffers that are named by
    707        * GL_READ_BUFFER and GL_DRAW_BUFFERi.
    708        */
    709 
    710       /* check for attachment completeness
    711        */
    712       if (i == -2) {
    713          att = &fb->Attachment[BUFFER_DEPTH];
    714          test_attachment_completeness(ctx, GL_DEPTH, att);
    715          if (!att->Complete) {
    716             fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
    717             fbo_incomplete("depth attachment incomplete", -1);
    718             return;
    719          }
    720       }
    721       else if (i == -1) {
    722          att = &fb->Attachment[BUFFER_STENCIL];
    723          test_attachment_completeness(ctx, GL_STENCIL, att);
    724          if (!att->Complete) {
    725             fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
    726             fbo_incomplete("stencil attachment incomplete", -1);
    727             return;
    728          }
    729       }
    730       else {
    731          att = &fb->Attachment[BUFFER_COLOR0 + i];
    732          test_attachment_completeness(ctx, GL_COLOR, att);
    733          if (!att->Complete) {
    734             fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
    735             fbo_incomplete("color attachment incomplete", i);
    736             return;
    737          }
    738       }
    739 
    740       /* get width, height, format of the renderbuffer/texture
    741        */
    742       if (att->Type == GL_TEXTURE) {
    743          const struct gl_texture_image *texImg =
    744             _mesa_get_attachment_teximage(att);
    745          minWidth = MIN2(minWidth, texImg->Width);
    746          maxWidth = MAX2(maxWidth, texImg->Width);
    747          minHeight = MIN2(minHeight, texImg->Height);
    748          maxHeight = MAX2(maxHeight, texImg->Height);
    749          f = texImg->_BaseFormat;
    750          attFormat = texImg->TexFormat;
    751          numImages++;
    752          if (!_mesa_is_legal_color_format(ctx, f) &&
    753              !is_legal_depth_format(ctx, f)) {
    754             fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
    755             fbo_incomplete("texture attachment incomplete", -1);
    756             return;
    757          }
    758       }
    759       else if (att->Type == GL_RENDERBUFFER_EXT) {
    760          minWidth = MIN2(minWidth, att->Renderbuffer->Width);
    761          maxWidth = MAX2(minWidth, att->Renderbuffer->Width);
    762          minHeight = MIN2(minHeight, att->Renderbuffer->Height);
    763          maxHeight = MAX2(minHeight, att->Renderbuffer->Height);
    764          f = att->Renderbuffer->InternalFormat;
    765          attFormat = att->Renderbuffer->Format;
    766          numImages++;
    767       }
    768       else {
    769          assert(att->Type == GL_NONE);
    770          continue;
    771       }
    772 
    773       if (att->Renderbuffer && numSamples < 0) {
    774          /* first buffer */
    775          numSamples = att->Renderbuffer->NumSamples;
    776       }
    777 
    778       /* check if integer color */
    779       fb->_IntegerColor = _mesa_is_format_integer_color(attFormat);
    780 
    781       /* Error-check width, height, format, samples
    782        */
    783       if (numImages == 1) {
    784          /* save format, num samples */
    785          if (i >= 0) {
    786             intFormat = f;
    787          }
    788       }
    789       else {
    790          if (!ctx->Extensions.ARB_framebuffer_object) {
    791             /* check that width, height, format are same */
    792             if (minWidth != maxWidth || minHeight != maxHeight) {
    793                fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
    794                fbo_incomplete("width or height mismatch", -1);
    795                return;
    796             }
    797             /* check that all color buffers are the same format */
    798             if (intFormat != GL_NONE && f != intFormat) {
    799                fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
    800                fbo_incomplete("format mismatch", -1);
    801                return;
    802             }
    803          }
    804          if (att->Renderbuffer &&
    805              att->Renderbuffer->NumSamples != numSamples) {
    806             fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
    807             fbo_incomplete("inconsistant number of samples", i);
    808             return;
    809          }
    810       }
    811 
    812       /* Check that the format is valid. (MESA_FORMAT_NONE means unsupported)
    813        */
    814       if (att->Type == GL_RENDERBUFFER &&
    815           att->Renderbuffer->Format == MESA_FORMAT_NONE) {
    816          fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
    817          fbo_incomplete("unsupported renderbuffer format", i);
    818          return;
    819       }
    820    }
    821 
    822 #if FEATURE_GL
    823    if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
    824       /* Check that all DrawBuffers are present */
    825       for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
    826 	 if (fb->ColorDrawBuffer[j] != GL_NONE) {
    827 	    const struct gl_renderbuffer_attachment *att
    828 	       = _mesa_get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
    829 	    assert(att);
    830 	    if (att->Type == GL_NONE) {
    831 	       fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
    832 	       fbo_incomplete("missing drawbuffer", j);
    833 	       return;
    834 	    }
    835 	 }
    836       }
    837 
    838       /* Check that the ReadBuffer is present */
    839       if (fb->ColorReadBuffer != GL_NONE) {
    840 	 const struct gl_renderbuffer_attachment *att
    841 	    = _mesa_get_attachment(ctx, fb, fb->ColorReadBuffer);
    842 	 assert(att);
    843 	 if (att->Type == GL_NONE) {
    844 	    fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
    845             fbo_incomplete("missing readbuffer", -1);
    846 	    return;
    847 	 }
    848       }
    849    }
    850 #else
    851    (void) j;
    852 #endif
    853 
    854    if (numImages == 0) {
    855       fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
    856       fbo_incomplete("no attachments", -1);
    857       return;
    858    }
    859 
    860    /* Provisionally set status = COMPLETE ... */
    861    fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
    862 
    863    /* ... but the driver may say the FB is incomplete.
    864     * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED
    865     * if anything.
    866     */
    867    if (ctx->Driver.ValidateFramebuffer) {
    868       ctx->Driver.ValidateFramebuffer(ctx, fb);
    869       if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    870          fbo_incomplete("driver marked FBO as incomplete", -1);
    871       }
    872    }
    873 
    874    if (fb->_Status == GL_FRAMEBUFFER_COMPLETE_EXT) {
    875       /*
    876        * Note that if ARB_framebuffer_object is supported and the attached
    877        * renderbuffers/textures are different sizes, the framebuffer
    878        * width/height will be set to the smallest width/height.
    879        */
    880       fb->Width = minWidth;
    881       fb->Height = minHeight;
    882 
    883       /* finally, update the visual info for the framebuffer */
    884       _mesa_update_framebuffer_visual(ctx, fb);
    885    }
    886 }
    887 
    888 
    889 GLboolean GLAPIENTRY
    890 _mesa_IsRenderbufferEXT(GLuint renderbuffer)
    891 {
    892    GET_CURRENT_CONTEXT(ctx);
    893    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
    894    if (renderbuffer) {
    895       struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
    896       if (rb != NULL && rb != &DummyRenderbuffer)
    897          return GL_TRUE;
    898    }
    899    return GL_FALSE;
    900 }
    901 
    902 
    903 void GLAPIENTRY
    904 _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
    905 {
    906    struct gl_renderbuffer *newRb;
    907    GET_CURRENT_CONTEXT(ctx);
    908 
    909    ASSERT_OUTSIDE_BEGIN_END(ctx);
    910 
    911    if (target != GL_RENDERBUFFER_EXT) {
    912       _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
    913       return;
    914    }
    915 
    916    /* No need to flush here since the render buffer binding has no
    917     * effect on rendering state.
    918     */
    919 
    920    if (renderbuffer) {
    921       newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
    922       if (newRb == &DummyRenderbuffer) {
    923          /* ID was reserved, but no real renderbuffer object made yet */
    924          newRb = NULL;
    925       }
    926       else if (!newRb && ctx->Extensions.ARB_framebuffer_object) {
    927          /* All RB IDs must be Gen'd */
    928          _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)");
    929          return;
    930       }
    931 
    932       if (!newRb) {
    933 	 /* create new renderbuffer object */
    934 	 newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
    935 	 if (!newRb) {
    936 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
    937 	    return;
    938 	 }
    939          ASSERT(newRb->AllocStorage);
    940          _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
    941          newRb->RefCount = 1; /* referenced by hash table */
    942       }
    943    }
    944    else {
    945       newRb = NULL;
    946    }
    947 
    948    ASSERT(newRb != &DummyRenderbuffer);
    949 
    950    _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
    951 }
    952 
    953 
    954 /**
    955  * If the given renderbuffer is anywhere attached to the framebuffer, detach
    956  * the renderbuffer.
    957  * This is used when a renderbuffer object is deleted.
    958  * The spec calls for unbinding.
    959  */
    960 static void
    961 detach_renderbuffer(struct gl_context *ctx,
    962                     struct gl_framebuffer *fb,
    963                     struct gl_renderbuffer *rb)
    964 {
    965    GLuint i;
    966    for (i = 0; i < BUFFER_COUNT; i++) {
    967       if (fb->Attachment[i].Renderbuffer == rb) {
    968          _mesa_remove_attachment(ctx, &fb->Attachment[i]);
    969       }
    970    }
    971    invalidate_framebuffer(fb);
    972 }
    973 
    974 
    975 void GLAPIENTRY
    976 _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
    977 {
    978    GLint i;
    979    GET_CURRENT_CONTEXT(ctx);
    980 
    981    ASSERT_OUTSIDE_BEGIN_END(ctx);
    982    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
    983 
    984    for (i = 0; i < n; i++) {
    985       if (renderbuffers[i] > 0) {
    986 	 struct gl_renderbuffer *rb;
    987 	 rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
    988 	 if (rb) {
    989             /* check if deleting currently bound renderbuffer object */
    990             if (rb == ctx->CurrentRenderbuffer) {
    991                /* bind default */
    992                ASSERT(rb->RefCount >= 2);
    993                _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    994             }
    995 
    996             if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
    997                detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
    998             }
    999             if (_mesa_is_user_fbo(ctx->ReadBuffer)
   1000                 && ctx->ReadBuffer != ctx->DrawBuffer) {
   1001                detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
   1002             }
   1003 
   1004 	    /* Remove from hash table immediately, to free the ID.
   1005              * But the object will not be freed until it's no longer
   1006              * referenced anywhere else.
   1007              */
   1008 	    _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
   1009 
   1010             if (rb != &DummyRenderbuffer) {
   1011                /* no longer referenced by hash table */
   1012                _mesa_reference_renderbuffer(&rb, NULL);
   1013 	    }
   1014 	 }
   1015       }
   1016    }
   1017 }
   1018 
   1019 
   1020 void GLAPIENTRY
   1021 _mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
   1022 {
   1023    GET_CURRENT_CONTEXT(ctx);
   1024    GLuint first;
   1025    GLint i;
   1026 
   1027    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1028 
   1029    if (n < 0) {
   1030       _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
   1031       return;
   1032    }
   1033 
   1034    if (!renderbuffers)
   1035       return;
   1036 
   1037    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
   1038 
   1039    for (i = 0; i < n; i++) {
   1040       GLuint name = first + i;
   1041       renderbuffers[i] = name;
   1042       /* insert dummy placeholder into hash table */
   1043       _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
   1044       _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
   1045       _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
   1046    }
   1047 }
   1048 
   1049 
   1050 /**
   1051  * Given an internal format token for a render buffer, return the
   1052  * corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX,
   1053  * GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL_EXT, GL_ALPHA, GL_LUMINANCE,
   1054  * GL_LUMINANCE_ALPHA, GL_INTENSITY, etc).
   1055  *
   1056  * This is similar to _mesa_base_tex_format() but the set of valid
   1057  * internal formats is different.
   1058  *
   1059  * Note that even if a format is determined to be legal here, validation
   1060  * of the FBO may fail if the format is not supported by the driver/GPU.
   1061  *
   1062  * \param internalFormat  as passed to glRenderbufferStorage()
   1063  * \return the base internal format, or 0 if internalFormat is illegal
   1064  */
   1065 GLenum
   1066 _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
   1067 {
   1068    /*
   1069     * Notes: some formats such as alpha, luminance, etc. were added
   1070     * with GL_ARB_framebuffer_object.
   1071     */
   1072    switch (internalFormat) {
   1073    case GL_ALPHA:
   1074    case GL_ALPHA4:
   1075    case GL_ALPHA8:
   1076    case GL_ALPHA12:
   1077    case GL_ALPHA16:
   1078       return ctx->API == API_OPENGL && ctx->Extensions.ARB_framebuffer_object
   1079          ? GL_ALPHA : 0;
   1080    case GL_LUMINANCE:
   1081    case GL_LUMINANCE4:
   1082    case GL_LUMINANCE8:
   1083    case GL_LUMINANCE12:
   1084    case GL_LUMINANCE16:
   1085       return ctx->API == API_OPENGL && ctx->Extensions.ARB_framebuffer_object
   1086          ? GL_LUMINANCE : 0;
   1087    case GL_LUMINANCE_ALPHA:
   1088    case GL_LUMINANCE4_ALPHA4:
   1089    case GL_LUMINANCE6_ALPHA2:
   1090    case GL_LUMINANCE8_ALPHA8:
   1091    case GL_LUMINANCE12_ALPHA4:
   1092    case GL_LUMINANCE12_ALPHA12:
   1093    case GL_LUMINANCE16_ALPHA16:
   1094       return ctx->API == API_OPENGL && ctx->Extensions.ARB_framebuffer_object
   1095          ? GL_LUMINANCE_ALPHA : 0;
   1096    case GL_INTENSITY:
   1097    case GL_INTENSITY4:
   1098    case GL_INTENSITY8:
   1099    case GL_INTENSITY12:
   1100    case GL_INTENSITY16:
   1101       return ctx->API == API_OPENGL && ctx->Extensions.ARB_framebuffer_object
   1102          ? GL_INTENSITY : 0;
   1103    case GL_RGB8:
   1104       return GL_RGB;
   1105    case GL_RGB:
   1106    case GL_R3_G3_B2:
   1107    case GL_RGB4:
   1108    case GL_RGB5:
   1109    case GL_RGB10:
   1110    case GL_RGB12:
   1111    case GL_RGB16:
   1112       return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0;
   1113    case GL_SRGB8_EXT:
   1114       return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGB : 0;
   1115    case GL_RGBA4:
   1116    case GL_RGB5_A1:
   1117    case GL_RGBA8:
   1118       return GL_RGBA;
   1119    case GL_RGBA:
   1120    case GL_RGBA2:
   1121    case GL_RGBA12:
   1122    case GL_RGBA16:
   1123       return _mesa_is_desktop_gl(ctx) ? GL_RGBA : 0;
   1124    case GL_RGB10_A2:
   1125    case GL_SRGB8_ALPHA8_EXT:
   1126       return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGBA : 0;
   1127    case GL_STENCIL_INDEX:
   1128    case GL_STENCIL_INDEX1_EXT:
   1129    case GL_STENCIL_INDEX4_EXT:
   1130    case GL_STENCIL_INDEX16_EXT:
   1131       /* There are extensions for GL_STENCIL_INDEX1 and GL_STENCIL_INDEX4 in
   1132        * OpenGL ES, but Mesa does not currently support them.
   1133        */
   1134       return _mesa_is_desktop_gl(ctx) ? GL_STENCIL_INDEX : 0;
   1135    case GL_STENCIL_INDEX8_EXT:
   1136       return GL_STENCIL_INDEX;
   1137    case GL_DEPTH_COMPONENT:
   1138    case GL_DEPTH_COMPONENT32:
   1139       return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_COMPONENT : 0;
   1140    case GL_DEPTH_COMPONENT16:
   1141    case GL_DEPTH_COMPONENT24:
   1142       return GL_DEPTH_COMPONENT;
   1143    case GL_DEPTH_STENCIL_EXT:
   1144       return _mesa_is_desktop_gl(ctx)
   1145          && ctx->Extensions.EXT_packed_depth_stencil
   1146          ? GL_DEPTH_STENCIL_EXT : 0;
   1147    case GL_DEPTH24_STENCIL8_EXT:
   1148       return ctx->Extensions.EXT_packed_depth_stencil
   1149          ? GL_DEPTH_STENCIL_EXT : 0;
   1150    case GL_DEPTH_COMPONENT32F:
   1151       return ctx->Version >= 30
   1152          || (ctx->API == API_OPENGL && ctx->Extensions.ARB_depth_buffer_float)
   1153          ? GL_DEPTH_COMPONENT : 0;
   1154    case GL_DEPTH32F_STENCIL8:
   1155       return ctx->Version >= 30
   1156          || (ctx->API == API_OPENGL && ctx->Extensions.ARB_depth_buffer_float)
   1157          ? GL_DEPTH_STENCIL : 0;
   1158    case GL_RED:
   1159    case GL_R16:
   1160       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_rg
   1161          ? GL_RED : 0;
   1162    case GL_R8:
   1163       return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg
   1164          ? GL_RED : 0;
   1165    case GL_RG:
   1166    case GL_RG16:
   1167       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_rg
   1168          ? GL_RG : 0;
   1169    case GL_RG8:
   1170       return ctx->API != API_OPENGLES && ctx->Extensions.ARB_texture_rg
   1171          ? GL_RG : 0;
   1172    /* signed normalized texture formats */
   1173    case GL_R8_SNORM:
   1174       return ctx->Version >= 30
   1175          || (ctx->API == API_OPENGL && ctx->Extensions.EXT_texture_snorm)
   1176          ? GL_RED : 0;
   1177    case GL_RED_SNORM:
   1178    case GL_R16_SNORM:
   1179       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
   1180          ? GL_RED : 0;
   1181    case GL_RG8_SNORM:
   1182       return ctx->Version >= 30
   1183          || (ctx->API == API_OPENGL && ctx->Extensions.EXT_texture_snorm)
   1184          ? GL_RG : 0;
   1185    case GL_RG_SNORM:
   1186    case GL_RG16_SNORM:
   1187       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
   1188          ? GL_RG : 0;
   1189    case GL_RGB8_SNORM:
   1190       return ctx->Version >= 30
   1191          || (ctx->API == API_OPENGL && ctx->Extensions.EXT_texture_snorm)
   1192          ? GL_RGB : 0;
   1193    case GL_RGB_SNORM:
   1194    case GL_RGB16_SNORM:
   1195       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
   1196          ? GL_RGB : 0;
   1197    case GL_RGBA8_SNORM:
   1198       return ctx->Version >= 30
   1199          || (ctx->API == API_OPENGL && ctx->Extensions.EXT_texture_snorm)
   1200          ? GL_RGBA : 0;
   1201    case GL_RGBA_SNORM:
   1202    case GL_RGBA16_SNORM:
   1203       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm
   1204          ? GL_RGBA : 0;
   1205    case GL_ALPHA_SNORM:
   1206    case GL_ALPHA8_SNORM:
   1207    case GL_ALPHA16_SNORM:
   1208       return ctx->API == API_OPENGL &&
   1209              ctx->Extensions.EXT_texture_snorm &&
   1210              ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
   1211    case GL_LUMINANCE_SNORM:
   1212    case GL_LUMINANCE8_SNORM:
   1213    case GL_LUMINANCE16_SNORM:
   1214       return ctx->API == API_OPENGL &&
   1215              ctx->Extensions.EXT_texture_snorm &&
   1216              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
   1217    case GL_LUMINANCE_ALPHA_SNORM:
   1218    case GL_LUMINANCE8_ALPHA8_SNORM:
   1219    case GL_LUMINANCE16_ALPHA16_SNORM:
   1220       return ctx->API == API_OPENGL &&
   1221              ctx->Extensions.EXT_texture_snorm &&
   1222              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
   1223    case GL_INTENSITY_SNORM:
   1224    case GL_INTENSITY8_SNORM:
   1225    case GL_INTENSITY16_SNORM:
   1226       return ctx->API == API_OPENGL &&
   1227              ctx->Extensions.EXT_texture_snorm &&
   1228              ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
   1229    case GL_R16F:
   1230    case GL_R32F:
   1231       return ctx->Version >= 30
   1232          || (ctx->API == API_OPENGL &&
   1233              ctx->Extensions.ARB_texture_rg &&
   1234              ctx->Extensions.ARB_texture_float) ? GL_RED : 0;
   1235    case GL_RG16F:
   1236    case GL_RG32F:
   1237       return ctx->Version >= 30
   1238          || (ctx->API == API_OPENGL &&
   1239              ctx->Extensions.ARB_texture_rg &&
   1240              ctx->Extensions.ARB_texture_float) ? GL_RG : 0;
   1241    case GL_RGB16F:
   1242    case GL_RGB32F:
   1243       return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float)
   1244          || _mesa_is_gles3(ctx)
   1245          ? GL_RGB : 0;
   1246    case GL_RGBA16F:
   1247    case GL_RGBA32F:
   1248       return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float)
   1249          || _mesa_is_gles3(ctx)
   1250          ? GL_RGBA : 0;
   1251    case GL_ALPHA16F_ARB:
   1252    case GL_ALPHA32F_ARB:
   1253       return ctx->API == API_OPENGL &&
   1254              ctx->Extensions.ARB_texture_float &&
   1255              ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
   1256    case GL_LUMINANCE16F_ARB:
   1257    case GL_LUMINANCE32F_ARB:
   1258       return ctx->API == API_OPENGL &&
   1259              ctx->Extensions.ARB_texture_float &&
   1260              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
   1261    case GL_LUMINANCE_ALPHA16F_ARB:
   1262    case GL_LUMINANCE_ALPHA32F_ARB:
   1263       return ctx->API == API_OPENGL &&
   1264              ctx->Extensions.ARB_texture_float &&
   1265              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
   1266    case GL_INTENSITY16F_ARB:
   1267    case GL_INTENSITY32F_ARB:
   1268       return ctx->API == API_OPENGL &&
   1269              ctx->Extensions.ARB_texture_float &&
   1270              ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
   1271    case GL_RGB9_E5:
   1272       return (_mesa_is_desktop_gl(ctx)
   1273               && ctx->Extensions.EXT_texture_shared_exponent)
   1274          || _mesa_is_gles3(ctx) ? GL_RGB : 0;
   1275    case GL_R11F_G11F_B10F:
   1276       return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float)
   1277          || _mesa_is_gles3(ctx) ? GL_RGB : 0;
   1278 
   1279    case GL_RGBA8UI_EXT:
   1280    case GL_RGBA16UI_EXT:
   1281    case GL_RGBA32UI_EXT:
   1282    case GL_RGBA8I_EXT:
   1283    case GL_RGBA16I_EXT:
   1284    case GL_RGBA32I_EXT:
   1285       return ctx->Version >= 30
   1286          || (_mesa_is_desktop_gl(ctx) &&
   1287              ctx->Extensions.EXT_texture_integer) ? GL_RGBA : 0;
   1288 
   1289    case GL_RGB8UI_EXT:
   1290    case GL_RGB16UI_EXT:
   1291    case GL_RGB32UI_EXT:
   1292    case GL_RGB8I_EXT:
   1293    case GL_RGB16I_EXT:
   1294    case GL_RGB32I_EXT:
   1295       return ctx->Version >= 30
   1296          || (_mesa_is_desktop_gl(ctx) &&
   1297              ctx->Extensions.EXT_texture_integer) ? GL_RGB : 0;
   1298 
   1299    case GL_R8UI:
   1300    case GL_R8I:
   1301    case GL_R16UI:
   1302    case GL_R16I:
   1303    case GL_R32UI:
   1304    case GL_R32I:
   1305       return ctx->Version >= 30
   1306          || (_mesa_is_desktop_gl(ctx) &&
   1307              ctx->Extensions.ARB_texture_rg &&
   1308              ctx->Extensions.EXT_texture_integer) ? GL_RED : 0;
   1309 
   1310    case GL_RG8UI:
   1311    case GL_RG8I:
   1312    case GL_RG16UI:
   1313    case GL_RG16I:
   1314    case GL_RG32UI:
   1315    case GL_RG32I:
   1316       return ctx->Version >= 30
   1317          || (_mesa_is_desktop_gl(ctx) &&
   1318              ctx->Extensions.ARB_texture_rg &&
   1319              ctx->Extensions.EXT_texture_integer) ? GL_RG : 0;
   1320 
   1321    case GL_INTENSITY8I_EXT:
   1322    case GL_INTENSITY8UI_EXT:
   1323    case GL_INTENSITY16I_EXT:
   1324    case GL_INTENSITY16UI_EXT:
   1325    case GL_INTENSITY32I_EXT:
   1326    case GL_INTENSITY32UI_EXT:
   1327       return ctx->API == API_OPENGL &&
   1328              ctx->Extensions.EXT_texture_integer &&
   1329              ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0;
   1330 
   1331    case GL_LUMINANCE8I_EXT:
   1332    case GL_LUMINANCE8UI_EXT:
   1333    case GL_LUMINANCE16I_EXT:
   1334    case GL_LUMINANCE16UI_EXT:
   1335    case GL_LUMINANCE32I_EXT:
   1336    case GL_LUMINANCE32UI_EXT:
   1337       return ctx->API == API_OPENGL &&
   1338              ctx->Extensions.EXT_texture_integer &&
   1339              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0;
   1340 
   1341    case GL_LUMINANCE_ALPHA8I_EXT:
   1342    case GL_LUMINANCE_ALPHA8UI_EXT:
   1343    case GL_LUMINANCE_ALPHA16I_EXT:
   1344    case GL_LUMINANCE_ALPHA16UI_EXT:
   1345    case GL_LUMINANCE_ALPHA32I_EXT:
   1346    case GL_LUMINANCE_ALPHA32UI_EXT:
   1347       return ctx->API == API_OPENGL &&
   1348              ctx->Extensions.EXT_texture_integer &&
   1349              ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0;
   1350 
   1351    case GL_ALPHA8I_EXT:
   1352    case GL_ALPHA8UI_EXT:
   1353    case GL_ALPHA16I_EXT:
   1354    case GL_ALPHA16UI_EXT:
   1355    case GL_ALPHA32I_EXT:
   1356    case GL_ALPHA32UI_EXT:
   1357       return ctx->API == API_OPENGL &&
   1358              ctx->Extensions.EXT_texture_integer &&
   1359              ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
   1360 
   1361    case GL_RGB10_A2UI:
   1362       return (_mesa_is_desktop_gl(ctx) &&
   1363               ctx->Extensions.ARB_texture_rgb10_a2ui)
   1364          || _mesa_is_gles3(ctx) ? GL_RGBA : 0;
   1365 
   1366    case GL_RGB565:
   1367       return _mesa_is_gles(ctx) || ctx->Extensions.ARB_ES2_compatibility
   1368          ? GL_RGB : 0;
   1369    default:
   1370       return 0;
   1371    }
   1372 }
   1373 
   1374 
   1375 /**
   1376  * Invalidate a renderbuffer attachment.  Called from _mesa_HashWalk().
   1377  */
   1378 static void
   1379 invalidate_rb(GLuint key, void *data, void *userData)
   1380 {
   1381    struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
   1382    struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
   1383 
   1384    /* If this is a user-created FBO */
   1385    if (_mesa_is_user_fbo(fb)) {
   1386       GLuint i;
   1387       for (i = 0; i < BUFFER_COUNT; i++) {
   1388          struct gl_renderbuffer_attachment *att = fb->Attachment + i;
   1389          if (att->Type == GL_RENDERBUFFER &&
   1390              att->Renderbuffer == rb) {
   1391             /* Mark fb status as indeterminate to force re-validation */
   1392             fb->_Status = 0;
   1393             return;
   1394          }
   1395       }
   1396    }
   1397 }
   1398 
   1399 
   1400 /** sentinal value, see below */
   1401 #define NO_SAMPLES 1000
   1402 
   1403 
   1404 /**
   1405  * Helper function used by _mesa_RenderbufferStorageEXT() and
   1406  * _mesa_RenderbufferStorageMultisample().
   1407  * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorageEXT().
   1408  */
   1409 static void
   1410 renderbuffer_storage(GLenum target, GLenum internalFormat,
   1411                      GLsizei width, GLsizei height, GLsizei samples)
   1412 {
   1413    const char *func = samples == NO_SAMPLES ?
   1414       "glRenderbufferStorage" : "RenderbufferStorageMultisample";
   1415    struct gl_renderbuffer *rb;
   1416    GLenum baseFormat;
   1417    GET_CURRENT_CONTEXT(ctx);
   1418 
   1419    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1420 
   1421    if (target != GL_RENDERBUFFER_EXT) {
   1422       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
   1423       return;
   1424    }
   1425 
   1426    baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
   1427    if (baseFormat == 0) {
   1428       _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
   1429       return;
   1430    }
   1431 
   1432    if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
   1433       _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
   1434       return;
   1435    }
   1436 
   1437    if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
   1438       _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func);
   1439       return;
   1440    }
   1441 
   1442    if (samples == NO_SAMPLES) {
   1443       /* NumSamples == 0 indicates non-multisampling */
   1444       samples = 0;
   1445    }
   1446    else if (samples > (GLsizei) ctx->Const.MaxSamples) {
   1447       /* note: driver may choose to use more samples than what's requested */
   1448       _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
   1449       return;
   1450    }
   1451 
   1452    rb = ctx->CurrentRenderbuffer;
   1453    if (!rb) {
   1454       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
   1455       return;
   1456    }
   1457 
   1458    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   1459 
   1460    if (rb->InternalFormat == internalFormat &&
   1461        rb->Width == (GLuint) width &&
   1462        rb->Height == (GLuint) height &&
   1463        rb->NumSamples == samples) {
   1464       /* no change in allocation needed */
   1465       return;
   1466    }
   1467 
   1468    /* These MUST get set by the AllocStorage func */
   1469    rb->Format = MESA_FORMAT_NONE;
   1470    rb->NumSamples = samples;
   1471 
   1472    /* Now allocate the storage */
   1473    ASSERT(rb->AllocStorage);
   1474    if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
   1475       /* No error - check/set fields now */
   1476       /* If rb->Format == MESA_FORMAT_NONE, the format is unsupported. */
   1477       assert(rb->Width == (GLuint) width);
   1478       assert(rb->Height == (GLuint) height);
   1479       rb->InternalFormat = internalFormat;
   1480       rb->_BaseFormat = baseFormat;
   1481       assert(rb->_BaseFormat != 0);
   1482    }
   1483    else {
   1484       /* Probably ran out of memory - clear the fields */
   1485       rb->Width = 0;
   1486       rb->Height = 0;
   1487       rb->Format = MESA_FORMAT_NONE;
   1488       rb->InternalFormat = GL_NONE;
   1489       rb->_BaseFormat = GL_NONE;
   1490       rb->NumSamples = 0;
   1491    }
   1492 
   1493    /* Invalidate the framebuffers the renderbuffer is attached in. */
   1494    if (rb->AttachedAnytime) {
   1495       _mesa_HashWalk(ctx->Shared->FrameBuffers, invalidate_rb, rb);
   1496    }
   1497 }
   1498 
   1499 
   1500 #if FEATURE_OES_EGL_image
   1501 void GLAPIENTRY
   1502 _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
   1503 {
   1504    struct gl_renderbuffer *rb;
   1505    GET_CURRENT_CONTEXT(ctx);
   1506    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1507 
   1508    if (!ctx->Extensions.OES_EGL_image) {
   1509       _mesa_error(ctx, GL_INVALID_OPERATION,
   1510                   "glEGLImageTargetRenderbufferStorageOES(unsupported)");
   1511       return;
   1512    }
   1513 
   1514    if (target != GL_RENDERBUFFER) {
   1515       _mesa_error(ctx, GL_INVALID_ENUM,
   1516                   "EGLImageTargetRenderbufferStorageOES");
   1517       return;
   1518    }
   1519 
   1520    rb = ctx->CurrentRenderbuffer;
   1521    if (!rb) {
   1522       _mesa_error(ctx, GL_INVALID_OPERATION,
   1523                   "EGLImageTargetRenderbufferStorageOES");
   1524       return;
   1525    }
   1526 
   1527    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   1528 
   1529    ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image);
   1530 }
   1531 #endif
   1532 
   1533 
   1534 /**
   1535  * Helper function for _mesa_GetRenderbufferParameterivEXT() and
   1536  * _mesa_GetFramebufferAttachmentParameterivEXT()
   1537  * We have to be careful to respect the base format.  For example, if a
   1538  * renderbuffer/texture was created with internalFormat=GL_RGB but the
   1539  * driver actually chose a GL_RGBA format, when the user queries ALPHA_SIZE
   1540  * we need to return zero.
   1541  */
   1542 static GLint
   1543 get_component_bits(GLenum pname, GLenum baseFormat, gl_format format)
   1544 {
   1545    if (_mesa_base_format_has_channel(baseFormat, pname))
   1546       return _mesa_get_format_bits(format, pname);
   1547    else
   1548       return 0;
   1549 }
   1550 
   1551 
   1552 
   1553 void GLAPIENTRY
   1554 _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
   1555                              GLsizei width, GLsizei height)
   1556 {
   1557    /* GL_ARB_fbo says calling this function is equivalent to calling
   1558     * glRenderbufferStorageMultisample() with samples=0.  We pass in
   1559     * a token value here just for error reporting purposes.
   1560     */
   1561    renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES);
   1562 }
   1563 
   1564 
   1565 void GLAPIENTRY
   1566 _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
   1567                                      GLenum internalFormat,
   1568                                      GLsizei width, GLsizei height)
   1569 {
   1570    renderbuffer_storage(target, internalFormat, width, height, samples);
   1571 }
   1572 
   1573 
   1574 /**
   1575  * OpenGL ES version of glRenderBufferStorage.
   1576  */
   1577 void GLAPIENTRY
   1578 _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
   1579 			   GLsizei width, GLsizei height)
   1580 {
   1581    switch (internalFormat) {
   1582    case GL_RGB565:
   1583       /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
   1584       /* choose a closest format */
   1585       internalFormat = GL_RGB5;
   1586       break;
   1587    default:
   1588       break;
   1589    }
   1590 
   1591    renderbuffer_storage(target, internalFormat, width, height, 0);
   1592 }
   1593 
   1594 
   1595 void GLAPIENTRY
   1596 _mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
   1597 {
   1598    struct gl_renderbuffer *rb;
   1599    GET_CURRENT_CONTEXT(ctx);
   1600 
   1601    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1602 
   1603    if (target != GL_RENDERBUFFER_EXT) {
   1604       _mesa_error(ctx, GL_INVALID_ENUM,
   1605                   "glGetRenderbufferParameterivEXT(target)");
   1606       return;
   1607    }
   1608 
   1609    rb = ctx->CurrentRenderbuffer;
   1610    if (!rb) {
   1611       _mesa_error(ctx, GL_INVALID_OPERATION,
   1612                   "glGetRenderbufferParameterivEXT");
   1613       return;
   1614    }
   1615 
   1616    /* No need to flush here since we're just quering state which is
   1617     * not effected by rendering.
   1618     */
   1619 
   1620    switch (pname) {
   1621    case GL_RENDERBUFFER_WIDTH_EXT:
   1622       *params = rb->Width;
   1623       return;
   1624    case GL_RENDERBUFFER_HEIGHT_EXT:
   1625       *params = rb->Height;
   1626       return;
   1627    case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
   1628       *params = rb->InternalFormat;
   1629       return;
   1630    case GL_RENDERBUFFER_RED_SIZE_EXT:
   1631    case GL_RENDERBUFFER_GREEN_SIZE_EXT:
   1632    case GL_RENDERBUFFER_BLUE_SIZE_EXT:
   1633    case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
   1634    case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
   1635    case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
   1636       *params = get_component_bits(pname, rb->_BaseFormat, rb->Format);
   1637       break;
   1638    case GL_RENDERBUFFER_SAMPLES:
   1639       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_framebuffer_object)
   1640           || _mesa_is_gles3(ctx)) {
   1641          *params = rb->NumSamples;
   1642          break;
   1643       }
   1644       /* fallthrough */
   1645    default:
   1646       _mesa_error(ctx, GL_INVALID_ENUM,
   1647                   "glGetRenderbufferParameterivEXT(target)");
   1648       return;
   1649    }
   1650 }
   1651 
   1652 
   1653 GLboolean GLAPIENTRY
   1654 _mesa_IsFramebufferEXT(GLuint framebuffer)
   1655 {
   1656    GET_CURRENT_CONTEXT(ctx);
   1657    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
   1658    if (framebuffer) {
   1659       struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer);
   1660       if (rb != NULL && rb != &DummyFramebuffer)
   1661          return GL_TRUE;
   1662    }
   1663    return GL_FALSE;
   1664 }
   1665 
   1666 
   1667 /**
   1668  * Check if any of the attachments of the given framebuffer are textures
   1669  * (render to texture).  Call ctx->Driver.RenderTexture() for such
   1670  * attachments.
   1671  */
   1672 static void
   1673 check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
   1674 {
   1675    GLuint i;
   1676    ASSERT(ctx->Driver.RenderTexture);
   1677 
   1678    if (_mesa_is_winsys_fbo(fb))
   1679       return; /* can't render to texture with winsys framebuffers */
   1680 
   1681    for (i = 0; i < BUFFER_COUNT; i++) {
   1682       struct gl_renderbuffer_attachment *att = fb->Attachment + i;
   1683       if (att->Texture && _mesa_get_attachment_teximage(att)) {
   1684          ctx->Driver.RenderTexture(ctx, fb, att);
   1685       }
   1686    }
   1687 }
   1688 
   1689 
   1690 /**
   1691  * Examine all the framebuffer's attachments to see if any are textures.
   1692  * If so, call ctx->Driver.FinishRenderTexture() for each texture to
   1693  * notify the device driver that the texture image may have changed.
   1694  */
   1695 static void
   1696 check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
   1697 {
   1698    if (_mesa_is_winsys_fbo(fb))
   1699       return; /* can't render to texture with winsys framebuffers */
   1700 
   1701    if (ctx->Driver.FinishRenderTexture) {
   1702       GLuint i;
   1703       for (i = 0; i < BUFFER_COUNT; i++) {
   1704          struct gl_renderbuffer_attachment *att = fb->Attachment + i;
   1705          if (att->Texture && att->Renderbuffer) {
   1706             ctx->Driver.FinishRenderTexture(ctx, att);
   1707          }
   1708       }
   1709    }
   1710 }
   1711 
   1712 
   1713 void GLAPIENTRY
   1714 _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
   1715 {
   1716    struct gl_framebuffer *newDrawFb, *newReadFb;
   1717    struct gl_framebuffer *oldDrawFb, *oldReadFb;
   1718    GLboolean bindReadBuf, bindDrawBuf;
   1719    GET_CURRENT_CONTEXT(ctx);
   1720 
   1721 #ifdef DEBUG
   1722    if (ctx->Extensions.ARB_framebuffer_object) {
   1723       ASSERT(ctx->Extensions.EXT_framebuffer_object);
   1724       ASSERT(ctx->Extensions.EXT_framebuffer_blit);
   1725    }
   1726 #endif
   1727 
   1728    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1729 
   1730    if (!ctx->Extensions.EXT_framebuffer_object) {
   1731       _mesa_error(ctx, GL_INVALID_OPERATION,
   1732                   "glBindFramebufferEXT(unsupported)");
   1733       return;
   1734    }
   1735 
   1736    switch (target) {
   1737 #if FEATURE_EXT_framebuffer_blit
   1738    case GL_DRAW_FRAMEBUFFER_EXT:
   1739       if (!ctx->Extensions.EXT_framebuffer_blit) {
   1740          _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
   1741          return;
   1742       }
   1743       bindDrawBuf = GL_TRUE;
   1744       bindReadBuf = GL_FALSE;
   1745       break;
   1746    case GL_READ_FRAMEBUFFER_EXT:
   1747       if (!ctx->Extensions.EXT_framebuffer_blit) {
   1748          _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
   1749          return;
   1750       }
   1751       bindDrawBuf = GL_FALSE;
   1752       bindReadBuf = GL_TRUE;
   1753       break;
   1754 #endif
   1755    case GL_FRAMEBUFFER_EXT:
   1756       bindDrawBuf = GL_TRUE;
   1757       bindReadBuf = GL_TRUE;
   1758       break;
   1759    default:
   1760       _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)");
   1761       return;
   1762    }
   1763 
   1764    if (framebuffer) {
   1765       /* Binding a user-created framebuffer object */
   1766       newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
   1767       if (newDrawFb == &DummyFramebuffer) {
   1768          /* ID was reserved, but no real framebuffer object made yet */
   1769          newDrawFb = NULL;
   1770       }
   1771       else if (!newDrawFb && ctx->Extensions.ARB_framebuffer_object) {
   1772          /* All FBO IDs must be Gen'd */
   1773          _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
   1774          return;
   1775       }
   1776 
   1777       if (!newDrawFb) {
   1778 	 /* create new framebuffer object */
   1779 	 newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
   1780 	 if (!newDrawFb) {
   1781 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
   1782 	    return;
   1783 	 }
   1784          _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
   1785       }
   1786       newReadFb = newDrawFb;
   1787    }
   1788    else {
   1789       /* Binding the window system framebuffer (which was originally set
   1790        * with MakeCurrent).
   1791        */
   1792       newDrawFb = ctx->WinSysDrawBuffer;
   1793       newReadFb = ctx->WinSysReadBuffer;
   1794    }
   1795 
   1796    ASSERT(newDrawFb);
   1797    ASSERT(newDrawFb != &DummyFramebuffer);
   1798 
   1799    /* save pointers to current/old framebuffers */
   1800    oldDrawFb = ctx->DrawBuffer;
   1801    oldReadFb = ctx->ReadBuffer;
   1802 
   1803    /* check if really changing bindings */
   1804    if (oldDrawFb == newDrawFb)
   1805       bindDrawBuf = GL_FALSE;
   1806    if (oldReadFb == newReadFb)
   1807       bindReadBuf = GL_FALSE;
   1808 
   1809    /*
   1810     * OK, now bind the new Draw/Read framebuffers, if they're changing.
   1811     *
   1812     * We also check if we're beginning and/or ending render-to-texture.
   1813     * When a framebuffer with texture attachments is unbound, call
   1814     * ctx->Driver.FinishRenderTexture().
   1815     * When a framebuffer with texture attachments is bound, call
   1816     * ctx->Driver.RenderTexture().
   1817     *
   1818     * Note that if the ReadBuffer has texture attachments we don't consider
   1819     * that a render-to-texture case.
   1820     */
   1821    if (bindReadBuf) {
   1822       FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   1823 
   1824       /* check if old readbuffer was render-to-texture */
   1825       check_end_texture_render(ctx, oldReadFb);
   1826 
   1827       _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
   1828    }
   1829 
   1830    if (bindDrawBuf) {
   1831       FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   1832 
   1833       /* check if old framebuffer had any texture attachments */
   1834       if (oldDrawFb)
   1835          check_end_texture_render(ctx, oldDrawFb);
   1836 
   1837       /* check if newly bound framebuffer has any texture attachments */
   1838       check_begin_texture_render(ctx, newDrawFb);
   1839 
   1840       _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
   1841    }
   1842 
   1843    if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
   1844       ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
   1845    }
   1846 }
   1847 
   1848 
   1849 void GLAPIENTRY
   1850 _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
   1851 {
   1852    GLint i;
   1853    GET_CURRENT_CONTEXT(ctx);
   1854 
   1855    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1856    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   1857 
   1858    for (i = 0; i < n; i++) {
   1859       if (framebuffers[i] > 0) {
   1860 	 struct gl_framebuffer *fb;
   1861 	 fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
   1862 	 if (fb) {
   1863             ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
   1864 
   1865             /* check if deleting currently bound framebuffer object */
   1866             if (ctx->Extensions.EXT_framebuffer_blit) {
   1867                /* separate draw/read binding points */
   1868                if (fb == ctx->DrawBuffer) {
   1869                   /* bind default */
   1870                   ASSERT(fb->RefCount >= 2);
   1871                   _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
   1872                }
   1873                if (fb == ctx->ReadBuffer) {
   1874                   /* bind default */
   1875                   ASSERT(fb->RefCount >= 2);
   1876                   _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
   1877                }
   1878             }
   1879             else {
   1880                /* only one binding point for read/draw buffers */
   1881                if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) {
   1882                   /* bind default */
   1883                   ASSERT(fb->RefCount >= 2);
   1884                   _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   1885                }
   1886             }
   1887 
   1888 	    /* remove from hash table immediately, to free the ID */
   1889 	    _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
   1890 
   1891             if (fb != &DummyFramebuffer) {
   1892                /* But the object will not be freed until it's no longer
   1893                 * bound in any context.
   1894                 */
   1895                _mesa_reference_framebuffer(&fb, NULL);
   1896 	    }
   1897 	 }
   1898       }
   1899    }
   1900 }
   1901 
   1902 
   1903 void GLAPIENTRY
   1904 _mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
   1905 {
   1906    GET_CURRENT_CONTEXT(ctx);
   1907    GLuint first;
   1908    GLint i;
   1909 
   1910    ASSERT_OUTSIDE_BEGIN_END(ctx);
   1911 
   1912    if (n < 0) {
   1913       _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
   1914       return;
   1915    }
   1916 
   1917    if (!framebuffers)
   1918       return;
   1919 
   1920    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
   1921 
   1922    for (i = 0; i < n; i++) {
   1923       GLuint name = first + i;
   1924       framebuffers[i] = name;
   1925       /* insert dummy placeholder into hash table */
   1926       _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
   1927       _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
   1928       _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
   1929    }
   1930 }
   1931 
   1932 
   1933 
   1934 GLenum GLAPIENTRY
   1935 _mesa_CheckFramebufferStatusEXT(GLenum target)
   1936 {
   1937    struct gl_framebuffer *buffer;
   1938    GET_CURRENT_CONTEXT(ctx);
   1939 
   1940    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
   1941 
   1942    buffer = get_framebuffer_target(ctx, target);
   1943    if (!buffer) {
   1944       _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
   1945       return 0;
   1946    }
   1947 
   1948    if (_mesa_is_winsys_fbo(buffer)) {
   1949       /* The window system / default framebuffer is always complete */
   1950       return GL_FRAMEBUFFER_COMPLETE_EXT;
   1951    }
   1952 
   1953    /* No need to flush here */
   1954 
   1955    if (buffer->_Status != GL_FRAMEBUFFER_COMPLETE) {
   1956       _mesa_test_framebuffer_completeness(ctx, buffer);
   1957    }
   1958 
   1959    return buffer->_Status;
   1960 }
   1961 
   1962 
   1963 /**
   1964  * Replicate the src attachment point. Used by framebuffer_texture() when
   1965  * the same texture is attached at GL_DEPTH_ATTACHMENT and
   1966  * GL_STENCIL_ATTACHMENT.
   1967  */
   1968 static void
   1969 reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
   1970                                      gl_buffer_index dst,
   1971                                      gl_buffer_index src)
   1972 {
   1973    struct gl_renderbuffer_attachment *dst_att = &fb->Attachment[dst];
   1974    struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src];
   1975 
   1976    assert(src_att->Texture != NULL);
   1977    assert(src_att->Renderbuffer != NULL);
   1978 
   1979    _mesa_reference_texobj(&dst_att->Texture, src_att->Texture);
   1980    _mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer);
   1981    dst_att->Type = src_att->Type;
   1982    dst_att->Complete = src_att->Complete;
   1983    dst_att->TextureLevel = src_att->TextureLevel;
   1984    dst_att->Zoffset = src_att->Zoffset;
   1985 }
   1986 
   1987 
   1988 /**
   1989  * Common code called by glFramebufferTexture1D/2D/3DEXT() and
   1990  * glFramebufferTextureLayerEXT().
   1991  * Note: glFramebufferTextureLayerEXT() has no textarget parameter so we'll
   1992  * get textarget=0 in that case.
   1993  */
   1994 static void
   1995 framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
   1996                     GLenum attachment, GLenum textarget, GLuint texture,
   1997                     GLint level, GLint zoffset)
   1998 {
   1999    struct gl_renderbuffer_attachment *att;
   2000    struct gl_texture_object *texObj = NULL;
   2001    struct gl_framebuffer *fb;
   2002    GLenum maxLevelsTarget;
   2003 
   2004    ASSERT_OUTSIDE_BEGIN_END(ctx);
   2005 
   2006    fb = get_framebuffer_target(ctx, target);
   2007    if (!fb) {
   2008       _mesa_error(ctx, GL_INVALID_ENUM,
   2009                   "glFramebufferTexture%sEXT(target=0x%x)", caller, target);
   2010       return;
   2011    }
   2012 
   2013    /* check framebuffer binding */
   2014    if (_mesa_is_winsys_fbo(fb)) {
   2015       _mesa_error(ctx, GL_INVALID_OPERATION,
   2016                   "glFramebufferTexture%sEXT", caller);
   2017       return;
   2018    }
   2019 
   2020    /* The textarget, level, and zoffset parameters are only validated if
   2021     * texture is non-zero.
   2022     */
   2023    if (texture) {
   2024       GLboolean err = GL_TRUE;
   2025 
   2026       texObj = _mesa_lookup_texture(ctx, texture);
   2027       if (texObj != NULL) {
   2028          if (textarget == 0) {
   2029             /* If textarget == 0 it means we're being called by
   2030              * glFramebufferTextureLayer() and textarget is not used.
   2031              * The only legal texture types for that function are 3D and
   2032              * 1D/2D arrays textures.
   2033              */
   2034             err = (texObj->Target != GL_TEXTURE_3D) &&
   2035                 (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
   2036                 (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT);
   2037          }
   2038          else {
   2039             /* Make sure textarget is consistent with the texture's type */
   2040             err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
   2041                 ? !_mesa_is_cube_face(textarget)
   2042                 : (texObj->Target != textarget);
   2043          }
   2044       }
   2045       else {
   2046          /* can't render to a non-existant texture */
   2047          _mesa_error(ctx, GL_INVALID_OPERATION,
   2048                      "glFramebufferTexture%sEXT(non existant texture)",
   2049                      caller);
   2050          return;
   2051       }
   2052 
   2053       if (err) {
   2054          _mesa_error(ctx, GL_INVALID_OPERATION,
   2055                      "glFramebufferTexture%sEXT(texture target mismatch)",
   2056                      caller);
   2057          return;
   2058       }
   2059 
   2060       if (texObj->Target == GL_TEXTURE_3D) {
   2061          const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
   2062          if (zoffset < 0 || zoffset >= maxSize) {
   2063             _mesa_error(ctx, GL_INVALID_VALUE,
   2064                         "glFramebufferTexture%sEXT(zoffset)", caller);
   2065             return;
   2066          }
   2067       }
   2068       else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
   2069                (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
   2070          if (zoffset < 0 || zoffset >= ctx->Const.MaxArrayTextureLayers) {
   2071             _mesa_error(ctx, GL_INVALID_VALUE,
   2072                         "glFramebufferTexture%sEXT(layer)", caller);
   2073             return;
   2074          }
   2075       }
   2076 
   2077       maxLevelsTarget = textarget ? textarget : texObj->Target;
   2078       if ((level < 0) ||
   2079           (level >= _mesa_max_texture_levels(ctx, maxLevelsTarget))) {
   2080          _mesa_error(ctx, GL_INVALID_VALUE,
   2081                      "glFramebufferTexture%sEXT(level)", caller);
   2082          return;
   2083       }
   2084    }
   2085 
   2086    att = _mesa_get_attachment(ctx, fb, attachment);
   2087    if (att == NULL) {
   2088       _mesa_error(ctx, GL_INVALID_ENUM,
   2089                   "glFramebufferTexture%sEXT(attachment)", caller);
   2090       return;
   2091    }
   2092 
   2093    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   2094 
   2095    _glthread_LOCK_MUTEX(fb->Mutex);
   2096    if (texObj) {
   2097       if (attachment == GL_DEPTH_ATTACHMENT &&
   2098           texObj == fb->Attachment[BUFFER_STENCIL].Texture &&
   2099           level == fb->Attachment[BUFFER_STENCIL].TextureLevel &&
   2100           _mesa_tex_target_to_face(textarget) ==
   2101           fb->Attachment[BUFFER_STENCIL].CubeMapFace &&
   2102           zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) {
   2103 	 /* The texture object is already attached to the stencil attachment
   2104 	  * point. Don't create a new renderbuffer; just reuse the stencil
   2105 	  * attachment's. This is required to prevent a GL error in
   2106 	  * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL).
   2107 	  */
   2108 	 reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
   2109 	                                      BUFFER_STENCIL);
   2110       } else if (attachment == GL_STENCIL_ATTACHMENT &&
   2111 	         texObj == fb->Attachment[BUFFER_DEPTH].Texture &&
   2112                  level == fb->Attachment[BUFFER_DEPTH].TextureLevel &&
   2113                  _mesa_tex_target_to_face(textarget) ==
   2114                  fb->Attachment[BUFFER_DEPTH].CubeMapFace &&
   2115                  zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) {
   2116 	 /* As above, but with depth and stencil transposed. */
   2117 	 reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
   2118 	                                      BUFFER_DEPTH);
   2119       } else {
   2120 	 _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
   2121 				      level, zoffset);
   2122 	 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
   2123 	    /* Above we created a new renderbuffer and attached it to the
   2124 	     * depth attachment point. Now attach it to the stencil attachment
   2125 	     * point too.
   2126 	     */
   2127 	    assert(att == &fb->Attachment[BUFFER_DEPTH]);
   2128 	    reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL,
   2129 	                                         BUFFER_DEPTH);
   2130 	 }
   2131       }
   2132 
   2133       /* Set the render-to-texture flag.  We'll check this flag in
   2134        * glTexImage() and friends to determine if we need to revalidate
   2135        * any FBOs that might be rendering into this texture.
   2136        * This flag never gets cleared since it's non-trivial to determine
   2137        * when all FBOs might be done rendering to this texture.  That's OK
   2138        * though since it's uncommon to render to a texture then repeatedly
   2139        * call glTexImage() to change images in the texture.
   2140        */
   2141       texObj->_RenderToTexture = GL_TRUE;
   2142    }
   2143    else {
   2144       _mesa_remove_attachment(ctx, att);
   2145       if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
   2146 	 assert(att == &fb->Attachment[BUFFER_DEPTH]);
   2147 	 _mesa_remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]);
   2148       }
   2149    }
   2150 
   2151    invalidate_framebuffer(fb);
   2152 
   2153    _glthread_UNLOCK_MUTEX(fb->Mutex);
   2154 }
   2155 
   2156 
   2157 
   2158 void GLAPIENTRY
   2159 _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
   2160                               GLenum textarget, GLuint texture, GLint level)
   2161 {
   2162    GET_CURRENT_CONTEXT(ctx);
   2163 
   2164    if (texture != 0) {
   2165       GLboolean error;
   2166 
   2167       switch (textarget) {
   2168       case GL_TEXTURE_1D:
   2169          error = GL_FALSE;
   2170          break;
   2171       case GL_TEXTURE_1D_ARRAY:
   2172          error = !ctx->Extensions.EXT_texture_array;
   2173          break;
   2174       default:
   2175          error = GL_TRUE;
   2176       }
   2177 
   2178       if (error) {
   2179          _mesa_error(ctx, GL_INVALID_OPERATION,
   2180                      "glFramebufferTexture1DEXT(textarget=%s)",
   2181                      _mesa_lookup_enum_by_nr(textarget));
   2182          return;
   2183       }
   2184    }
   2185 
   2186    framebuffer_texture(ctx, "1D", target, attachment, textarget, texture,
   2187                        level, 0);
   2188 }
   2189 
   2190 
   2191 void GLAPIENTRY
   2192 _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
   2193                               GLenum textarget, GLuint texture, GLint level)
   2194 {
   2195    GET_CURRENT_CONTEXT(ctx);
   2196 
   2197    if (texture != 0) {
   2198       GLboolean error;
   2199 
   2200       switch (textarget) {
   2201       case GL_TEXTURE_2D:
   2202          error = GL_FALSE;
   2203          break;
   2204       case GL_TEXTURE_RECTANGLE:
   2205          error = _mesa_is_gles(ctx)
   2206             || !ctx->Extensions.NV_texture_rectangle;
   2207          break;
   2208       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   2209       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   2210       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   2211       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   2212       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   2213       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   2214          error = !ctx->Extensions.ARB_texture_cube_map;
   2215          break;
   2216       case GL_TEXTURE_2D_ARRAY:
   2217          error = (_mesa_is_gles(ctx) && ctx->Version < 30)
   2218             || !ctx->Extensions.EXT_texture_array;
   2219          break;
   2220       default:
   2221          error = GL_TRUE;
   2222       }
   2223 
   2224       if (error) {
   2225          _mesa_error(ctx, GL_INVALID_OPERATION,
   2226                      "glFramebufferTexture2DEXT(textarget=%s)",
   2227                      _mesa_lookup_enum_by_nr(textarget));
   2228          return;
   2229       }
   2230    }
   2231 
   2232    framebuffer_texture(ctx, "2D", target, attachment, textarget, texture,
   2233                        level, 0);
   2234 }
   2235 
   2236 
   2237 void GLAPIENTRY
   2238 _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
   2239                               GLenum textarget, GLuint texture,
   2240                               GLint level, GLint zoffset)
   2241 {
   2242    GET_CURRENT_CONTEXT(ctx);
   2243 
   2244    if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
   2245       _mesa_error(ctx, GL_INVALID_OPERATION,
   2246                   "glFramebufferTexture3DEXT(textarget)");
   2247       return;
   2248    }
   2249 
   2250    framebuffer_texture(ctx, "3D", target, attachment, textarget, texture,
   2251                        level, zoffset);
   2252 }
   2253 
   2254 
   2255 void GLAPIENTRY
   2256 _mesa_FramebufferTextureLayerEXT(GLenum target, GLenum attachment,
   2257                                  GLuint texture, GLint level, GLint layer)
   2258 {
   2259    GET_CURRENT_CONTEXT(ctx);
   2260 
   2261    framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
   2262                        level, layer);
   2263 }
   2264 
   2265 
   2266 void GLAPIENTRY
   2267 _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
   2268                                  GLenum renderbufferTarget,
   2269                                  GLuint renderbuffer)
   2270 {
   2271    struct gl_renderbuffer_attachment *att;
   2272    struct gl_framebuffer *fb;
   2273    struct gl_renderbuffer *rb;
   2274    GET_CURRENT_CONTEXT(ctx);
   2275 
   2276    ASSERT_OUTSIDE_BEGIN_END(ctx);
   2277 
   2278    fb = get_framebuffer_target(ctx, target);
   2279    if (!fb) {
   2280       _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferRenderbufferEXT(target)");
   2281       return;
   2282    }
   2283 
   2284    if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
   2285       _mesa_error(ctx, GL_INVALID_ENUM,
   2286                   "glFramebufferRenderbufferEXT(renderbufferTarget)");
   2287       return;
   2288    }
   2289 
   2290    if (_mesa_is_winsys_fbo(fb)) {
   2291       /* Can't attach new renderbuffers to a window system framebuffer */
   2292       _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
   2293       return;
   2294    }
   2295 
   2296    att = _mesa_get_attachment(ctx, fb, attachment);
   2297    if (att == NULL) {
   2298       _mesa_error(ctx, GL_INVALID_ENUM,
   2299                   "glFramebufferRenderbufferEXT(invalid attachment %s)",
   2300                   _mesa_lookup_enum_by_nr(attachment));
   2301       return;
   2302    }
   2303 
   2304    if (renderbuffer) {
   2305       rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
   2306       if (!rb) {
   2307 	 _mesa_error(ctx, GL_INVALID_OPERATION,
   2308 		     "glFramebufferRenderbufferEXT(non-existant"
   2309                      " renderbuffer %u)", renderbuffer);
   2310 	 return;
   2311       }
   2312       else if (rb == &DummyRenderbuffer) {
   2313          /* This is what NVIDIA does */
   2314 	 _mesa_error(ctx, GL_INVALID_VALUE,
   2315 		     "glFramebufferRenderbufferEXT(renderbuffer %u)",
   2316                      renderbuffer);
   2317 	 return;
   2318       }
   2319    }
   2320    else {
   2321       /* remove renderbuffer attachment */
   2322       rb = NULL;
   2323    }
   2324 
   2325    if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
   2326        rb && rb->Format != MESA_FORMAT_NONE) {
   2327       /* make sure the renderbuffer is a depth/stencil format */
   2328       const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
   2329       if (baseFormat != GL_DEPTH_STENCIL) {
   2330          _mesa_error(ctx, GL_INVALID_OPERATION,
   2331                      "glFramebufferRenderbufferEXT(renderbuffer"
   2332                      " is not DEPTH_STENCIL format)");
   2333          return;
   2334       }
   2335    }
   2336 
   2337 
   2338    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   2339 
   2340    assert(ctx->Driver.FramebufferRenderbuffer);
   2341    ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb);
   2342 
   2343    /* Some subsequent GL commands may depend on the framebuffer's visual
   2344     * after the binding is updated.  Update visual info now.
   2345     */
   2346    _mesa_update_framebuffer_visual(ctx, fb);
   2347 }
   2348 
   2349 
   2350 void GLAPIENTRY
   2351 _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
   2352                                              GLenum pname, GLint *params)
   2353 {
   2354    const struct gl_renderbuffer_attachment *att;
   2355    struct gl_framebuffer *buffer;
   2356    GLenum err;
   2357    GET_CURRENT_CONTEXT(ctx);
   2358 
   2359    ASSERT_OUTSIDE_BEGIN_END(ctx);
   2360 
   2361    /* The error differs in GL and GLES. */
   2362    err = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
   2363 
   2364    buffer = get_framebuffer_target(ctx, target);
   2365    if (!buffer) {
   2366       _mesa_error(ctx, GL_INVALID_ENUM,
   2367                   "glGetFramebufferAttachmentParameterivEXT(target)");
   2368       return;
   2369    }
   2370 
   2371    if (_mesa_is_winsys_fbo(buffer)) {
   2372       /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
   2373        * says:
   2374        *
   2375        *     "If the framebuffer currently bound to target is zero, then
   2376        *     INVALID_OPERATION is generated."
   2377        *
   2378        * The EXT_framebuffer_object spec has the same wording, and the
   2379        * OES_framebuffer_object spec refers to the EXT_framebuffer_object
   2380        * spec.
   2381        */
   2382       if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) {
   2383 	 _mesa_error(ctx, GL_INVALID_OPERATION,
   2384 		     "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
   2385 	 return;
   2386       }
   2387       /* the default / window-system FBO */
   2388       att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
   2389    }
   2390    else {
   2391       /* user-created framebuffer FBO */
   2392       att = _mesa_get_attachment(ctx, buffer, attachment);
   2393    }
   2394 
   2395    if (att == NULL) {
   2396       _mesa_error(ctx, GL_INVALID_ENUM,
   2397                   "glGetFramebufferAttachmentParameterivEXT(attachment)");
   2398       return;
   2399    }
   2400 
   2401    if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
   2402       /* the depth and stencil attachments must point to the same buffer */
   2403       const struct gl_renderbuffer_attachment *depthAtt, *stencilAtt;
   2404       depthAtt = _mesa_get_attachment(ctx, buffer, GL_DEPTH_ATTACHMENT);
   2405       stencilAtt = _mesa_get_attachment(ctx, buffer, GL_STENCIL_ATTACHMENT);
   2406       if (depthAtt->Renderbuffer != stencilAtt->Renderbuffer) {
   2407          _mesa_error(ctx, GL_INVALID_OPERATION,
   2408                      "glGetFramebufferAttachmentParameterivEXT(DEPTH/STENCIL"
   2409                      " attachments differ)");
   2410          return;
   2411       }
   2412    }
   2413 
   2414    /* No need to flush here */
   2415 
   2416    switch (pname) {
   2417    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
   2418       *params = _mesa_is_winsys_fbo(buffer)
   2419          ? GL_FRAMEBUFFER_DEFAULT : att->Type;
   2420       return;
   2421    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
   2422       if (att->Type == GL_RENDERBUFFER_EXT) {
   2423 	 *params = att->Renderbuffer->Name;
   2424       }
   2425       else if (att->Type == GL_TEXTURE) {
   2426 	 *params = att->Texture->Name;
   2427       }
   2428       else {
   2429          assert(att->Type == GL_NONE);
   2430          if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
   2431             *params = 0;
   2432          } else {
   2433             goto invalid_pname_enum;
   2434          }
   2435       }
   2436       return;
   2437    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
   2438       if (att->Type == GL_TEXTURE) {
   2439 	 *params = att->TextureLevel;
   2440       }
   2441       else if (att->Type == GL_NONE) {
   2442          _mesa_error(ctx, err,
   2443                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2444       }
   2445       else {
   2446          goto invalid_pname_enum;
   2447       }
   2448       return;
   2449    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
   2450       if (att->Type == GL_TEXTURE) {
   2451          if (att->Texture && att->Texture->Target == GL_TEXTURE_CUBE_MAP) {
   2452             *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
   2453          }
   2454          else {
   2455             *params = 0;
   2456          }
   2457       }
   2458       else if (att->Type == GL_NONE) {
   2459          _mesa_error(ctx, err,
   2460                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2461       }
   2462       else {
   2463          goto invalid_pname_enum;
   2464       }
   2465       return;
   2466    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
   2467       if (ctx->API == API_OPENGLES) {
   2468          goto invalid_pname_enum;
   2469       } else if (att->Type == GL_NONE) {
   2470          _mesa_error(ctx, err,
   2471                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2472       } else if (att->Type == GL_TEXTURE) {
   2473          if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) {
   2474             *params = att->Zoffset;
   2475          }
   2476          else {
   2477             *params = 0;
   2478          }
   2479       }
   2480       else {
   2481          goto invalid_pname_enum;
   2482       }
   2483       return;
   2484    case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
   2485       if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object)
   2486           && !_mesa_is_gles3(ctx)) {
   2487          goto invalid_pname_enum;
   2488       }
   2489       else if (att->Type == GL_NONE) {
   2490          _mesa_error(ctx, err,
   2491                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2492       }
   2493       else {
   2494          if (ctx->Extensions.EXT_framebuffer_sRGB) {
   2495             *params = _mesa_get_format_color_encoding(att->Renderbuffer->Format);
   2496          }
   2497          else {
   2498             /* According to ARB_framebuffer_sRGB, we should return LINEAR
   2499              * if the sRGB conversion is unsupported. */
   2500             *params = GL_LINEAR;
   2501          }
   2502       }
   2503       return;
   2504    case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
   2505       if ((ctx->API != API_OPENGL || !ctx->Extensions.ARB_framebuffer_object)
   2506           && ctx->API != API_OPENGL_CORE
   2507           && !_mesa_is_gles3(ctx)) {
   2508          goto invalid_pname_enum;
   2509       }
   2510       else if (att->Type == GL_NONE) {
   2511          _mesa_error(ctx, err,
   2512                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2513       }
   2514       else {
   2515          gl_format format = att->Renderbuffer->Format;
   2516          if (format == MESA_FORMAT_S8) {
   2517             /* special cases */
   2518             *params = GL_INDEX;
   2519          }
   2520          else if (format == MESA_FORMAT_Z32_FLOAT_X24S8) {
   2521             /* depends on the attachment parameter */
   2522             if (attachment == GL_STENCIL_ATTACHMENT) {
   2523                *params = GL_INDEX;
   2524             }
   2525             else {
   2526                *params = GL_FLOAT;
   2527             }
   2528          }
   2529          else {
   2530             *params = _mesa_get_format_datatype(format);
   2531          }
   2532       }
   2533       return;
   2534    case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
   2535    case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
   2536    case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
   2537    case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
   2538    case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
   2539    case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
   2540       if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object)
   2541           && !_mesa_is_gles3(ctx)) {
   2542          goto invalid_pname_enum;
   2543       }
   2544       else if (att->Type == GL_NONE) {
   2545          _mesa_error(ctx, err,
   2546                      "glGetFramebufferAttachmentParameterivEXT(pname)");
   2547       }
   2548       else if (att->Texture) {
   2549          const struct gl_texture_image *texImage =
   2550             _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target,
   2551                                    att->TextureLevel);
   2552          if (texImage) {
   2553             *params = get_component_bits(pname, texImage->_BaseFormat,
   2554                                          texImage->TexFormat);
   2555          }
   2556          else {
   2557             *params = 0;
   2558          }
   2559       }
   2560       else if (att->Renderbuffer) {
   2561          *params = get_component_bits(pname, att->Renderbuffer->_BaseFormat,
   2562                                       att->Renderbuffer->Format);
   2563       }
   2564       else {
   2565          _mesa_problem(ctx, "glGetFramebufferAttachmentParameterivEXT:"
   2566                        " invalid FBO attachment structure");
   2567       }
   2568       return;
   2569    default:
   2570       goto invalid_pname_enum;
   2571    }
   2572 
   2573    return;
   2574 
   2575 invalid_pname_enum:
   2576    _mesa_error(ctx, GL_INVALID_ENUM,
   2577                "glGetFramebufferAttachmentParameteriv(pname)");
   2578    return;
   2579 }
   2580 
   2581 
   2582 void GLAPIENTRY
   2583 _mesa_GenerateMipmapEXT(GLenum target)
   2584 {
   2585    struct gl_texture_image *srcImage;
   2586    struct gl_texture_object *texObj;
   2587    GLboolean error;
   2588 
   2589    GET_CURRENT_CONTEXT(ctx);
   2590 
   2591    ASSERT_OUTSIDE_BEGIN_END(ctx);
   2592    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   2593 
   2594    switch (target) {
   2595    case GL_TEXTURE_1D:
   2596       error = _mesa_is_gles(ctx);
   2597       break;
   2598    case GL_TEXTURE_2D:
   2599       error = GL_FALSE;
   2600       break;
   2601    case GL_TEXTURE_3D:
   2602       error = ctx->API == API_OPENGLES;
   2603       break;
   2604    case GL_TEXTURE_CUBE_MAP:
   2605       error = !ctx->Extensions.ARB_texture_cube_map;
   2606       break;
   2607    case GL_TEXTURE_1D_ARRAY:
   2608       error = _mesa_is_gles(ctx) || !ctx->Extensions.EXT_texture_array;
   2609       break;
   2610    case GL_TEXTURE_2D_ARRAY:
   2611       error = (_mesa_is_gles(ctx) && ctx->Version < 30)
   2612          || !ctx->Extensions.EXT_texture_array;
   2613       break;
   2614    default:
   2615       error = GL_TRUE;
   2616    }
   2617 
   2618    if (error) {
   2619       _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)",
   2620                   _mesa_lookup_enum_by_nr(target));
   2621       return;
   2622    }
   2623 
   2624    texObj = _mesa_get_current_tex_object(ctx, target);
   2625 
   2626    if (texObj->BaseLevel >= texObj->MaxLevel) {
   2627       /* nothing to do */
   2628       return;
   2629    }
   2630 
   2631    if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
   2632        !_mesa_cube_complete(texObj)) {
   2633       _mesa_error(ctx, GL_INVALID_OPERATION,
   2634                   "glGenerateMipmap(incomplete cube map)");
   2635       return;
   2636    }
   2637 
   2638    _mesa_lock_texture(ctx, texObj);
   2639 
   2640    srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
   2641    if (!srcImage) {
   2642       _mesa_unlock_texture(ctx, texObj);
   2643       _mesa_error(ctx, GL_INVALID_OPERATION,
   2644                   "glGenerateMipmap(zero size base image)");
   2645       return;
   2646    }
   2647 
   2648    if (_mesa_is_enum_format_integer(srcImage->InternalFormat) ||
   2649        _mesa_is_depthstencil_format(srcImage->InternalFormat) ||
   2650        _mesa_is_stencil_format(srcImage->InternalFormat)) {
   2651       _mesa_unlock_texture(ctx, texObj);
   2652       _mesa_error(ctx, GL_INVALID_OPERATION,
   2653                   "glGenerateMipmap(invalid internal format)");
   2654       return;
   2655    }
   2656 
   2657    if (target == GL_TEXTURE_CUBE_MAP) {
   2658       GLuint face;
   2659       for (face = 0; face < 6; face++)
   2660 	 ctx->Driver.GenerateMipmap(ctx,
   2661 				    GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
   2662 				    texObj);
   2663    }
   2664    else {
   2665       ctx->Driver.GenerateMipmap(ctx, target, texObj);
   2666    }
   2667    _mesa_unlock_texture(ctx, texObj);
   2668 }
   2669 
   2670 
   2671 #if FEATURE_EXT_framebuffer_blit
   2672 
   2673 static const struct gl_renderbuffer_attachment *
   2674 find_attachment(const struct gl_framebuffer *fb,
   2675                 const struct gl_renderbuffer *rb)
   2676 {
   2677    GLuint i;
   2678    for (i = 0; i < Elements(fb->Attachment); i++) {
   2679       if (fb->Attachment[i].Renderbuffer == rb)
   2680          return &fb->Attachment[i];
   2681    }
   2682    return NULL;
   2683 }
   2684 
   2685 
   2686 /**
   2687  * Helper function for checking if the datatypes of color buffers are
   2688  * compatible for glBlitFramebuffer.  From the 3.1 spec, page 198:
   2689  *
   2690  * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
   2691  *  and any of the following conditions hold:
   2692  *   - The read buffer contains fixed-point or floating-point values and any
   2693  *     draw buffer contains neither fixed-point nor floating-point values.
   2694  *   - The read buffer contains unsigned integer values and any draw buffer
   2695  *     does not contain unsigned integer values.
   2696  *   - The read buffer contains signed integer values and any draw buffer
   2697  *     does not contain signed integer values."
   2698  */
   2699 static GLboolean
   2700 compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat)
   2701 {
   2702    GLenum srcType = _mesa_get_format_datatype(srcFormat);
   2703    GLenum dstType = _mesa_get_format_datatype(dstFormat);
   2704 
   2705    if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
   2706       assert(srcType == GL_UNSIGNED_NORMALIZED ||
   2707              srcType == GL_SIGNED_NORMALIZED ||
   2708              srcType == GL_FLOAT);
   2709       /* Boil any of those types down to GL_FLOAT */
   2710       srcType = GL_FLOAT;
   2711    }
   2712 
   2713    if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
   2714       assert(dstType == GL_UNSIGNED_NORMALIZED ||
   2715              dstType == GL_SIGNED_NORMALIZED ||
   2716              dstType == GL_FLOAT);
   2717       /* Boil any of those types down to GL_FLOAT */
   2718       dstType = GL_FLOAT;
   2719    }
   2720 
   2721    return srcType == dstType;
   2722 }
   2723 
   2724 
   2725 /**
   2726  * Return the equivalent non-generic internal format.
   2727  * This is useful for comparing whether two internal formats are semantically
   2728  * equivalent.
   2729  */
   2730 static GLenum
   2731 get_nongeneric_internalformat(GLenum format)
   2732 {
   2733    switch (format) {
   2734       /* GL 1.1 formats. */
   2735       case 4:
   2736       case GL_RGBA:
   2737          return GL_RGBA8;
   2738 
   2739       case 3:
   2740       case GL_RGB:
   2741          return GL_RGB8;
   2742 
   2743       case 2:
   2744       case GL_LUMINANCE_ALPHA:
   2745          return GL_LUMINANCE8_ALPHA8;
   2746 
   2747       case 1:
   2748       case GL_LUMINANCE:
   2749          return GL_LUMINANCE8;
   2750 
   2751       case GL_ALPHA:
   2752          return GL_ALPHA8;
   2753 
   2754       case GL_INTENSITY:
   2755          return GL_INTENSITY8;
   2756 
   2757       /* GL_ARB_texture_rg */
   2758       case GL_RED:
   2759          return GL_R8;
   2760 
   2761       case GL_RG:
   2762          return GL_RG8;
   2763 
   2764       /* GL_EXT_texture_sRGB */
   2765       case GL_SRGB:
   2766          return GL_SRGB8;
   2767 
   2768       case GL_SRGB_ALPHA:
   2769          return GL_SRGB8_ALPHA8;
   2770 
   2771       case GL_SLUMINANCE:
   2772          return GL_SLUMINANCE8;
   2773 
   2774       case GL_SLUMINANCE_ALPHA:
   2775          return GL_SLUMINANCE8_ALPHA8;
   2776 
   2777       /* GL_EXT_texture_snorm */
   2778       case GL_RGBA_SNORM:
   2779          return GL_RGBA8_SNORM;
   2780 
   2781       case GL_RGB_SNORM:
   2782          return GL_RGB8_SNORM;
   2783 
   2784       case GL_RG_SNORM:
   2785          return GL_RG8_SNORM;
   2786 
   2787       case GL_RED_SNORM:
   2788          return GL_R8_SNORM;
   2789 
   2790       case GL_LUMINANCE_ALPHA_SNORM:
   2791          return GL_LUMINANCE8_ALPHA8_SNORM;
   2792 
   2793       case GL_LUMINANCE_SNORM:
   2794          return GL_LUMINANCE8_SNORM;
   2795 
   2796       case GL_ALPHA_SNORM:
   2797          return GL_ALPHA8_SNORM;
   2798 
   2799       case GL_INTENSITY_SNORM:
   2800          return GL_INTENSITY8_SNORM;
   2801 
   2802       default:
   2803          return format;
   2804    }
   2805 }
   2806 
   2807 
   2808 static GLenum
   2809 get_linear_internalformat(GLenum format)
   2810 {
   2811    switch (format) {
   2812    case GL_SRGB:
   2813       return GL_RGB;
   2814 
   2815    case GL_SRGB_ALPHA:
   2816       return GL_RGBA;
   2817 
   2818    case GL_SRGB8:
   2819       return GL_RGB8;
   2820 
   2821    case GL_SRGB8_ALPHA8:
   2822       return GL_RGBA8;
   2823 
   2824    case GL_SLUMINANCE:
   2825       return GL_LUMINANCE8;
   2826 
   2827    case GL_SLUMINANCE_ALPHA:
   2828       return GL_LUMINANCE8_ALPHA8;
   2829 
   2830    default:
   2831       return format;
   2832    }
   2833 }
   2834 
   2835 
   2836 static GLboolean
   2837 compatible_resolve_formats(const struct gl_renderbuffer *colorReadRb,
   2838                            const struct gl_renderbuffer *colorDrawRb)
   2839 {
   2840    GLenum readFormat, drawFormat;
   2841 
   2842    /* The simple case where we know the backing Mesa formats are the same.
   2843     */
   2844    if (_mesa_get_srgb_format_linear(colorReadRb->Format) ==
   2845        _mesa_get_srgb_format_linear(colorDrawRb->Format)) {
   2846       return GL_TRUE;
   2847    }
   2848 
   2849    /* The Mesa formats are different, so we must check whether the internal
   2850     * formats are compatible.
   2851     *
   2852     * Under some circumstances, the user may request e.g. two GL_RGBA8
   2853     * textures and get two entirely different Mesa formats like RGBA8888 and
   2854     * ARGB8888. Drivers behaving like that should be able to cope with
   2855     * non-matching formats by themselves, because it's not the user's fault.
   2856     *
   2857     * Blits between linear and sRGB formats are also allowed.
   2858     */
   2859    readFormat = get_nongeneric_internalformat(colorReadRb->InternalFormat);
   2860    drawFormat = get_nongeneric_internalformat(colorDrawRb->InternalFormat);
   2861    readFormat = get_linear_internalformat(readFormat);
   2862    drawFormat = get_linear_internalformat(drawFormat);
   2863 
   2864    if (readFormat == drawFormat) {
   2865       return GL_TRUE;
   2866    }
   2867 
   2868    return GL_FALSE;
   2869 }
   2870 
   2871 
   2872 /**
   2873  * Blit rectangular region, optionally from one framebuffer to another.
   2874  *
   2875  * Note, if the src buffer is multisampled and the dest is not, this is
   2876  * when the samples must be resolved to a single color.
   2877  */
   2878 void GLAPIENTRY
   2879 _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   2880                          GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   2881                          GLbitfield mask, GLenum filter)
   2882 {
   2883    const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
   2884                                      GL_DEPTH_BUFFER_BIT |
   2885                                      GL_STENCIL_BUFFER_BIT);
   2886    const struct gl_framebuffer *readFb, *drawFb;
   2887    const struct gl_renderbuffer *colorReadRb, *colorDrawRb;
   2888    GET_CURRENT_CONTEXT(ctx);
   2889 
   2890    ASSERT_OUTSIDE_BEGIN_END(ctx);
   2891    FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   2892 
   2893    if (MESA_VERBOSE & VERBOSE_API)
   2894       _mesa_debug(ctx,
   2895                   "glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d, 0x%x, %s)\n",
   2896                   srcX0, srcY0, srcX1, srcY1,
   2897                   dstX0, dstY0, dstX1, dstY1,
   2898                   mask, _mesa_lookup_enum_by_nr(filter));
   2899 
   2900    if (ctx->NewState) {
   2901       _mesa_update_state(ctx);
   2902    }
   2903 
   2904    readFb = ctx->ReadBuffer;
   2905    drawFb = ctx->DrawBuffer;
   2906 
   2907    if (!readFb || !drawFb) {
   2908       /* This will normally never happen but someday we may want to
   2909        * support MakeCurrent() with no drawables.
   2910        */
   2911       return;
   2912    }
   2913 
   2914    /* check for complete framebuffers */
   2915    if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
   2916        readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   2917       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
   2918                   "glBlitFramebufferEXT(incomplete draw/read buffers)");
   2919       return;
   2920    }
   2921 
   2922    if (filter != GL_NEAREST && filter != GL_LINEAR) {
   2923       _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(filter)");
   2924       return;
   2925    }
   2926 
   2927    if (mask & ~legalMaskBits) {
   2928       _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
   2929       return;
   2930    }
   2931 
   2932    /* depth/stencil must be blitted with nearest filtering */
   2933    if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
   2934         && filter != GL_NEAREST) {
   2935       _mesa_error(ctx, GL_INVALID_OPERATION,
   2936              "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)");
   2937       return;
   2938    }
   2939 
   2940    /* get color read/draw renderbuffers */
   2941    if (mask & GL_COLOR_BUFFER_BIT) {
   2942       colorReadRb = readFb->_ColorReadBuffer;
   2943       colorDrawRb = drawFb->_ColorDrawBuffers[0];
   2944 
   2945       /* From the EXT_framebuffer_object spec:
   2946        *
   2947        *     "If a buffer is specified in <mask> and does not exist in both
   2948        *     the read and draw framebuffers, the corresponding bit is silently
   2949        *     ignored."
   2950        */
   2951       if ((colorReadRb == NULL) || (colorDrawRb == NULL)) {
   2952 	 colorReadRb = colorDrawRb = NULL;
   2953 	 mask &= ~GL_COLOR_BUFFER_BIT;
   2954       }
   2955       else if (!compatible_color_datatypes(colorReadRb->Format,
   2956                                            colorDrawRb->Format)) {
   2957          _mesa_error(ctx, GL_INVALID_OPERATION,
   2958                      "glBlitFramebufferEXT(color buffer datatypes mismatch)");
   2959          return;
   2960       }
   2961    }
   2962    else {
   2963       colorReadRb = colorDrawRb = NULL;
   2964    }
   2965 
   2966    if (mask & GL_STENCIL_BUFFER_BIT) {
   2967       struct gl_renderbuffer *readRb =
   2968          readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
   2969       struct gl_renderbuffer *drawRb =
   2970          drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
   2971 
   2972       /* From the EXT_framebuffer_object spec:
   2973        *
   2974        *     "If a buffer is specified in <mask> and does not exist in both
   2975        *     the read and draw framebuffers, the corresponding bit is silently
   2976        *     ignored."
   2977        */
   2978       if ((readRb == NULL) || (drawRb == NULL)) {
   2979 	 mask &= ~GL_STENCIL_BUFFER_BIT;
   2980       }
   2981       else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
   2982 	       _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
   2983 	 /* There is no need to check the stencil datatype here, because
   2984 	  * there is only one: GL_UNSIGNED_INT.
   2985 	  */
   2986          _mesa_error(ctx, GL_INVALID_OPERATION,
   2987                      "glBlitFramebufferEXT(stencil buffer size mismatch)");
   2988          return;
   2989       }
   2990    }
   2991 
   2992    if (mask & GL_DEPTH_BUFFER_BIT) {
   2993       struct gl_renderbuffer *readRb =
   2994          readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
   2995       struct gl_renderbuffer *drawRb =
   2996          drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
   2997 
   2998       /* From the EXT_framebuffer_object spec:
   2999        *
   3000        *     "If a buffer is specified in <mask> and does not exist in both
   3001        *     the read and draw framebuffers, the corresponding bit is silently
   3002        *     ignored."
   3003        */
   3004       if ((readRb == NULL) || (drawRb == NULL)) {
   3005 	 mask &= ~GL_DEPTH_BUFFER_BIT;
   3006       }
   3007       else if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
   3008 	        _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
   3009 	       (_mesa_get_format_datatype(readRb->Format) !=
   3010 		_mesa_get_format_datatype(drawRb->Format))) {
   3011          _mesa_error(ctx, GL_INVALID_OPERATION,
   3012                      "glBlitFramebufferEXT(depth buffer format mismatch)");
   3013          return;
   3014       }
   3015    }
   3016 
   3017    if (readFb->Visual.samples > 0 &&
   3018        drawFb->Visual.samples > 0 &&
   3019        readFb->Visual.samples != drawFb->Visual.samples) {
   3020       _mesa_error(ctx, GL_INVALID_OPERATION,
   3021                   "glBlitFramebufferEXT(mismatched samples)");
   3022       return;
   3023    }
   3024 
   3025    /* extra checks for multisample copies... */
   3026    if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
   3027       /* src and dest region sizes must be the same */
   3028       if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
   3029           abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
   3030          _mesa_error(ctx, GL_INVALID_OPERATION,
   3031                 "glBlitFramebufferEXT(bad src/dst multisample region sizes)");
   3032          return;
   3033       }
   3034 
   3035       /* color formats must match */
   3036       if (colorReadRb &&
   3037           colorDrawRb &&
   3038           !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
   3039          _mesa_error(ctx, GL_INVALID_OPERATION,
   3040                 "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
   3041          return;
   3042       }
   3043    }
   3044 
   3045    if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) {
   3046       /* 3.1 spec, page 199:
   3047        * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
   3048        * if filter is LINEAR and read buffer contains integer data."
   3049        */
   3050       GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
   3051       if (type == GL_INT || type == GL_UNSIGNED_INT) {
   3052          _mesa_error(ctx, GL_INVALID_OPERATION,
   3053                      "glBlitFramebufferEXT(integer color type)");
   3054          return;
   3055       }
   3056    }
   3057 
   3058    if (!ctx->Extensions.EXT_framebuffer_blit) {
   3059       _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT");
   3060       return;
   3061    }
   3062 
   3063    /* Debug code */
   3064    if (DEBUG_BLIT) {
   3065       printf("glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d,"
   3066 	     " 0x%x, 0x%x)\n",
   3067 	     srcX0, srcY0, srcX1, srcY1,
   3068 	     dstX0, dstY0, dstX1, dstY1,
   3069 	     mask, filter);
   3070       if (colorReadRb) {
   3071          const struct gl_renderbuffer_attachment *att;
   3072 
   3073          att = find_attachment(readFb, colorReadRb);
   3074          printf("  Src FBO %u  RB %u (%dx%d)  ",
   3075 		readFb->Name, colorReadRb->Name,
   3076 		colorReadRb->Width, colorReadRb->Height);
   3077          if (att && att->Texture) {
   3078             printf("Tex %u  tgt 0x%x  level %u  face %u",
   3079 		   att->Texture->Name,
   3080 		   att->Texture->Target,
   3081 		   att->TextureLevel,
   3082 		   att->CubeMapFace);
   3083          }
   3084          printf("\n");
   3085 
   3086          att = find_attachment(drawFb, colorDrawRb);
   3087          printf("  Dst FBO %u  RB %u (%dx%d)  ",
   3088 		drawFb->Name, colorDrawRb->Name,
   3089 		colorDrawRb->Width, colorDrawRb->Height);
   3090          if (att && att->Texture) {
   3091             printf("Tex %u  tgt 0x%x  level %u  face %u",
   3092 		   att->Texture->Name,
   3093 		   att->Texture->Target,
   3094 		   att->TextureLevel,
   3095 		   att->CubeMapFace);
   3096          }
   3097          printf("\n");
   3098       }
   3099    }
   3100 
   3101    if (!mask) {
   3102       return;
   3103    }
   3104 
   3105    ASSERT(ctx->Driver.BlitFramebuffer);
   3106    ctx->Driver.BlitFramebuffer(ctx,
   3107                                srcX0, srcY0, srcX1, srcY1,
   3108                                dstX0, dstY0, dstX1, dstY1,
   3109                                mask, filter);
   3110 }
   3111 #endif /* FEATURE_EXT_framebuffer_blit */
   3112 
   3113 
   3114 #if FEATURE_ARB_geometry_shader4
   3115 void GLAPIENTRY
   3116 _mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
   3117                             GLuint texture, GLint level)
   3118 {
   3119    GET_CURRENT_CONTEXT(ctx);
   3120    _mesa_error(ctx, GL_INVALID_OPERATION,
   3121                "glFramebufferTextureARB "
   3122                "not implemented!");
   3123 }
   3124 
   3125 
   3126 void GLAPIENTRY
   3127 _mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
   3128                                 GLuint texture, GLint level, GLenum face)
   3129 {
   3130    GET_CURRENT_CONTEXT(ctx);
   3131    _mesa_error(ctx, GL_INVALID_OPERATION,
   3132                "glFramebufferTextureFaceARB "
   3133                "not implemented!");
   3134 }
   3135 #endif /* FEATURE_ARB_geometry_shader4 */
   3136 
   3137 static void
   3138 invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
   3139                                const GLenum *attachments, GLint x, GLint y,
   3140                                GLsizei width, GLsizei height, const char *name)
   3141 {
   3142    int i;
   3143    struct gl_framebuffer *fb;
   3144    GET_CURRENT_CONTEXT(ctx);
   3145 
   3146    ASSERT_OUTSIDE_BEGIN_END(ctx);
   3147 
   3148    fb = get_framebuffer_target(ctx, target);
   3149    if (!fb) {
   3150       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", name);
   3151       return;
   3152    }
   3153 
   3154    if (numAttachments < 0) {
   3155       _mesa_error(ctx, GL_INVALID_VALUE,
   3156                   "%s(numAttachments < 0)", name);
   3157       return;
   3158    }
   3159 
   3160    /* The GL_ARB_invalidate_subdata spec says:
   3161     *
   3162     *     "If an attachment is specified that does not exist in the
   3163     *     framebuffer bound to <target>, it is ignored."
   3164     *
   3165     * It also says:
   3166     *
   3167     *     "If <attachments> contains COLOR_ATTACHMENTm and m is greater than
   3168     *     or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
   3169     *     INVALID_OPERATION is generated."
   3170     *
   3171     * No mention is made of GL_AUXi being out of range.  Therefore, we allow
   3172     * any enum that can be allowed by the API (OpenGL ES 3.0 has a different
   3173     * set of retrictions).
   3174     */
   3175    for (i = 0; i < numAttachments; i++) {
   3176       if (_mesa_is_winsys_fbo(fb)) {
   3177          switch (attachments[i]) {
   3178          case GL_ACCUM:
   3179          case GL_AUX0:
   3180          case GL_AUX1:
   3181          case GL_AUX2:
   3182          case GL_AUX3:
   3183             /* Accumulation buffers and auxilary buffers were removed in
   3184              * OpenGL 3.1, and they never existed in OpenGL ES.
   3185              */
   3186             if (ctx->API != API_OPENGL)
   3187                goto invalid_enum;
   3188             break;
   3189          case GL_COLOR:
   3190          case GL_DEPTH:
   3191          case GL_STENCIL:
   3192             break;
   3193          case GL_BACK_LEFT:
   3194          case GL_BACK_RIGHT:
   3195          case GL_FRONT_LEFT:
   3196          case GL_FRONT_RIGHT:
   3197             if (!_mesa_is_desktop_gl(ctx))
   3198                goto invalid_enum;
   3199             break;
   3200          default:
   3201             goto invalid_enum;
   3202          }
   3203       } else {
   3204          switch (attachments[i]) {
   3205          case GL_DEPTH_ATTACHMENT:
   3206          case GL_STENCIL_ATTACHMENT:
   3207             break;
   3208          case GL_COLOR_ATTACHMENT0:
   3209          case GL_COLOR_ATTACHMENT1:
   3210          case GL_COLOR_ATTACHMENT2:
   3211          case GL_COLOR_ATTACHMENT3:
   3212          case GL_COLOR_ATTACHMENT4:
   3213          case GL_COLOR_ATTACHMENT5:
   3214          case GL_COLOR_ATTACHMENT6:
   3215          case GL_COLOR_ATTACHMENT7:
   3216          case GL_COLOR_ATTACHMENT8:
   3217          case GL_COLOR_ATTACHMENT9:
   3218          case GL_COLOR_ATTACHMENT10:
   3219          case GL_COLOR_ATTACHMENT11:
   3220          case GL_COLOR_ATTACHMENT12:
   3221          case GL_COLOR_ATTACHMENT13:
   3222          case GL_COLOR_ATTACHMENT14:
   3223          case GL_COLOR_ATTACHMENT15: {
   3224             const int k = attachments[i] - GL_COLOR_ATTACHMENT0;
   3225             if (k >= ctx->Const.MaxColorAttachments) {
   3226                _mesa_error(ctx, GL_INVALID_OPERATION,
   3227                            "%s(attachment >= max. color attachments)", name);
   3228                return;
   3229             }
   3230          }
   3231          default:
   3232             goto invalid_enum;
   3233          }
   3234       }
   3235    }
   3236 
   3237    /* We don't actually do anything for this yet.  Just return after
   3238     * validating the parameters and generating the required errors.
   3239     */
   3240    return;
   3241 
   3242 invalid_enum:
   3243    _mesa_error(ctx, GL_INVALID_ENUM, "%s(attachment)", name);
   3244    return;
   3245 }
   3246 
   3247 void GLAPIENTRY
   3248 _mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
   3249                                const GLenum *attachments, GLint x, GLint y,
   3250                                GLsizei width, GLsizei height)
   3251 {
   3252    invalidate_framebuffer_storage(target, numAttachments, attachments,
   3253                                   x, y, width, height,
   3254                                   "glInvalidateSubFramebuffer");
   3255 }
   3256 
   3257 void GLAPIENTRY
   3258 _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
   3259                             const GLenum *attachments)
   3260 {
   3261    /* The GL_ARB_invalidate_subdata spec says:
   3262     *
   3263     *     "The command
   3264     *
   3265     *        void InvalidateFramebuffer(enum target,
   3266     *                                   sizei numAttachments,
   3267     *                                   const enum *attachments);
   3268     *
   3269     *     is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
   3270     *     <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
   3271     *     <MAX_VIEWPORT_DIMS[1]> respectively."
   3272     */
   3273    invalidate_framebuffer_storage(target, numAttachments, attachments,
   3274                                   0, 0, MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
   3275                                   "glInvalidateFramebuffer");
   3276 }
   3277