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