OSDN Git Service

mesa: some C99 tidy ups for framebuffer.c
[android-x86/external-mesa.git] / src / mesa / main / framebuffer.c
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2008  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  * Functions for allocating/managing framebuffers and renderbuffers.
28  * Also, routines for reading/writing renderbuffer data as ubytes,
29  * ushorts, uints, etc.
30  */
31
32 #include <stdio.h>
33 #include "glheader.h"
34 #include "imports.h"
35 #include "blend.h"
36 #include "buffers.h"
37 #include "context.h"
38 #include "enums.h"
39 #include "formats.h"
40 #include "macros.h"
41 #include "mtypes.h"
42 #include "fbobject.h"
43 #include "framebuffer.h"
44 #include "renderbuffer.h"
45 #include "texobj.h"
46 #include "glformats.h"
47 #include "state.h"
48
49
50
51 /**
52  * Compute/set the _DepthMax field for the given framebuffer.
53  * This value depends on the Z buffer resolution.
54  */
55 static void
56 compute_depth_max(struct gl_framebuffer *fb)
57 {
58    if (fb->Visual.depthBits == 0) {
59       /* Special case.  Even if we don't have a depth buffer we need
60        * good values for DepthMax for Z vertex transformation purposes
61        * and for per-fragment fog computation.
62        */
63       fb->_DepthMax = (1 << 16) - 1;
64    }
65    else if (fb->Visual.depthBits < 32) {
66       fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
67    }
68    else {
69       /* Special case since shift values greater than or equal to the
70        * number of bits in the left hand expression's type are undefined.
71        */
72       fb->_DepthMax = 0xffffffff;
73    }
74    fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
75
76    /* Minimum resolvable depth value, for polygon offset */
77    fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
78 }
79
80 /**
81  * Create and initialize a gl_framebuffer object.
82  * This is intended for creating _window_system_ framebuffers, not generic
83  * framebuffer objects ala GL_EXT_framebuffer_object.
84  *
85  * \sa _mesa_new_framebuffer
86  */
87 struct gl_framebuffer *
88 _mesa_create_framebuffer(const struct gl_config *visual)
89 {
90    struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
91    assert(visual);
92    if (fb) {
93       _mesa_initialize_window_framebuffer(fb, visual);
94    }
95    return fb;
96 }
97
98
99 /**
100  * Allocate a new gl_framebuffer object.
101  * This is the default function for ctx->Driver.NewFramebuffer().
102  * This is for allocating user-created framebuffers, not window-system
103  * framebuffers!
104  * \sa _mesa_create_framebuffer
105  */
106 struct gl_framebuffer *
107 _mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
108 {
109    struct gl_framebuffer *fb;
110    (void) ctx;
111    assert(name != 0);
112    fb = CALLOC_STRUCT(gl_framebuffer);
113    if (fb) {
114       _mesa_initialize_user_framebuffer(fb, name);
115    }
116    return fb;
117 }
118
119
120 /**
121  * Initialize a gl_framebuffer object.  Typically used to initialize
122  * window system-created framebuffers, not user-created framebuffers.
123  * \sa _mesa_initialize_user_framebuffer
124  */
125 void
126 _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
127                                      const struct gl_config *visual)
128 {
129    assert(fb);
130    assert(visual);
131
132    memset(fb, 0, sizeof(struct gl_framebuffer));
133
134    simple_mtx_init(&fb->Mutex, mtx_plain);
135
136    fb->RefCount = 1;
137
138    /* save the visual */
139    fb->Visual = *visual;
140
141    /* Init read/draw renderbuffer state */
142    if (visual->doubleBufferMode) {
143       fb->_NumColorDrawBuffers = 1;
144       fb->ColorDrawBuffer[0] = GL_BACK;
145       fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
146       fb->ColorReadBuffer = GL_BACK;
147       fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
148    }
149    else {
150       fb->_NumColorDrawBuffers = 1;
151       fb->ColorDrawBuffer[0] = GL_FRONT;
152       fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
153       fb->ColorReadBuffer = GL_FRONT;
154       fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
155    }
156
157    fb->Delete = _mesa_destroy_framebuffer;
158    fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
159    fb->_AllColorBuffersFixedPoint = !visual->floatMode;
160    fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
161    fb->_HasAttachments = true;
162
163    compute_depth_max(fb);
164 }
165
166
167 /**
168  * Initialize a user-created gl_framebuffer object.
169  * \sa _mesa_initialize_window_framebuffer
170  */
171 void
172 _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
173 {
174    assert(fb);
175    assert(name);
176
177    memset(fb, 0, sizeof(struct gl_framebuffer));
178
179    fb->Name = name;
180    fb->RefCount = 1;
181    fb->_NumColorDrawBuffers = 1;
182    fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
183    fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
184    fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
185    fb->_ColorReadBufferIndex = BUFFER_COLOR0;
186    fb->Delete = _mesa_destroy_framebuffer;
187    simple_mtx_init(&fb->Mutex, mtx_plain);
188 }
189
190
191 /**
192  * Deallocate buffer and everything attached to it.
193  * Typically called via the gl_framebuffer->Delete() method.
194  */
195 void
196 _mesa_destroy_framebuffer(struct gl_framebuffer *fb)
197 {
198    if (fb) {
199       _mesa_free_framebuffer_data(fb);
200       free(fb->Label);
201       free(fb);
202    }
203 }
204
205
206 /**
207  * Free all the data hanging off the given gl_framebuffer, but don't free
208  * the gl_framebuffer object itself.
209  */
210 void
211 _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
212 {
213    assert(fb);
214    assert(fb->RefCount == 0);
215
216    simple_mtx_destroy(&fb->Mutex);
217
218    for (unsigned i = 0; i < BUFFER_COUNT; i++) {
219       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
220       if (att->Renderbuffer) {
221          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
222       }
223       if (att->Texture) {
224          _mesa_reference_texobj(&att->Texture, NULL);
225       }
226       assert(!att->Renderbuffer);
227       assert(!att->Texture);
228       att->Type = GL_NONE;
229    }
230 }
231
232
233 /**
234  * Set *ptr to point to fb, with refcounting and locking.
235  * This is normally only called from the _mesa_reference_framebuffer() macro
236  * when there's a real pointer change.
237  */
238 void
239 _mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
240                              struct gl_framebuffer *fb)
241 {
242    if (*ptr) {
243       /* unreference old renderbuffer */
244       GLboolean deleteFlag = GL_FALSE;
245       struct gl_framebuffer *oldFb = *ptr;
246
247       simple_mtx_lock(&oldFb->Mutex);
248       assert(oldFb->RefCount > 0);
249       oldFb->RefCount--;
250       deleteFlag = (oldFb->RefCount == 0);
251       simple_mtx_unlock(&oldFb->Mutex);
252
253       if (deleteFlag)
254          oldFb->Delete(oldFb);
255
256       *ptr = NULL;
257    }
258
259    if (fb) {
260       simple_mtx_lock(&fb->Mutex);
261       fb->RefCount++;
262       simple_mtx_unlock(&fb->Mutex);
263       *ptr = fb;
264    }
265 }
266
267
268 /**
269  * Resize the given framebuffer's renderbuffers to the new width and height.
270  * This should only be used for window-system framebuffers, not
271  * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
272  * This will typically be called directly from a device driver.
273  *
274  * \note it's possible for ctx to be null since a window can be resized
275  * without a currently bound rendering context.
276  */
277 void
278 _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
279                          GLuint width, GLuint height)
280 {
281    /* XXX I think we could check if the size is not changing
282     * and return early.
283     */
284
285    /* Can only resize win-sys framebuffer objects */
286    assert(_mesa_is_winsys_fbo(fb));
287
288    for (unsigned i = 0; i < BUFFER_COUNT; i++) {
289       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
290       if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
291          struct gl_renderbuffer *rb = att->Renderbuffer;
292          /* only resize if size is changing */
293          if (rb->Width != width || rb->Height != height) {
294             if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
295                assert(rb->Width == width);
296                assert(rb->Height == height);
297             }
298             else {
299                _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
300                /* no return */
301             }
302          }
303       }
304    }
305
306    fb->Width = width;
307    fb->Height = height;
308
309    if (ctx) {
310       /* update scissor / window bounds */
311       _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
312       /* Signal new buffer state so that swrast will update its clipping
313        * info (the CLIP_BIT flag).
314        */
315       ctx->NewState |= _NEW_BUFFERS;
316    }
317 }
318
319 /**
320  * Given a bounding box, intersect the bounding box with the scissor of
321  * a specified vieport.
322  *
323  * \param ctx     GL context.
324  * \param idx     Index of the desired viewport
325  * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
326  *                xmax, ymin, ymax.
327  */
328 void
329 _mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
330                                      unsigned idx, int *bbox)
331 {
332    if (ctx->Scissor.EnableFlags & (1u << idx)) {
333       if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) {
334          bbox[0] = ctx->Scissor.ScissorArray[idx].X;
335       }
336       if (ctx->Scissor.ScissorArray[idx].Y > bbox[2]) {
337          bbox[2] = ctx->Scissor.ScissorArray[idx].Y;
338       }
339       if (ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width < bbox[1]) {
340          bbox[1] = ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width;
341       }
342       if (ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height < bbox[3]) {
343          bbox[3] = ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height;
344       }
345       /* finally, check for empty region */
346       if (bbox[0] > bbox[1]) {
347          bbox[0] = bbox[1];
348       }
349       if (bbox[2] > bbox[3]) {
350          bbox[2] = bbox[3];
351       }
352    }
353 }
354
355 /**
356  * Calculate the inclusive bounding box for the scissor of a specific viewport
357  *
358  * \param ctx     GL context.
359  * \param buffer  Framebuffer to be checked against
360  * \param idx     Index of the desired viewport
361  * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
362  *                xmax, ymin, ymax.
363  *
364  * \warning This function assumes that the framebuffer dimensions are up to
365  * date.
366  *
367  * \sa _mesa_clip_to_region
368  */
369 static void
370 scissor_bounding_box(const struct gl_context *ctx,
371                      const struct gl_framebuffer *buffer,
372                      unsigned idx, int *bbox)
373 {
374    bbox[0] = 0;
375    bbox[2] = 0;
376    bbox[1] = buffer->Width;
377    bbox[3] = buffer->Height;
378
379    _mesa_intersect_scissor_bounding_box(ctx, idx, bbox);
380
381    assert(bbox[0] <= bbox[1]);
382    assert(bbox[2] <= bbox[3]);
383 }
384
385 /**
386  * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
387  * These values are computed from the buffer's width and height and
388  * the scissor box, if it's enabled.
389  * \param ctx  the GL context.
390  */
391 void
392 _mesa_update_draw_buffer_bounds(struct gl_context *ctx,
393                                 struct gl_framebuffer *buffer)
394 {
395    int bbox[4];
396
397    if (!buffer)
398       return;
399
400    /* Default to the first scissor as that's always valid */
401    scissor_bounding_box(ctx, buffer, 0, bbox);
402    buffer->_Xmin = bbox[0];
403    buffer->_Ymin = bbox[2];
404    buffer->_Xmax = bbox[1];
405    buffer->_Ymax = bbox[3];
406 }
407
408
409 /**
410  * The glGet queries of the framebuffer red/green/blue size, stencil size,
411  * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
412  * change depending on the renderbuffer bindings.  This function updates
413  * the given framebuffer's Visual from the current renderbuffer bindings.
414  *
415  * This may apply to user-created framebuffers or window system framebuffers.
416  *
417  * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
418  * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
419  * The former one is used to convert floating point depth values into
420  * integer Z values.
421  */
422 void
423 _mesa_update_framebuffer_visual(struct gl_context *ctx,
424                                 struct gl_framebuffer *fb)
425 {
426    memset(&fb->Visual, 0, sizeof(fb->Visual));
427    fb->Visual.rgbMode = GL_TRUE; /* assume this */
428
429    /* find first RGB renderbuffer */
430    for (unsigned i = 0; i < BUFFER_COUNT; i++) {
431       if (fb->Attachment[i].Renderbuffer) {
432          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
433          const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
434          const mesa_format fmt = rb->Format;
435
436          /* Grab samples and sampleBuffers from any attachment point (assuming
437           * the framebuffer is complete, we'll get the same answer from all
438           * attachments).
439           */
440          fb->Visual.samples = rb->NumSamples;
441          fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
442
443          if (_mesa_is_legal_color_format(ctx, baseFormat)) {
444             fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
445             fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
446             fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
447             fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
448             fb->Visual.rgbBits = fb->Visual.redBits
449                + fb->Visual.greenBits + fb->Visual.blueBits;
450             if (_mesa_get_format_color_encoding(fmt) == GL_SRGB)
451                 fb->Visual.sRGBCapable = ctx->Extensions.EXT_framebuffer_sRGB;
452             break;
453          }
454       }
455    }
456
457    fb->Visual.floatMode = GL_FALSE;
458    for (unsigned i = 0; i < BUFFER_COUNT; i++) {
459       if (fb->Attachment[i].Renderbuffer) {
460          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
461          const mesa_format fmt = rb->Format;
462
463          if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
464             fb->Visual.floatMode = GL_TRUE;
465             break;
466          }
467       }
468    }
469
470    if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
471       const struct gl_renderbuffer *rb =
472          fb->Attachment[BUFFER_DEPTH].Renderbuffer;
473       const mesa_format fmt = rb->Format;
474       fb->Visual.haveDepthBuffer = GL_TRUE;
475       fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
476    }
477
478    if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
479       const struct gl_renderbuffer *rb =
480          fb->Attachment[BUFFER_STENCIL].Renderbuffer;
481       const mesa_format fmt = rb->Format;
482       fb->Visual.haveStencilBuffer = GL_TRUE;
483       fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
484    }
485
486    if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
487       const struct gl_renderbuffer *rb =
488          fb->Attachment[BUFFER_ACCUM].Renderbuffer;
489       const mesa_format fmt = rb->Format;
490       fb->Visual.haveAccumBuffer = GL_TRUE;
491       fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
492       fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
493       fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
494       fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
495    }
496
497    compute_depth_max(fb);
498 }
499
500
501 /*
502  * Example DrawBuffers scenarios:
503  *
504  * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
505  * "gl_FragColor" or program writes to the "result.color" register:
506  *
507  *   fragment color output   renderbuffer
508  *   ---------------------   ---------------
509  *   color[0]                Front, Back
510  *
511  *
512  * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
513  * gl_FragData[i] or program writes to result.color[i] registers:
514  *
515  *   fragment color output   renderbuffer
516  *   ---------------------   ---------------
517  *   color[0]                Front
518  *   color[1]                Aux0
519  *   color[3]                Aux1
520  *
521  *
522  * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
523  * gl_FragColor, or fixed function:
524  *
525  *   fragment color output   renderbuffer
526  *   ---------------------   ---------------
527  *   color[0]                Front, Aux0, Aux1
528  *
529  *
530  * In either case, the list of renderbuffers is stored in the
531  * framebuffer->_ColorDrawBuffers[] array and
532  * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
533  * The renderer (like swrast) has to look at the current fragment shader
534  * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
535  * how to map color outputs to renderbuffers.
536  *
537  * Note that these two calls are equivalent (for fixed function fragment
538  * shading anyway):
539  *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
540  *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
541  */
542
543
544
545
546 /**
547  * Update the (derived) list of color drawing renderbuffer pointers.
548  * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
549  * writing colors.
550  */
551 static void
552 update_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
553 {
554    GLuint output;
555
556    /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
557    fb->_ColorDrawBuffers[0] = NULL;
558
559    for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
560       gl_buffer_index buf = fb->_ColorDrawBufferIndexes[output];
561       if (buf != BUFFER_NONE) {
562          fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
563       }
564       else {
565          fb->_ColorDrawBuffers[output] = NULL;
566       }
567    }
568 }
569
570
571 /**
572  * Update the (derived) color read renderbuffer pointer.
573  * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
574  */
575 static void
576 update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
577 {
578    (void) ctx;
579    if (fb->_ColorReadBufferIndex == BUFFER_NONE ||
580        fb->DeletePending ||
581        fb->Width == 0 ||
582        fb->Height == 0) {
583       fb->_ColorReadBuffer = NULL; /* legal! */
584    }
585    else {
586       assert(fb->_ColorReadBufferIndex >= 0);
587       assert(fb->_ColorReadBufferIndex < BUFFER_COUNT);
588       fb->_ColorReadBuffer
589          = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
590    }
591 }
592
593
594 /**
595  * Update a gl_framebuffer's derived state.
596  *
597  * Specifically, update these framebuffer fields:
598  *    _ColorDrawBuffers
599  *    _NumColorDrawBuffers
600  *    _ColorReadBuffer
601  *
602  * If the framebuffer is user-created, make sure it's complete.
603  *
604  * The following functions (at least) can effect framebuffer state:
605  * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
606  * glRenderbufferStorageEXT.
607  */
608 static void
609 update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
610 {
611    if (_mesa_is_winsys_fbo(fb)) {
612       /* This is a window-system framebuffer */
613       /* Need to update the FB's GL_DRAW_BUFFER state to match the
614        * context state (GL_READ_BUFFER too).
615        */
616       if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
617          _mesa_drawbuffers(ctx, fb, ctx->Const.MaxDrawBuffers,
618                            ctx->Color.DrawBuffer, NULL);
619       }
620    }
621    else {
622       /* This is a user-created framebuffer.
623        * Completeness only matters for user-created framebuffers.
624        */
625       if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
626          _mesa_test_framebuffer_completeness(ctx, fb);
627       }
628    }
629
630    /* Strictly speaking, we don't need to update the draw-state
631     * if this FB is bound as ctx->ReadBuffer (and conversely, the
632     * read-state if this FB is bound as ctx->DrawBuffer), but no
633     * harm.
634     */
635    update_color_draw_buffers(ctx, fb);
636    update_color_read_buffer(ctx, fb);
637
638    compute_depth_max(fb);
639 }
640
641
642 /**
643  * Update state related to the draw/read framebuffers.
644  */
645 void
646 _mesa_update_framebuffer(struct gl_context *ctx,
647                          struct gl_framebuffer *readFb,
648                          struct gl_framebuffer *drawFb)
649 {
650    assert(ctx);
651
652    update_framebuffer(ctx, drawFb);
653    if (readFb != drawFb)
654       update_framebuffer(ctx, readFb);
655
656    _mesa_update_clamp_vertex_color(ctx, drawFb);
657    _mesa_update_clamp_fragment_color(ctx, drawFb);
658 }
659
660
661 /**
662  * Check if the renderbuffer for a read/draw operation exists.
663  * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
664  *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
665  * \param reading  if TRUE, we're going to read from the buffer,
666                    if FALSE, we're going to write to the buffer.
667  * \return GL_TRUE if buffer exists, GL_FALSE otherwise
668  */
669 static GLboolean
670 renderbuffer_exists(struct gl_context *ctx,
671                     struct gl_framebuffer *fb,
672                     GLenum format,
673                     GLboolean reading)
674 {
675    const struct gl_renderbuffer_attachment *att = fb->Attachment;
676
677    /* If we don't know the framebuffer status, update it now */
678    if (fb->_Status == 0) {
679       _mesa_test_framebuffer_completeness(ctx, fb);
680    }
681
682    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
683       return GL_FALSE;
684    }
685
686    switch (format) {
687    case GL_COLOR:
688    case GL_RED:
689    case GL_GREEN:
690    case GL_BLUE:
691    case GL_ALPHA:
692    case GL_LUMINANCE:
693    case GL_LUMINANCE_ALPHA:
694    case GL_INTENSITY:
695    case GL_RG:
696    case GL_RGB:
697    case GL_BGR:
698    case GL_RGBA:
699    case GL_BGRA:
700    case GL_ABGR_EXT:
701    case GL_RED_INTEGER_EXT:
702    case GL_RG_INTEGER:
703    case GL_GREEN_INTEGER_EXT:
704    case GL_BLUE_INTEGER_EXT:
705    case GL_ALPHA_INTEGER_EXT:
706    case GL_RGB_INTEGER_EXT:
707    case GL_RGBA_INTEGER_EXT:
708    case GL_BGR_INTEGER_EXT:
709    case GL_BGRA_INTEGER_EXT:
710    case GL_LUMINANCE_INTEGER_EXT:
711    case GL_LUMINANCE_ALPHA_INTEGER_EXT:
712       if (reading) {
713          /* about to read from a color buffer */
714          const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer;
715          if (!readBuf) {
716             return GL_FALSE;
717          }
718          assert(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 ||
719                 _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 ||
720                 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 ||
721                 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 ||
722                 _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0);
723       }
724       else {
725          /* about to draw to zero or more color buffers (none is OK) */
726          return GL_TRUE;
727       }
728       break;
729    case GL_DEPTH:
730    case GL_DEPTH_COMPONENT:
731       if (att[BUFFER_DEPTH].Type == GL_NONE) {
732          return GL_FALSE;
733       }
734       break;
735    case GL_STENCIL:
736    case GL_STENCIL_INDEX:
737       if (att[BUFFER_STENCIL].Type == GL_NONE) {
738          return GL_FALSE;
739       }
740       break;
741    case GL_DEPTH_STENCIL_EXT:
742       if (att[BUFFER_DEPTH].Type == GL_NONE ||
743           att[BUFFER_STENCIL].Type == GL_NONE) {
744          return GL_FALSE;
745       }
746       break;
747    default:
748       _mesa_problem(ctx,
749                     "Unexpected format 0x%x in renderbuffer_exists",
750                     format);
751       return GL_FALSE;
752    }
753
754    /* OK */
755    return GL_TRUE;
756 }
757
758
759 /**
760  * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
761  * glCopyTex[Sub]Image, etc) exists.
762  * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
763  *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
764  * \return GL_TRUE if buffer exists, GL_FALSE otherwise
765  */
766 GLboolean
767 _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
768 {
769    return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE);
770 }
771
772
773 /**
774  * As above, but for drawing operations.
775  */
776 GLboolean
777 _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
778 {
779    return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE);
780 }
781
782
783 /**
784  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using
785  * GetIntegerv, GetFramebufferParameteriv, etc)
786  *
787  * If @fb is NULL, the method returns the value for the current bound
788  * framebuffer.
789  */
790 GLenum
791 _mesa_get_color_read_format(struct gl_context *ctx,
792                             struct gl_framebuffer *fb,
793                             const char *caller)
794 {
795    if (ctx->NewState)
796       _mesa_update_state(ctx);
797
798    if (fb == NULL)
799       fb = ctx->ReadBuffer;
800
801    if (!fb || !fb->_ColorReadBuffer) {
802       /*
803        * From OpenGL 4.5 spec, section 18.2.2 "ReadPixels":
804        *
805        *    "An INVALID_OPERATION error is generated by GetIntegerv if pname
806        *     is IMPLEMENTATION_COLOR_READ_FORMAT or IMPLEMENTATION_COLOR_-
807        *     READ_TYPE and any of:
808        *      * the read framebuffer is not framebuffer complete.
809        *      * the read framebuffer is a framebuffer object, and the selected
810        *        read buffer (see section 18.2.1) has no image attached.
811        *      * the selected read buffer is NONE."
812        *
813        * There is not equivalent quote for GetFramebufferParameteriv or
814        * GetNamedFramebufferParameteriv, but from section 9.2.3 "Framebuffer
815        * Object Queries":
816        *
817        *    "Values of framebuffer-dependent state are identical to those that
818        *     would be obtained were the framebuffer object bound and queried
819        *     using the simple state queries in that table."
820        *
821        * Where "using the simple state queries" refer to use GetIntegerv. So
822        * we will assume that on that situation the same error should be
823        * triggered too.
824        */
825       _mesa_error(ctx, GL_INVALID_OPERATION,
826                   "%s(GL_IMPLEMENTATION_COLOR_READ_FORMAT: no GL_READ_BUFFER)",
827                   caller);
828       return GL_NONE;
829    }
830    else {
831       const mesa_format format = fb->_ColorReadBuffer->Format;
832       const GLenum data_type = _mesa_get_format_datatype(format);
833
834       if (format == MESA_FORMAT_B8G8R8A8_UNORM)
835          return GL_BGRA;
836       else if (format == MESA_FORMAT_B5G6R5_UNORM)
837          return GL_RGB;
838       else if (format == MESA_FORMAT_R_UNORM8)
839          return GL_RED;
840
841       switch (data_type) {
842       case GL_UNSIGNED_INT:
843       case GL_INT:
844          return GL_RGBA_INTEGER;
845       default:
846          return GL_RGBA;
847       }
848    }
849 }
850
851
852 /**
853  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES queries (using
854  * GetIntegerv, GetFramebufferParameteriv, etc)
855  *
856  * If @fb is NULL, the method returns the value for the current bound
857  * framebuffer.
858  */
859 GLenum
860 _mesa_get_color_read_type(struct gl_context *ctx,
861                           struct gl_framebuffer *fb,
862                           const char *caller)
863 {
864    if (ctx->NewState)
865       _mesa_update_state(ctx);
866
867    if (fb == NULL)
868       fb = ctx->ReadBuffer;
869
870    if (!fb || !fb->_ColorReadBuffer) {
871       /*
872        * See comment on _mesa_get_color_read_format
873        */
874       _mesa_error(ctx, GL_INVALID_OPERATION,
875                   "%s(GL_IMPLEMENTATION_COLOR_READ_TYPE: no GL_READ_BUFFER)",
876                   caller);
877       return GL_NONE;
878    }
879    else {
880       const GLenum format = fb->_ColorReadBuffer->Format;
881       const GLenum data_type = _mesa_get_format_datatype(format);
882
883       if (format == MESA_FORMAT_B5G6R5_UNORM)
884          return GL_UNSIGNED_SHORT_5_6_5;
885
886       if (format == MESA_FORMAT_B10G10R10A2_UNORM ||
887           format == MESA_FORMAT_B10G10R10X2_UNORM ||
888           format == MESA_FORMAT_R10G10B10A2_UNORM ||
889           format == MESA_FORMAT_R10G10B10X2_UNORM)
890          return GL_UNSIGNED_INT_2_10_10_10_REV;
891
892       switch (data_type) {
893       case GL_SIGNED_NORMALIZED:
894          return GL_BYTE;
895       case GL_UNSIGNED_INT:
896       case GL_INT:
897       case GL_FLOAT:
898          return data_type;
899       case GL_UNSIGNED_NORMALIZED:
900       default:
901          return GL_UNSIGNED_BYTE;
902       }
903    }
904 }
905
906
907 /**
908  * Returns the read renderbuffer for the specified format.
909  */
910 struct gl_renderbuffer *
911 _mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx,
912                                        GLenum format)
913 {
914    const struct gl_framebuffer *rfb = ctx->ReadBuffer;
915
916    if (_mesa_is_color_format(format)) {
917       return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer;
918    } else if (_mesa_is_depth_format(format) ||
919               _mesa_is_depthstencil_format(format)) {
920       return rfb->Attachment[BUFFER_DEPTH].Renderbuffer;
921    } else {
922       return rfb->Attachment[BUFFER_STENCIL].Renderbuffer;
923    }
924 }
925
926
927 /**
928  * Print framebuffer info to stderr, for debugging.
929  */
930 void
931 _mesa_print_framebuffer(const struct gl_framebuffer *fb)
932 {
933    fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
934    fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
935            _mesa_enum_to_string(fb->_Status));
936    fprintf(stderr, "  Attachments:\n");
937
938    for (unsigned i = 0; i < BUFFER_COUNT; i++) {
939       const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
940       if (att->Type == GL_TEXTURE) {
941          const struct gl_texture_image *texImage = att->Renderbuffer->TexImage;
942          fprintf(stderr,
943                  "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
944                  i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
945                  att->Zoffset, att->Complete);
946          fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
947                  texImage->Width, texImage->Height, texImage->Depth,
948                  _mesa_get_format_name(texImage->TexFormat));
949       }
950       else if (att->Type == GL_RENDERBUFFER) {
951          fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
952                  i, att->Renderbuffer->Name, att->Complete);
953          fprintf(stderr, "       Size: %u x %u  Format %s\n",
954                  att->Renderbuffer->Width, att->Renderbuffer->Height,
955                  _mesa_get_format_name(att->Renderbuffer->Format));
956       }
957       else {
958          fprintf(stderr, "  %2d: none\n", i);
959       }
960    }
961 }
962
963 bool
964 _mesa_is_front_buffer_reading(const struct gl_framebuffer *fb)
965 {
966    if (!fb || _mesa_is_user_fbo(fb))
967       return false;
968
969    return fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT;
970 }
971
972 bool
973 _mesa_is_front_buffer_drawing(const struct gl_framebuffer *fb)
974 {
975    if (!fb || _mesa_is_user_fbo(fb))
976       return false;
977
978    return (fb->_NumColorDrawBuffers >= 1 &&
979            fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT);
980 }
981
982 static inline GLuint
983 _mesa_geometric_nonvalidated_samples(const struct gl_framebuffer *buffer)
984 {
985    return buffer->_HasAttachments ?
986       buffer->Visual.samples :
987       buffer->DefaultGeometry.NumSamples;
988 }
989
990 bool
991 _mesa_is_multisample_enabled(const struct gl_context *ctx)
992 {
993    /* The sample count may not be validated by the driver, but when it is set,
994     * we know that is in a valid range and no driver should ever validate a
995     * multisampled framebuffer to non-multisampled and vice-versa.
996     */
997    return ctx->Multisample.Enabled &&
998           ctx->DrawBuffer &&
999           _mesa_geometric_nonvalidated_samples(ctx->DrawBuffer) >= 1;
1000 }
1001
1002 /**
1003  * Is alpha testing enabled and applicable to the currently bound
1004  * framebuffer?
1005  */
1006 bool
1007 _mesa_is_alpha_test_enabled(const struct gl_context *ctx)
1008 {
1009    bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1;
1010    return (ctx->Color.AlphaEnabled && !buffer0_is_integer);
1011 }
1012
1013 /**
1014  * Is alpha to coverage enabled and applicable to the currently bound
1015  * framebuffer?
1016  */
1017 bool
1018 _mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx)
1019 {
1020    bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1;
1021    return (ctx->Multisample.SampleAlphaToCoverage &&
1022            _mesa_is_multisample_enabled(ctx) &&
1023            !buffer0_is_integer);
1024 }