Subversion Repositories Kolibri OS

Rev

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