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