1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26/**
27 * \file buffers.c
28 * glReadBuffer, DrawBuffer functions.
29 */
30
31
32
33#include "glheader.h"
34#include "buffers.h"
35#include "context.h"
36#include "enums.h"
37#include "fbobject.h"
38#include "mtypes.h"
39#include "util/bitscan.h"
40#include "util/u_math.h"
41
42
43#define BAD_MASK ~0u
44
45
46/**
47 * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are
48 * available to the rendering context (for drawing or reading).
49 * This depends on the type of framebuffer.  For window system framebuffers
50 * we look at the framebuffer's visual.  But for user-create framebuffers we
51 * look at the number of supported color attachments.
52 * \param fb  the framebuffer to draw to, or read from
53 * \return  bitmask of BUFFER_BIT_* flags
54 */
55static GLbitfield
56supported_buffer_bitmask(const struct gl_context *ctx,
57                         const struct gl_framebuffer *fb)
58{
59   GLbitfield mask = 0x0;
60
61   if (_mesa_is_user_fbo(fb)) {
62      /* A user-created renderbuffer */
63      mask = ((1 << ctx->Const.MaxColorAttachments) - 1) << BUFFER_COLOR0;
64   }
65   else {
66      /* A window system framebuffer */
67      GLint i;
68      mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
69      if (fb->Visual.stereoMode) {
70         mask |= BUFFER_BIT_FRONT_RIGHT;
71         if (fb->Visual.doubleBufferMode) {
72            mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
73         }
74      }
75      else if (fb->Visual.doubleBufferMode) {
76         mask |= BUFFER_BIT_BACK_LEFT;
77      }
78
79      for (i = 0; i < fb->Visual.numAuxBuffers; i++) {
80         mask |= (BUFFER_BIT_AUX0 << i);
81      }
82   }
83
84   return mask;
85}
86
87static GLenum
88back_to_front_if_single_buffered(const struct gl_context *ctx, GLenum buffer)
89{
90   /* If the front buffer is the only buffer, GL_BACK and all other flags
91    * that include BACK select the front buffer for drawing. There are
92    * several reasons we want to do this.
93    *
94    * 1) OpenGL ES 3.0 requires it:
95    *
96    *   Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
97    *   ES 3.0.1 specification says:
98    *
99    *     "When draw buffer zero is BACK, color values are written
100    *     into the sole buffer for single-buffered contexts, or into
101    *     the back buffer for double-buffered contexts."
102    *
103    *   We also do this for GLES 1 and 2 because those APIs have no
104    *   concept of selecting the front and back buffer anyway and it's
105    *   convenient to be able to maintain the magic behaviour of
106    *   GL_BACK in that case.
107    *
108    * 2) Pbuffers are back buffers from the application point of view,
109    *    but they are front buffers from the Mesa point of view,
110    *    because they are always single buffered.
111    */
112   if (!ctx->DrawBuffer->Visual.doubleBufferMode) {
113      switch (buffer) {
114      case GL_BACK:
115         buffer = GL_FRONT;
116         break;
117      case GL_BACK_RIGHT:
118         buffer = GL_FRONT_RIGHT;
119         break;
120      case GL_BACK_LEFT:
121         buffer = GL_FRONT_LEFT;
122         break;
123      }
124   }
125
126   return buffer;
127}
128
129/**
130 * Helper routine used by glDrawBuffer and glDrawBuffersARB.
131 * Given a GLenum naming one or more color buffers (such as
132 * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags.
133 */
134static GLbitfield
135draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
136{
137   buffer = back_to_front_if_single_buffered(ctx, buffer);
138
139   switch (buffer) {
140      case GL_NONE:
141         return 0;
142      case GL_FRONT:
143         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
144      case GL_BACK:
145         return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
146      case GL_RIGHT:
147         return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
148      case GL_FRONT_RIGHT:
149         return BUFFER_BIT_FRONT_RIGHT;
150      case GL_BACK_RIGHT:
151         return BUFFER_BIT_BACK_RIGHT;
152      case GL_BACK_LEFT:
153         return BUFFER_BIT_BACK_LEFT;
154      case GL_FRONT_AND_BACK:
155         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT
156              | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
157      case GL_LEFT:
158         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT;
159      case GL_FRONT_LEFT:
160         return BUFFER_BIT_FRONT_LEFT;
161      case GL_AUX0:
162         return BUFFER_BIT_AUX0;
163      case GL_AUX1:
164      case GL_AUX2:
165      case GL_AUX3:
166         return 1 << BUFFER_COUNT; /* invalid, but not BAD_MASK */
167      case GL_COLOR_ATTACHMENT0_EXT:
168         return BUFFER_BIT_COLOR0;
169      case GL_COLOR_ATTACHMENT1_EXT:
170         return BUFFER_BIT_COLOR1;
171      case GL_COLOR_ATTACHMENT2_EXT:
172         return BUFFER_BIT_COLOR2;
173      case GL_COLOR_ATTACHMENT3_EXT:
174         return BUFFER_BIT_COLOR3;
175      case GL_COLOR_ATTACHMENT4_EXT:
176         return BUFFER_BIT_COLOR4;
177      case GL_COLOR_ATTACHMENT5_EXT:
178         return BUFFER_BIT_COLOR5;
179      case GL_COLOR_ATTACHMENT6_EXT:
180         return BUFFER_BIT_COLOR6;
181      case GL_COLOR_ATTACHMENT7_EXT:
182         return BUFFER_BIT_COLOR7;
183      default:
184         /* not an error, but also not supported */
185         if (buffer >= GL_COLOR_ATTACHMENT8 && buffer <= GL_COLOR_ATTACHMENT31)
186            return 1 << BUFFER_COUNT;
187         /* error */
188         return BAD_MASK;
189   }
190}
191
192
193/**
194 * Helper routine used by glReadBuffer.
195 * Given a GLenum naming a color buffer, return the index of the corresponding
196 * renderbuffer (a BUFFER_* value).
197 * return BUFFER_NONE for an invalid buffer.
198 */
199static gl_buffer_index
200read_buffer_enum_to_index(const struct gl_context *ctx, GLenum buffer)
201{
202   buffer = back_to_front_if_single_buffered(ctx, buffer);
203
204   switch (buffer) {
205      case GL_FRONT:
206         return BUFFER_FRONT_LEFT;
207      case GL_BACK:
208         return BUFFER_BACK_LEFT;
209      case GL_RIGHT:
210         return BUFFER_FRONT_RIGHT;
211      case GL_FRONT_RIGHT:
212         return BUFFER_FRONT_RIGHT;
213      case GL_BACK_RIGHT:
214         return BUFFER_BACK_RIGHT;
215      case GL_BACK_LEFT:
216         return BUFFER_BACK_LEFT;
217      case GL_LEFT:
218         return BUFFER_FRONT_LEFT;
219      case GL_FRONT_LEFT:
220         return BUFFER_FRONT_LEFT;
221      case GL_AUX0:
222         return BUFFER_AUX0;
223      case GL_FRONT_AND_BACK:
224         return BUFFER_FRONT_LEFT;
225      case GL_AUX1:
226      case GL_AUX2:
227      case GL_AUX3:
228         return BUFFER_COUNT; /* invalid, but not -1 */
229      case GL_COLOR_ATTACHMENT0_EXT:
230         return BUFFER_COLOR0;
231      case GL_COLOR_ATTACHMENT1_EXT:
232         return BUFFER_COLOR1;
233      case GL_COLOR_ATTACHMENT2_EXT:
234         return BUFFER_COLOR2;
235      case GL_COLOR_ATTACHMENT3_EXT:
236         return BUFFER_COLOR3;
237      case GL_COLOR_ATTACHMENT4_EXT:
238         return BUFFER_COLOR4;
239      case GL_COLOR_ATTACHMENT5_EXT:
240         return BUFFER_COLOR5;
241      case GL_COLOR_ATTACHMENT6_EXT:
242         return BUFFER_COLOR6;
243      case GL_COLOR_ATTACHMENT7_EXT:
244         return BUFFER_COLOR7;
245      default:
246         /* not an error, but also not supported */
247         if (buffer >= GL_COLOR_ATTACHMENT8 && buffer <= GL_COLOR_ATTACHMENT31)
248            return BUFFER_COUNT;
249         /* error */
250         return BUFFER_NONE;
251   }
252}
253
254static bool
255is_legal_es3_readbuffer_enum(GLenum buf)
256{
257   return buf == GL_BACK || buf == GL_NONE ||
258          (buf >= GL_COLOR_ATTACHMENT0 && buf <= GL_COLOR_ATTACHMENT31);
259}
260
261/**
262 * Called by glDrawBuffer() and glNamedFramebufferDrawBuffer().
263 * Specify which renderbuffer(s) to draw into for the first color output.
264 * <buffer> can name zero, one, two or four renderbuffers!
265 * \sa _mesa_DrawBuffers
266 *
267 * \param buffer  buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc.
268 *
269 * Note that the behaviour of this function depends on whether the
270 * current ctx->DrawBuffer is a window-system framebuffer or a user-created
271 * framebuffer object.
272 *   In the former case, we update the per-context ctx->Color.DrawBuffer
273 *   state var _and_ the FB's ColorDrawBuffer state.
274 *   In the later case, we update the FB's ColorDrawBuffer state only.
275 *
276 * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the
277 * new FB is a window system FB, we need to re-update the FB's
278 * ColorDrawBuffer state to match the context.  This is handled in
279 * _mesa_update_framebuffer().
280 *
281 * See the GL_EXT_framebuffer_object spec for more info.
282 */
283static ALWAYS_INLINE void
284draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
285            GLenum buffer, const char *caller, bool no_error)
286{
287   GLbitfield destMask;
288
289   FLUSH_VERTICES(ctx, 0);
290
291   if (MESA_VERBOSE & VERBOSE_API) {
292      _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer));
293   }
294
295   if (buffer == GL_NONE) {
296      destMask = 0x0;
297   }
298   else {
299      const GLbitfield supportedMask
300         = supported_buffer_bitmask(ctx, fb);
301      destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
302      if (!no_error && destMask == BAD_MASK) {
303         /* totally bogus buffer */
304         _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", caller,
305                     _mesa_enum_to_string(buffer));
306         return;
307      }
308      destMask &= supportedMask;
309      if (!no_error && destMask == 0x0) {
310         /* none of the named color buffers exist! */
311         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffer %s)",
312                     caller, _mesa_enum_to_string(buffer));
313         return;
314      }
315   }
316
317   /* if we get here, there's no error so set new state */
318   const GLenum16 buffer16 = buffer;
319   _mesa_drawbuffers(ctx, fb, 1, &buffer16, &destMask);
320
321   /* Call device driver function only if fb is the bound draw buffer */
322   if (fb == ctx->DrawBuffer) {
323      if (ctx->Driver.DrawBuffer)
324         ctx->Driver.DrawBuffer(ctx);
325      if (ctx->Driver.DrawBufferAllocate)
326         ctx->Driver.DrawBufferAllocate(ctx);
327   }
328}
329
330
331static void
332draw_buffer_error(struct gl_context *ctx, struct gl_framebuffer *fb,
333                  GLenum buffer, const char *caller)
334{
335   draw_buffer(ctx, fb, buffer, caller, false);
336}
337
338
339static void
340draw_buffer_no_error(struct gl_context *ctx, struct gl_framebuffer *fb,
341                     GLenum buffer, const char *caller)
342{
343   draw_buffer(ctx, fb, buffer, caller, true);
344}
345
346
347void GLAPIENTRY
348_mesa_DrawBuffer_no_error(GLenum buffer)
349{
350   GET_CURRENT_CONTEXT(ctx);
351   draw_buffer_no_error(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer");
352}
353
354
355void GLAPIENTRY
356_mesa_DrawBuffer(GLenum buffer)
357{
358   GET_CURRENT_CONTEXT(ctx);
359   draw_buffer_error(ctx, ctx->DrawBuffer, buffer, "glDrawBuffer");
360}
361
362
363void GLAPIENTRY
364_mesa_NamedFramebufferDrawBuffer_no_error(GLuint framebuffer, GLenum buf)
365{
366   GET_CURRENT_CONTEXT(ctx);
367   struct gl_framebuffer *fb;
368
369   if (framebuffer) {
370      fb = _mesa_lookup_framebuffer(ctx, framebuffer);
371   } else {
372      fb = ctx->WinSysDrawBuffer;
373   }
374
375   draw_buffer_no_error(ctx, fb, buf, "glNamedFramebufferDrawBuffer");
376}
377
378
379void GLAPIENTRY
380_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
381{
382   GET_CURRENT_CONTEXT(ctx);
383   struct gl_framebuffer *fb;
384
385   if (framebuffer) {
386      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
387                                        "glNamedFramebufferDrawBuffer");
388      if (!fb)
389         return;
390   }
391   else
392      fb = ctx->WinSysDrawBuffer;
393
394   draw_buffer_error(ctx, fb, buf, "glNamedFramebufferDrawBuffer");
395}
396
397
398/**
399 * Called by glDrawBuffersARB() and glNamedFramebufferDrawBuffers() to specify
400 * the destination color renderbuffers for N fragment program color outputs.
401 * \sa _mesa_DrawBuffer
402 * \param n  number of outputs
403 * \param buffers  array [n] of renderbuffer names.  Unlike glDrawBuffer, the
404 *                 names cannot specify more than one buffer.  For example,
405 *                 GL_FRONT_AND_BACK is illegal. The only exception is GL_BACK
406 *                 that is considered special and allowed as far as n is one
407 *                 since 4.5.
408 */
409static ALWAYS_INLINE void
410draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n,
411             const GLenum *buffers, const char *caller, bool no_error)
412{
413   GLuint output;
414   GLbitfield usedBufferMask, supportedMask;
415   GLbitfield destMask[MAX_DRAW_BUFFERS];
416
417   FLUSH_VERTICES(ctx, 0);
418
419   if (!no_error) {
420      /* Turns out n==0 is a valid input that should not produce an error.
421       * The remaining code below correctly handles the n==0 case.
422       *
423       * From the OpenGL 3.0 specification, page 258:
424       * "An INVALID_VALUE error is generated if n is greater than
425       *  MAX_DRAW_BUFFERS."
426       */
427      if (n < 0) {
428         _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller);
429         return;
430      }
431
432      if (n > (GLsizei) ctx->Const.MaxDrawBuffers) {
433         _mesa_error(ctx, GL_INVALID_VALUE,
434                     "%s(n > maximum number of draw buffers)", caller);
435         return;
436      }
437
438      /* From the ES 3.0 specification, page 180:
439       * "If the GL is bound to the default framebuffer, then n must be 1
440       *  and the constant must be BACK or NONE."
441       * (same restriction applies with GL_EXT_draw_buffers specification)
442       */
443      if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(fb) &&
444          (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) {
445         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffers)", caller);
446         return;
447      }
448   }
449
450   supportedMask = supported_buffer_bitmask(ctx, fb);
451   usedBufferMask = 0x0;
452
453   /* complicated error checking... */
454   for (output = 0; output < n; output++) {
455      if (!no_error) {
456         /* From the OpenGL 4.5 specification, page 493 (page 515 of the PDF)
457          * "An INVALID_ENUM error is generated if any value in bufs is FRONT,
458          * LEFT, RIGHT, or FRONT_AND_BACK . This restriction applies to both
459          * the default framebuffer and framebuffer objects, and exists because
460          * these constants may themselves refer to multiple buffers, as shown
461          * in table 17.4."
462          *
463          * From the OpenGL 4.5 specification, page 492 (page 514 of the PDF):
464          * "If the default framebuffer is affected, then each of the constants
465          * must be one of the values listed in table 17.6 or the special value
466          * BACK. When BACK is used, n must be 1 and color values are written
467          * into the left buffer for single-buffered contexts, or into the back
468          * left buffer for double-buffered contexts."
469          *
470          * Note "special value BACK". GL_BACK also refers to multiple buffers,
471          * but it is consider a special case here. This is a change on 4.5.
472          * For OpenGL 4.x we check that behaviour. For any previous version we
473          * keep considering it wrong (as INVALID_ENUM).
474          */
475         if (buffers[output] == GL_BACK &&
476             _mesa_is_winsys_fbo(fb) &&
477             _mesa_is_desktop_gl(ctx) &&
478             ctx->Version >= 40) {
479            if (n != 1) {
480               _mesa_error(ctx, GL_INVALID_OPERATION, "%s(with GL_BACK n must be 1)",
481                           caller);
482               return;
483            }
484         } else if (buffers[output] == GL_FRONT ||
485                    buffers[output] == GL_LEFT ||
486                    buffers[output] == GL_RIGHT ||
487                    buffers[output] == GL_FRONT_AND_BACK ||
488                    (buffers[output] == GL_BACK &&
489                     _mesa_is_desktop_gl(ctx))) {
490            _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
491                        caller, _mesa_enum_to_string(buffers[output]));
492            return;
493         }
494      }
495
496      destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
497
498      if (!no_error) {
499         /* From the OpenGL 3.0 specification, page 258:
500          * "Each buffer listed in bufs must be one of the values from tables
501          *  4.5 or 4.6.  Otherwise, an INVALID_ENUM error is generated.
502          */
503         if (destMask[output] == BAD_MASK) {
504            _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)",
505                        caller, _mesa_enum_to_string(buffers[output]));
506            return;
507         }
508
509         /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL ES 3.0
510          * specification says:
511          *
512          *     "If the GL is bound to a draw framebuffer object, the ith
513          *     buffer listed in bufs must be COLOR_ATTACHMENTi or NONE .
514          *     Specifying a buffer out of order, BACK , or COLOR_ATTACHMENTm
515          *     where m is greater than or equal to the value of MAX_-
516          *     COLOR_ATTACHMENTS , will generate the error INVALID_OPERATION .
517          */
518         if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(fb) &&
519             buffers[output] != GL_NONE &&
520             (buffers[output] < GL_COLOR_ATTACHMENT0 ||
521              buffers[output] >= GL_COLOR_ATTACHMENT0 + ctx->Const.MaxColorAttachments)) {
522            _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
523            return;
524         }
525      }
526
527      if (buffers[output] == GL_NONE) {
528         destMask[output] = 0x0;
529      }
530      else {
531         /* Page 259 (page 275 of the PDF) in section 4.2.1 of the OpenGL 3.0
532          * spec (20080923) says:
533          *
534          *     "If the GL is bound to a framebuffer object and DrawBuffers is
535          *     supplied with [...] COLOR_ATTACHMENTm where m is greater than
536          *     or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
537          *     INVALID_OPERATION results."
538          */
539         if (!no_error && _mesa_is_user_fbo(fb) && buffers[output] >=
540             GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) {
541            _mesa_error(ctx, GL_INVALID_OPERATION,
542                        "%s(buffers[%d] >= maximum number of draw buffers)",
543                        caller, output);
544            return;
545         }
546
547         /* From the OpenGL 3.0 specification, page 259:
548          * "If the GL is bound to the default framebuffer and DrawBuffers is
549          *  supplied with a constant (other than NONE) that does not indicate
550          *  any of the color buffers allocated to the GL context by the window
551          *  system, the error INVALID_OPERATION will be generated.
552          *
553          *  If the GL is bound to a framebuffer object and DrawBuffers is
554          *  supplied with a constant from table 4.6 [...] then the error
555          *  INVALID_OPERATION results."
556          */
557         destMask[output] &= supportedMask;
558         if (!no_error) {
559            if (destMask[output] == 0) {
560               _mesa_error(ctx, GL_INVALID_OPERATION,
561                           "%s(unsupported buffer %s)",
562                           caller, _mesa_enum_to_string(buffers[output]));
563               return;
564            }
565
566            /* ES 3.0 is even more restrictive.  From the ES 3.0 spec, page 180:
567             * "If the GL is bound to a framebuffer object, the ith buffer
568             * listed in bufs must be COLOR_ATTACHMENTi or NONE. [...]
569             * INVALID_OPERATION." (same restriction applies with
570             * GL_EXT_draw_buffers specification)
571             */
572            if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(fb) &&
573                buffers[output] != GL_NONE &&
574                buffers[output] != GL_COLOR_ATTACHMENT0 + output) {
575               _mesa_error(ctx, GL_INVALID_OPERATION,
576                           "%s(unsupported buffer %s)",
577                           caller, _mesa_enum_to_string(buffers[output]));
578               return;
579            }
580
581            /* From the OpenGL 3.0 specification, page 258:
582             * "Except for NONE, a buffer may not appear more than once in the
583             * array pointed to by bufs.  Specifying a buffer more then once
584             * will result in the error INVALID_OPERATION."
585             */
586            if (destMask[output] & usedBufferMask) {
587               _mesa_error(ctx, GL_INVALID_OPERATION,
588                           "%s(duplicated buffer %s)",
589                           caller, _mesa_enum_to_string(buffers[output]));
590               return;
591            }
592         }
593
594         /* update bitmask */
595         usedBufferMask |= destMask[output];
596      }
597   }
598
599   /* OK, if we get here, there were no errors so set the new state */
600   GLenum16 buffers16[MAX_DRAW_BUFFERS];
601   for (int i = 0; i < n; i++)
602      buffers16[i] = buffers[i];
603
604   _mesa_drawbuffers(ctx, fb, n, buffers16, destMask);
605
606   /*
607    * Call device driver function if fb is the bound draw buffer.
608    * Note that n can be equal to 0,
609    * in which case we don't want to reference buffers[0], which
610    * may not be valid.
611    */
612   if (fb == ctx->DrawBuffer) {
613      if (ctx->Driver.DrawBuffer)
614         ctx->Driver.DrawBuffer(ctx);
615      if (ctx->Driver.DrawBufferAllocate)
616         ctx->Driver.DrawBufferAllocate(ctx);
617   }
618}
619
620
621static void
622draw_buffers_error(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n,
623                   const GLenum *buffers, const char *caller)
624{
625   draw_buffers(ctx, fb, n, buffers, caller, false);
626}
627
628
629static void
630draw_buffers_no_error(struct gl_context *ctx, struct gl_framebuffer *fb,
631                      GLsizei n, const GLenum *buffers, const char *caller)
632{
633   draw_buffers(ctx, fb, n, buffers, caller, true);
634}
635
636
637void GLAPIENTRY
638_mesa_DrawBuffers_no_error(GLsizei n, const GLenum *buffers)
639{
640   GET_CURRENT_CONTEXT(ctx);
641   draw_buffers_no_error(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers");
642}
643
644
645void GLAPIENTRY
646_mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
647{
648   GET_CURRENT_CONTEXT(ctx);
649   draw_buffers_error(ctx, ctx->DrawBuffer, n, buffers, "glDrawBuffers");
650}
651
652
653void GLAPIENTRY
654_mesa_NamedFramebufferDrawBuffers_no_error(GLuint framebuffer, GLsizei n,
655                                           const GLenum *bufs)
656{
657   GET_CURRENT_CONTEXT(ctx);
658   struct gl_framebuffer *fb;
659
660   if (framebuffer) {
661      fb = _mesa_lookup_framebuffer(ctx, framebuffer);
662   } else {
663      fb = ctx->WinSysDrawBuffer;
664   }
665
666   draw_buffers_no_error(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers");
667}
668
669
670void GLAPIENTRY
671_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n,
672                                  const GLenum *bufs)
673{
674   GET_CURRENT_CONTEXT(ctx);
675   struct gl_framebuffer *fb;
676
677   if (framebuffer) {
678      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
679                                        "glNamedFramebufferDrawBuffers");
680      if (!fb)
681         return;
682   }
683   else
684      fb = ctx->WinSysDrawBuffer;
685
686   draw_buffers_error(ctx, fb, n, bufs, "glNamedFramebufferDrawBuffers");
687}
688
689
690/**
691 * Performs necessary state updates when _mesa_drawbuffers makes an
692 * actual change.
693 */
694static void
695updated_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb)
696{
697   FLUSH_VERTICES(ctx, _NEW_BUFFERS);
698
699   if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) {
700      /* Flag the FBO as requiring validation. */
701      if (_mesa_is_user_fbo(fb)) {
702	 fb->_Status = 0;
703      }
704   }
705}
706
707
708/**
709 * Helper function to set the GL_DRAW_BUFFER state for the given context and
710 * FBO.  Called via glDrawBuffer(), glDrawBuffersARB()
711 *
712 * All error checking will have been done prior to calling this function
713 * so nothing should go wrong at this point.
714 *
715 * \param ctx  current context
716 * \param fb   the desired draw buffer
717 * \param n    number of color outputs to set
718 * \param buffers  array[n] of colorbuffer names, like GL_LEFT.
719 * \param destMask  array[n] of BUFFER_BIT_* bitmasks which correspond to the
720 *                  colorbuffer names.  (i.e. GL_FRONT_AND_BACK =>
721 *                  BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT).
722 */
723void
724_mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
725                  GLuint n, const GLenum16 *buffers,
726                  const GLbitfield *destMask)
727{
728   GLbitfield mask[MAX_DRAW_BUFFERS];
729   GLuint buf;
730
731   if (!destMask) {
732      /* compute destMask values now */
733      const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb);
734      GLuint output;
735      for (output = 0; output < n; output++) {
736         mask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
737         assert(mask[output] != BAD_MASK);
738         mask[output] &= supportedMask;
739      }
740      destMask = mask;
741   }
742
743   /*
744    * destMask[0] may have up to four bits set
745    * (ex: glDrawBuffer(GL_FRONT_AND_BACK)).
746    * Otherwise, destMask[x] can only have one bit set.
747    */
748   if (n > 0 && util_bitcount(destMask[0]) > 1) {
749      GLuint count = 0, destMask0 = destMask[0];
750      while (destMask0) {
751         const gl_buffer_index bufIndex = u_bit_scan(&destMask0);
752         if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
753            updated_drawbuffers(ctx, fb);
754            fb->_ColorDrawBufferIndexes[count] = bufIndex;
755         }
756         count++;
757      }
758      fb->ColorDrawBuffer[0] = buffers[0];
759      fb->_NumColorDrawBuffers = count;
760   }
761   else {
762      GLuint count = 0;
763      for (buf = 0; buf < n; buf++ ) {
764         if (destMask[buf]) {
765            gl_buffer_index bufIndex = ffs(destMask[buf]) - 1;
766            /* only one bit should be set in the destMask[buf] field */
767            assert(util_bitcount(destMask[buf]) == 1);
768            if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
769	       updated_drawbuffers(ctx, fb);
770               fb->_ColorDrawBufferIndexes[buf] = bufIndex;
771            }
772            count = buf + 1;
773         }
774         else {
775            if (fb->_ColorDrawBufferIndexes[buf] != BUFFER_NONE) {
776	       updated_drawbuffers(ctx, fb);
777               fb->_ColorDrawBufferIndexes[buf] = BUFFER_NONE;
778            }
779         }
780         fb->ColorDrawBuffer[buf] = buffers[buf];
781      }
782      fb->_NumColorDrawBuffers = count;
783   }
784
785   /* set remaining outputs to BUFFER_NONE */
786   for (buf = fb->_NumColorDrawBuffers; buf < ctx->Const.MaxDrawBuffers; buf++) {
787      if (fb->_ColorDrawBufferIndexes[buf] != BUFFER_NONE) {
788         updated_drawbuffers(ctx, fb);
789         fb->_ColorDrawBufferIndexes[buf] = BUFFER_NONE;
790      }
791   }
792   for (buf = n; buf < ctx->Const.MaxDrawBuffers; buf++) {
793      fb->ColorDrawBuffer[buf] = GL_NONE;
794   }
795
796   if (_mesa_is_winsys_fbo(fb)) {
797      /* also set context drawbuffer state */
798      for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
799         if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
800	    updated_drawbuffers(ctx, fb);
801            ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf];
802         }
803      }
804   }
805}
806
807
808/**
809 * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc.
810 * from the context's Color.DrawBuffer[] state.
811 * Use when changing contexts.
812 */
813void
814_mesa_update_draw_buffers(struct gl_context *ctx)
815{
816   /* should be a window system FBO */
817   assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
818
819   _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers,
820                     ctx->Color.DrawBuffer, NULL);
821}
822
823
824/**
825 * Like \sa _mesa_drawbuffers(), this is a helper function for setting
826 * GL_READ_BUFFER state for the given context and FBO.
827 * Note that all error checking should have been done before calling
828 * this function.
829 * \param ctx  the rendering context
830 * \param fb  the framebuffer object to update
831 * \param buffer  GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc.
832 * \param bufferIndex  the numerical index corresponding to 'buffer'
833 */
834void
835_mesa_readbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
836                 GLenum buffer, gl_buffer_index bufferIndex)
837{
838   if ((fb == ctx->ReadBuffer) && _mesa_is_winsys_fbo(fb)) {
839      /* Only update the per-context READ_BUFFER state if we're bound to
840       * a window-system framebuffer.
841       */
842      ctx->Pixel.ReadBuffer = buffer;
843   }
844
845   fb->ColorReadBuffer = buffer;
846   fb->_ColorReadBufferIndex = bufferIndex;
847
848   ctx->NewState |= _NEW_BUFFERS;
849}
850
851
852
853/**
854 * Called by glReadBuffer and glNamedFramebufferReadBuffer to set the source
855 * renderbuffer for reading pixels.
856 * \param mode color buffer such as GL_FRONT, GL_BACK, etc.
857 */
858static ALWAYS_INLINE void
859read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
860            GLenum buffer, const char *caller, bool no_error)
861{
862   gl_buffer_index srcBuffer;
863
864   FLUSH_VERTICES(ctx, 0);
865
866   if (MESA_VERBOSE & VERBOSE_API)
867      _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer));
868
869   if (buffer == GL_NONE) {
870      /* This is legal--it means that no buffer should be bound for reading. */
871      srcBuffer = BUFFER_NONE;
872   }
873   else {
874      /* general case / window-system framebuffer */
875      if (!no_error &&_mesa_is_gles3(ctx) &&
876          !is_legal_es3_readbuffer_enum(buffer))
877         srcBuffer = BUFFER_NONE;
878      else
879         srcBuffer = read_buffer_enum_to_index(ctx, buffer);
880
881      if (!no_error) {
882         GLbitfield supportedMask;
883
884         if (srcBuffer == BUFFER_NONE) {
885            _mesa_error(ctx, GL_INVALID_ENUM,
886                        "%s(invalid buffer %s)", caller,
887                        _mesa_enum_to_string(buffer));
888            return;
889         }
890
891         supportedMask = supported_buffer_bitmask(ctx, fb);
892         if (((1 << srcBuffer) & supportedMask) == 0) {
893            _mesa_error(ctx, GL_INVALID_OPERATION,
894                        "%s(invalid buffer %s)", caller,
895                        _mesa_enum_to_string(buffer));
896            return;
897         }
898      }
899   }
900
901   /* OK, all error checking has been completed now */
902
903   _mesa_readbuffer(ctx, fb, buffer, srcBuffer);
904
905   /* Call the device driver function only if fb is the bound read buffer */
906   if (fb == ctx->ReadBuffer) {
907      if (ctx->Driver.ReadBuffer)
908         ctx->Driver.ReadBuffer(ctx, buffer);
909   }
910}
911
912
913static void
914read_buffer_err(struct gl_context *ctx, struct gl_framebuffer *fb,
915                GLenum buffer, const char *caller)
916{
917   read_buffer(ctx, fb, buffer, caller, false);
918}
919
920
921static void
922read_buffer_no_error(struct gl_context *ctx, struct gl_framebuffer *fb,
923                     GLenum buffer, const char *caller)
924{
925   read_buffer(ctx, fb, buffer, caller, true);
926}
927
928
929void GLAPIENTRY
930_mesa_ReadBuffer_no_error(GLenum buffer)
931{
932   GET_CURRENT_CONTEXT(ctx);
933   read_buffer_no_error(ctx, ctx->ReadBuffer, buffer, "glReadBuffer");
934}
935
936
937void GLAPIENTRY
938_mesa_ReadBuffer(GLenum buffer)
939{
940   GET_CURRENT_CONTEXT(ctx);
941   read_buffer_err(ctx, ctx->ReadBuffer, buffer, "glReadBuffer");
942}
943
944
945void GLAPIENTRY
946_mesa_NamedFramebufferReadBuffer_no_error(GLuint framebuffer, GLenum src)
947{
948   GET_CURRENT_CONTEXT(ctx);
949
950   struct gl_framebuffer *fb;
951
952   if (framebuffer) {
953      fb = _mesa_lookup_framebuffer(ctx, framebuffer);
954   } else {
955      fb = ctx->WinSysReadBuffer;
956   }
957
958   read_buffer_no_error(ctx, fb, src, "glNamedFramebufferReadBuffer");
959}
960
961
962void GLAPIENTRY
963_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
964{
965   GET_CURRENT_CONTEXT(ctx);
966   struct gl_framebuffer *fb;
967
968   if (framebuffer) {
969      fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
970                                        "glNamedFramebufferReadBuffer");
971      if (!fb)
972         return;
973   }
974   else
975      fb = ctx->WinSysReadBuffer;
976
977   read_buffer_err(ctx, fb, src, "glNamedFramebufferReadBuffer");
978}
979