Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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