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