1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24848b8605Smrg
25848b8605Smrg
26848b8605Smrg/**
27848b8605Smrg * Functions for allocating/managing framebuffers and renderbuffers.
28848b8605Smrg * Also, routines for reading/writing renderbuffer data as ubytes,
29848b8605Smrg * ushorts, uints, etc.
30848b8605Smrg */
31848b8605Smrg
32b8e80941Smrg#include <stdio.h>
33848b8605Smrg#include "glheader.h"
34848b8605Smrg#include "imports.h"
35848b8605Smrg#include "blend.h"
36848b8605Smrg#include "buffers.h"
37848b8605Smrg#include "context.h"
38848b8605Smrg#include "enums.h"
39848b8605Smrg#include "formats.h"
40848b8605Smrg#include "macros.h"
41848b8605Smrg#include "mtypes.h"
42848b8605Smrg#include "fbobject.h"
43848b8605Smrg#include "framebuffer.h"
44848b8605Smrg#include "renderbuffer.h"
45848b8605Smrg#include "texobj.h"
46848b8605Smrg#include "glformats.h"
47b8e80941Smrg#include "state.h"
48848b8605Smrg
49848b8605Smrg
50848b8605Smrg
51848b8605Smrg/**
52848b8605Smrg * Compute/set the _DepthMax field for the given framebuffer.
53848b8605Smrg * This value depends on the Z buffer resolution.
54848b8605Smrg */
55848b8605Smrgstatic void
56848b8605Smrgcompute_depth_max(struct gl_framebuffer *fb)
57848b8605Smrg{
58848b8605Smrg   if (fb->Visual.depthBits == 0) {
59848b8605Smrg      /* Special case.  Even if we don't have a depth buffer we need
60848b8605Smrg       * good values for DepthMax for Z vertex transformation purposes
61848b8605Smrg       * and for per-fragment fog computation.
62848b8605Smrg       */
63848b8605Smrg      fb->_DepthMax = (1 << 16) - 1;
64848b8605Smrg   }
65848b8605Smrg   else if (fb->Visual.depthBits < 32) {
66848b8605Smrg      fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
67848b8605Smrg   }
68848b8605Smrg   else {
69848b8605Smrg      /* Special case since shift values greater than or equal to the
70848b8605Smrg       * number of bits in the left hand expression's type are undefined.
71848b8605Smrg       */
72848b8605Smrg      fb->_DepthMax = 0xffffffff;
73848b8605Smrg   }
74848b8605Smrg   fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
75848b8605Smrg
76848b8605Smrg   /* Minimum resolvable depth value, for polygon offset */
77848b8605Smrg   fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
78848b8605Smrg}
79848b8605Smrg
80848b8605Smrg/**
81848b8605Smrg * Create and initialize a gl_framebuffer object.
82848b8605Smrg * This is intended for creating _window_system_ framebuffers, not generic
83848b8605Smrg * framebuffer objects ala GL_EXT_framebuffer_object.
84848b8605Smrg *
85848b8605Smrg * \sa _mesa_new_framebuffer
86848b8605Smrg */
87848b8605Smrgstruct gl_framebuffer *
88848b8605Smrg_mesa_create_framebuffer(const struct gl_config *visual)
89848b8605Smrg{
90848b8605Smrg   struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
91848b8605Smrg   assert(visual);
92848b8605Smrg   if (fb) {
93848b8605Smrg      _mesa_initialize_window_framebuffer(fb, visual);
94848b8605Smrg   }
95848b8605Smrg   return fb;
96848b8605Smrg}
97848b8605Smrg
98848b8605Smrg
99848b8605Smrg/**
100848b8605Smrg * Allocate a new gl_framebuffer object.
101848b8605Smrg * This is the default function for ctx->Driver.NewFramebuffer().
102848b8605Smrg * This is for allocating user-created framebuffers, not window-system
103848b8605Smrg * framebuffers!
104848b8605Smrg * \sa _mesa_create_framebuffer
105848b8605Smrg */
106848b8605Smrgstruct gl_framebuffer *
107848b8605Smrg_mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
108848b8605Smrg{
109848b8605Smrg   struct gl_framebuffer *fb;
110848b8605Smrg   (void) ctx;
111848b8605Smrg   assert(name != 0);
112848b8605Smrg   fb = CALLOC_STRUCT(gl_framebuffer);
113848b8605Smrg   if (fb) {
114848b8605Smrg      _mesa_initialize_user_framebuffer(fb, name);
115848b8605Smrg   }
116848b8605Smrg   return fb;
117848b8605Smrg}
118848b8605Smrg
119848b8605Smrg
120848b8605Smrg/**
121848b8605Smrg * Initialize a gl_framebuffer object.  Typically used to initialize
122848b8605Smrg * window system-created framebuffers, not user-created framebuffers.
123848b8605Smrg * \sa _mesa_initialize_user_framebuffer
124848b8605Smrg */
125848b8605Smrgvoid
126848b8605Smrg_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
127848b8605Smrg				     const struct gl_config *visual)
128848b8605Smrg{
129848b8605Smrg   assert(fb);
130848b8605Smrg   assert(visual);
131848b8605Smrg
132848b8605Smrg   memset(fb, 0, sizeof(struct gl_framebuffer));
133848b8605Smrg
134b8e80941Smrg   simple_mtx_init(&fb->Mutex, mtx_plain);
135848b8605Smrg
136848b8605Smrg   fb->RefCount = 1;
137848b8605Smrg
138848b8605Smrg   /* save the visual */
139848b8605Smrg   fb->Visual = *visual;
140848b8605Smrg
141848b8605Smrg   /* Init read/draw renderbuffer state */
142848b8605Smrg   if (visual->doubleBufferMode) {
143848b8605Smrg      fb->_NumColorDrawBuffers = 1;
144848b8605Smrg      fb->ColorDrawBuffer[0] = GL_BACK;
145848b8605Smrg      fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
146848b8605Smrg      fb->ColorReadBuffer = GL_BACK;
147848b8605Smrg      fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
148848b8605Smrg   }
149848b8605Smrg   else {
150848b8605Smrg      fb->_NumColorDrawBuffers = 1;
151848b8605Smrg      fb->ColorDrawBuffer[0] = GL_FRONT;
152848b8605Smrg      fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
153848b8605Smrg      fb->ColorReadBuffer = GL_FRONT;
154848b8605Smrg      fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
155848b8605Smrg   }
156848b8605Smrg
157848b8605Smrg   fb->Delete = _mesa_destroy_framebuffer;
158848b8605Smrg   fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
159848b8605Smrg   fb->_AllColorBuffersFixedPoint = !visual->floatMode;
160848b8605Smrg   fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
161b8e80941Smrg   fb->_HasAttachments = true;
162b8e80941Smrg   fb->FlipY = true;
163b8e80941Smrg
164b8e80941Smrg   fb->SampleLocationTable = NULL;
165b8e80941Smrg   fb->ProgrammableSampleLocations = 0;
166b8e80941Smrg   fb->SampleLocationPixelGrid = 0;
167848b8605Smrg
168848b8605Smrg   compute_depth_max(fb);
169848b8605Smrg}
170848b8605Smrg
171848b8605Smrg
172848b8605Smrg/**
173848b8605Smrg * Initialize a user-created gl_framebuffer object.
174848b8605Smrg * \sa _mesa_initialize_window_framebuffer
175848b8605Smrg */
176848b8605Smrgvoid
177848b8605Smrg_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
178848b8605Smrg{
179848b8605Smrg   assert(fb);
180848b8605Smrg   assert(name);
181848b8605Smrg
182848b8605Smrg   memset(fb, 0, sizeof(struct gl_framebuffer));
183848b8605Smrg
184848b8605Smrg   fb->Name = name;
185848b8605Smrg   fb->RefCount = 1;
186848b8605Smrg   fb->_NumColorDrawBuffers = 1;
187848b8605Smrg   fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
188848b8605Smrg   fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
189848b8605Smrg   fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
190848b8605Smrg   fb->_ColorReadBufferIndex = BUFFER_COLOR0;
191b8e80941Smrg   fb->SampleLocationTable = NULL;
192b8e80941Smrg   fb->ProgrammableSampleLocations = 0;
193b8e80941Smrg   fb->SampleLocationPixelGrid = 0;
194848b8605Smrg   fb->Delete = _mesa_destroy_framebuffer;
195b8e80941Smrg   simple_mtx_init(&fb->Mutex, mtx_plain);
196848b8605Smrg}
197848b8605Smrg
198848b8605Smrg
199848b8605Smrg/**
200848b8605Smrg * Deallocate buffer and everything attached to it.
201848b8605Smrg * Typically called via the gl_framebuffer->Delete() method.
202848b8605Smrg */
203848b8605Smrgvoid
204848b8605Smrg_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
205848b8605Smrg{
206848b8605Smrg   if (fb) {
207848b8605Smrg      _mesa_free_framebuffer_data(fb);
208848b8605Smrg      free(fb->Label);
209848b8605Smrg      free(fb);
210848b8605Smrg   }
211848b8605Smrg}
212848b8605Smrg
213848b8605Smrg
214848b8605Smrg/**
215848b8605Smrg * Free all the data hanging off the given gl_framebuffer, but don't free
216848b8605Smrg * the gl_framebuffer object itself.
217848b8605Smrg */
218848b8605Smrgvoid
219848b8605Smrg_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
220848b8605Smrg{
221848b8605Smrg   assert(fb);
222848b8605Smrg   assert(fb->RefCount == 0);
223848b8605Smrg
224b8e80941Smrg   simple_mtx_destroy(&fb->Mutex);
225848b8605Smrg
226b8e80941Smrg   for (unsigned i = 0; i < BUFFER_COUNT; i++) {
227848b8605Smrg      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
228848b8605Smrg      if (att->Renderbuffer) {
229848b8605Smrg         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
230848b8605Smrg      }
231848b8605Smrg      if (att->Texture) {
232848b8605Smrg         _mesa_reference_texobj(&att->Texture, NULL);
233848b8605Smrg      }
234b8e80941Smrg      assert(!att->Renderbuffer);
235b8e80941Smrg      assert(!att->Texture);
236848b8605Smrg      att->Type = GL_NONE;
237848b8605Smrg   }
238b8e80941Smrg
239b8e80941Smrg   free(fb->SampleLocationTable);
240b8e80941Smrg   fb->SampleLocationTable = NULL;
241848b8605Smrg}
242848b8605Smrg
243848b8605Smrg
244848b8605Smrg/**
245848b8605Smrg * Set *ptr to point to fb, with refcounting and locking.
246848b8605Smrg * This is normally only called from the _mesa_reference_framebuffer() macro
247848b8605Smrg * when there's a real pointer change.
248848b8605Smrg */
249848b8605Smrgvoid
250848b8605Smrg_mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
251848b8605Smrg                             struct gl_framebuffer *fb)
252848b8605Smrg{
253848b8605Smrg   if (*ptr) {
254848b8605Smrg      /* unreference old renderbuffer */
255848b8605Smrg      GLboolean deleteFlag = GL_FALSE;
256848b8605Smrg      struct gl_framebuffer *oldFb = *ptr;
257848b8605Smrg
258b8e80941Smrg      simple_mtx_lock(&oldFb->Mutex);
259b8e80941Smrg      assert(oldFb->RefCount > 0);
260848b8605Smrg      oldFb->RefCount--;
261848b8605Smrg      deleteFlag = (oldFb->RefCount == 0);
262b8e80941Smrg      simple_mtx_unlock(&oldFb->Mutex);
263b8e80941Smrg
264848b8605Smrg      if (deleteFlag)
265848b8605Smrg         oldFb->Delete(oldFb);
266848b8605Smrg
267848b8605Smrg      *ptr = NULL;
268848b8605Smrg   }
269848b8605Smrg
270848b8605Smrg   if (fb) {
271b8e80941Smrg      simple_mtx_lock(&fb->Mutex);
272848b8605Smrg      fb->RefCount++;
273b8e80941Smrg      simple_mtx_unlock(&fb->Mutex);
274848b8605Smrg      *ptr = fb;
275848b8605Smrg   }
276848b8605Smrg}
277848b8605Smrg
278848b8605Smrg
279848b8605Smrg/**
280848b8605Smrg * Resize the given framebuffer's renderbuffers to the new width and height.
281848b8605Smrg * This should only be used for window-system framebuffers, not
282848b8605Smrg * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
283b8e80941Smrg * This will typically be called directly from a device driver.
284848b8605Smrg *
285848b8605Smrg * \note it's possible for ctx to be null since a window can be resized
286848b8605Smrg * without a currently bound rendering context.
287848b8605Smrg */
288848b8605Smrgvoid
289848b8605Smrg_mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
290848b8605Smrg                         GLuint width, GLuint height)
291848b8605Smrg{
292848b8605Smrg   /* XXX I think we could check if the size is not changing
293848b8605Smrg    * and return early.
294848b8605Smrg    */
295848b8605Smrg
296848b8605Smrg   /* Can only resize win-sys framebuffer objects */
297848b8605Smrg   assert(_mesa_is_winsys_fbo(fb));
298848b8605Smrg
299b8e80941Smrg   for (unsigned i = 0; i < BUFFER_COUNT; i++) {
300848b8605Smrg      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
301848b8605Smrg      if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
302848b8605Smrg         struct gl_renderbuffer *rb = att->Renderbuffer;
303848b8605Smrg         /* only resize if size is changing */
304848b8605Smrg         if (rb->Width != width || rb->Height != height) {
305848b8605Smrg            if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
306b8e80941Smrg               assert(rb->Width == width);
307b8e80941Smrg               assert(rb->Height == height);
308848b8605Smrg            }
309848b8605Smrg            else {
310848b8605Smrg               _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
311848b8605Smrg               /* no return */
312848b8605Smrg            }
313848b8605Smrg         }
314848b8605Smrg      }
315848b8605Smrg   }
316848b8605Smrg
317848b8605Smrg   fb->Width = width;
318848b8605Smrg   fb->Height = height;
319848b8605Smrg
320848b8605Smrg   if (ctx) {
321848b8605Smrg      /* update scissor / window bounds */
322b8e80941Smrg      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
323848b8605Smrg      /* Signal new buffer state so that swrast will update its clipping
324848b8605Smrg       * info (the CLIP_BIT flag).
325848b8605Smrg       */
326848b8605Smrg      ctx->NewState |= _NEW_BUFFERS;
327848b8605Smrg   }
328848b8605Smrg}
329848b8605Smrg
330848b8605Smrg/**
331b8e80941Smrg * Given a bounding box, intersect the bounding box with the scissor of
332b8e80941Smrg * a specified vieport.
333848b8605Smrg *
334848b8605Smrg * \param ctx     GL context.
335848b8605Smrg * \param idx     Index of the desired viewport
336848b8605Smrg * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
337848b8605Smrg *                xmax, ymin, ymax.
338848b8605Smrg */
339848b8605Smrgvoid
340b8e80941Smrg_mesa_intersect_scissor_bounding_box(const struct gl_context *ctx,
341b8e80941Smrg                                     unsigned idx, int *bbox)
342848b8605Smrg{
343848b8605Smrg   if (ctx->Scissor.EnableFlags & (1u << idx)) {
344848b8605Smrg      if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) {
345848b8605Smrg         bbox[0] = ctx->Scissor.ScissorArray[idx].X;
346848b8605Smrg      }
347848b8605Smrg      if (ctx->Scissor.ScissorArray[idx].Y > bbox[2]) {
348848b8605Smrg         bbox[2] = ctx->Scissor.ScissorArray[idx].Y;
349848b8605Smrg      }
350848b8605Smrg      if (ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width < bbox[1]) {
351848b8605Smrg         bbox[1] = ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width;
352848b8605Smrg      }
353848b8605Smrg      if (ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height < bbox[3]) {
354848b8605Smrg         bbox[3] = ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height;
355848b8605Smrg      }
356848b8605Smrg      /* finally, check for empty region */
357848b8605Smrg      if (bbox[0] > bbox[1]) {
358848b8605Smrg         bbox[0] = bbox[1];
359848b8605Smrg      }
360848b8605Smrg      if (bbox[2] > bbox[3]) {
361848b8605Smrg         bbox[2] = bbox[3];
362848b8605Smrg      }
363848b8605Smrg   }
364b8e80941Smrg}
365848b8605Smrg
366b8e80941Smrg/**
367b8e80941Smrg * Calculate the inclusive bounding box for the scissor of a specific viewport
368b8e80941Smrg *
369b8e80941Smrg * \param ctx     GL context.
370b8e80941Smrg * \param buffer  Framebuffer to be checked against
371b8e80941Smrg * \param idx     Index of the desired viewport
372b8e80941Smrg * \param bbox    Bounding box for the scissored viewport.  Stored as xmin,
373b8e80941Smrg *                xmax, ymin, ymax.
374b8e80941Smrg *
375b8e80941Smrg * \warning This function assumes that the framebuffer dimensions are up to
376b8e80941Smrg * date.
377b8e80941Smrg *
378b8e80941Smrg * \sa _mesa_clip_to_region
379b8e80941Smrg */
380b8e80941Smrgstatic void
381b8e80941Smrgscissor_bounding_box(const struct gl_context *ctx,
382b8e80941Smrg                     const struct gl_framebuffer *buffer,
383b8e80941Smrg                     unsigned idx, int *bbox)
384b8e80941Smrg{
385b8e80941Smrg   bbox[0] = 0;
386b8e80941Smrg   bbox[2] = 0;
387b8e80941Smrg   bbox[1] = buffer->Width;
388b8e80941Smrg   bbox[3] = buffer->Height;
389b8e80941Smrg
390b8e80941Smrg   _mesa_intersect_scissor_bounding_box(ctx, idx, bbox);
391b8e80941Smrg
392b8e80941Smrg   assert(bbox[0] <= bbox[1]);
393b8e80941Smrg   assert(bbox[2] <= bbox[3]);
394848b8605Smrg}
395848b8605Smrg
396848b8605Smrg/**
397848b8605Smrg * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
398848b8605Smrg * These values are computed from the buffer's width and height and
399848b8605Smrg * the scissor box, if it's enabled.
400848b8605Smrg * \param ctx  the GL context.
401848b8605Smrg */
402848b8605Smrgvoid
403b8e80941Smrg_mesa_update_draw_buffer_bounds(struct gl_context *ctx,
404b8e80941Smrg                                struct gl_framebuffer *buffer)
405848b8605Smrg{
406848b8605Smrg   int bbox[4];
407848b8605Smrg
408848b8605Smrg   if (!buffer)
409848b8605Smrg      return;
410848b8605Smrg
411848b8605Smrg   /* Default to the first scissor as that's always valid */
412b8e80941Smrg   scissor_bounding_box(ctx, buffer, 0, bbox);
413848b8605Smrg   buffer->_Xmin = bbox[0];
414848b8605Smrg   buffer->_Ymin = bbox[2];
415848b8605Smrg   buffer->_Xmax = bbox[1];
416848b8605Smrg   buffer->_Ymax = bbox[3];
417848b8605Smrg}
418848b8605Smrg
419848b8605Smrg
420848b8605Smrg/**
421848b8605Smrg * The glGet queries of the framebuffer red/green/blue size, stencil size,
422848b8605Smrg * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
423848b8605Smrg * change depending on the renderbuffer bindings.  This function updates
424848b8605Smrg * the given framebuffer's Visual from the current renderbuffer bindings.
425848b8605Smrg *
426848b8605Smrg * This may apply to user-created framebuffers or window system framebuffers.
427848b8605Smrg *
428848b8605Smrg * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
429848b8605Smrg * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
430848b8605Smrg * The former one is used to convert floating point depth values into
431848b8605Smrg * integer Z values.
432848b8605Smrg */
433848b8605Smrgvoid
434848b8605Smrg_mesa_update_framebuffer_visual(struct gl_context *ctx,
435848b8605Smrg				struct gl_framebuffer *fb)
436848b8605Smrg{
437848b8605Smrg   memset(&fb->Visual, 0, sizeof(fb->Visual));
438848b8605Smrg   fb->Visual.rgbMode = GL_TRUE; /* assume this */
439848b8605Smrg
440848b8605Smrg   /* find first RGB renderbuffer */
441b8e80941Smrg   for (unsigned i = 0; i < BUFFER_COUNT; i++) {
442848b8605Smrg      if (fb->Attachment[i].Renderbuffer) {
443848b8605Smrg         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
444848b8605Smrg         const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
445848b8605Smrg         const mesa_format fmt = rb->Format;
446848b8605Smrg
447848b8605Smrg         /* Grab samples and sampleBuffers from any attachment point (assuming
448848b8605Smrg          * the framebuffer is complete, we'll get the same answer from all
449848b8605Smrg          * attachments).
450848b8605Smrg          */
451848b8605Smrg         fb->Visual.samples = rb->NumSamples;
452848b8605Smrg         fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
453848b8605Smrg
454848b8605Smrg         if (_mesa_is_legal_color_format(ctx, baseFormat)) {
455848b8605Smrg            fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
456848b8605Smrg            fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
457848b8605Smrg            fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
458848b8605Smrg            fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
459848b8605Smrg            fb->Visual.rgbBits = fb->Visual.redBits
460848b8605Smrg               + fb->Visual.greenBits + fb->Visual.blueBits;
461848b8605Smrg            if (_mesa_get_format_color_encoding(fmt) == GL_SRGB)
462b8e80941Smrg                fb->Visual.sRGBCapable = ctx->Extensions.EXT_sRGB;
463848b8605Smrg            break;
464848b8605Smrg         }
465848b8605Smrg      }
466848b8605Smrg   }
467848b8605Smrg
468848b8605Smrg   fb->Visual.floatMode = GL_FALSE;
469b8e80941Smrg   for (unsigned i = 0; i < BUFFER_COUNT; i++) {
470848b8605Smrg      if (fb->Attachment[i].Renderbuffer) {
471848b8605Smrg         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
472848b8605Smrg         const mesa_format fmt = rb->Format;
473848b8605Smrg
474848b8605Smrg         if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
475848b8605Smrg            fb->Visual.floatMode = GL_TRUE;
476848b8605Smrg            break;
477848b8605Smrg         }
478848b8605Smrg      }
479848b8605Smrg   }
480848b8605Smrg
481848b8605Smrg   if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
482848b8605Smrg      const struct gl_renderbuffer *rb =
483848b8605Smrg         fb->Attachment[BUFFER_DEPTH].Renderbuffer;
484848b8605Smrg      const mesa_format fmt = rb->Format;
485848b8605Smrg      fb->Visual.haveDepthBuffer = GL_TRUE;
486848b8605Smrg      fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
487848b8605Smrg   }
488848b8605Smrg
489848b8605Smrg   if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
490848b8605Smrg      const struct gl_renderbuffer *rb =
491848b8605Smrg         fb->Attachment[BUFFER_STENCIL].Renderbuffer;
492848b8605Smrg      const mesa_format fmt = rb->Format;
493848b8605Smrg      fb->Visual.haveStencilBuffer = GL_TRUE;
494848b8605Smrg      fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
495848b8605Smrg   }
496848b8605Smrg
497848b8605Smrg   if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
498848b8605Smrg      const struct gl_renderbuffer *rb =
499848b8605Smrg         fb->Attachment[BUFFER_ACCUM].Renderbuffer;
500848b8605Smrg      const mesa_format fmt = rb->Format;
501848b8605Smrg      fb->Visual.haveAccumBuffer = GL_TRUE;
502848b8605Smrg      fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
503848b8605Smrg      fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
504848b8605Smrg      fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
505848b8605Smrg      fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
506848b8605Smrg   }
507848b8605Smrg
508848b8605Smrg   compute_depth_max(fb);
509848b8605Smrg}
510848b8605Smrg
511848b8605Smrg
512848b8605Smrg/*
513848b8605Smrg * Example DrawBuffers scenarios:
514848b8605Smrg *
515848b8605Smrg * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
516848b8605Smrg * "gl_FragColor" or program writes to the "result.color" register:
517848b8605Smrg *
518848b8605Smrg *   fragment color output   renderbuffer
519848b8605Smrg *   ---------------------   ---------------
520848b8605Smrg *   color[0]                Front, Back
521848b8605Smrg *
522848b8605Smrg *
523848b8605Smrg * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
524848b8605Smrg * gl_FragData[i] or program writes to result.color[i] registers:
525848b8605Smrg *
526848b8605Smrg *   fragment color output   renderbuffer
527848b8605Smrg *   ---------------------   ---------------
528848b8605Smrg *   color[0]                Front
529848b8605Smrg *   color[1]                Aux0
530848b8605Smrg *   color[3]                Aux1
531848b8605Smrg *
532848b8605Smrg *
533848b8605Smrg * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
534848b8605Smrg * gl_FragColor, or fixed function:
535848b8605Smrg *
536848b8605Smrg *   fragment color output   renderbuffer
537848b8605Smrg *   ---------------------   ---------------
538848b8605Smrg *   color[0]                Front, Aux0, Aux1
539848b8605Smrg *
540848b8605Smrg *
541848b8605Smrg * In either case, the list of renderbuffers is stored in the
542848b8605Smrg * framebuffer->_ColorDrawBuffers[] array and
543848b8605Smrg * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
544848b8605Smrg * The renderer (like swrast) has to look at the current fragment shader
545848b8605Smrg * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
546848b8605Smrg * how to map color outputs to renderbuffers.
547848b8605Smrg *
548848b8605Smrg * Note that these two calls are equivalent (for fixed function fragment
549848b8605Smrg * shading anyway):
550848b8605Smrg *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
551848b8605Smrg *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
552848b8605Smrg */
553848b8605Smrg
554848b8605Smrg
555848b8605Smrg
556848b8605Smrg
557848b8605Smrg/**
558848b8605Smrg * Update the (derived) list of color drawing renderbuffer pointers.
559848b8605Smrg * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
560848b8605Smrg * writing colors.
561848b8605Smrg */
562848b8605Smrgstatic void
563b8e80941Smrgupdate_color_draw_buffers(struct gl_framebuffer *fb)
564848b8605Smrg{
565848b8605Smrg   GLuint output;
566848b8605Smrg
567848b8605Smrg   /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
568848b8605Smrg   fb->_ColorDrawBuffers[0] = NULL;
569848b8605Smrg
570848b8605Smrg   for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
571b8e80941Smrg      gl_buffer_index buf = fb->_ColorDrawBufferIndexes[output];
572b8e80941Smrg      if (buf != BUFFER_NONE) {
573848b8605Smrg         fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
574848b8605Smrg      }
575848b8605Smrg      else {
576848b8605Smrg         fb->_ColorDrawBuffers[output] = NULL;
577848b8605Smrg      }
578848b8605Smrg   }
579848b8605Smrg}
580848b8605Smrg
581848b8605Smrg
582848b8605Smrg/**
583848b8605Smrg * Update the (derived) color read renderbuffer pointer.
584848b8605Smrg * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
585848b8605Smrg */
586848b8605Smrgstatic void
587b8e80941Smrgupdate_color_read_buffer(struct gl_framebuffer *fb)
588848b8605Smrg{
589b8e80941Smrg   if (fb->_ColorReadBufferIndex == BUFFER_NONE ||
590848b8605Smrg       fb->DeletePending ||
591848b8605Smrg       fb->Width == 0 ||
592848b8605Smrg       fb->Height == 0) {
593848b8605Smrg      fb->_ColorReadBuffer = NULL; /* legal! */
594848b8605Smrg   }
595848b8605Smrg   else {
596b8e80941Smrg      assert(fb->_ColorReadBufferIndex >= 0);
597b8e80941Smrg      assert(fb->_ColorReadBufferIndex < BUFFER_COUNT);
598848b8605Smrg      fb->_ColorReadBuffer
599848b8605Smrg         = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
600848b8605Smrg   }
601848b8605Smrg}
602848b8605Smrg
603848b8605Smrg
604848b8605Smrg/**
605848b8605Smrg * Update a gl_framebuffer's derived state.
606848b8605Smrg *
607848b8605Smrg * Specifically, update these framebuffer fields:
608848b8605Smrg *    _ColorDrawBuffers
609848b8605Smrg *    _NumColorDrawBuffers
610848b8605Smrg *    _ColorReadBuffer
611848b8605Smrg *
612848b8605Smrg * If the framebuffer is user-created, make sure it's complete.
613848b8605Smrg *
614848b8605Smrg * The following functions (at least) can effect framebuffer state:
615848b8605Smrg * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
616848b8605Smrg * glRenderbufferStorageEXT.
617848b8605Smrg */
618848b8605Smrgstatic void
619848b8605Smrgupdate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
620848b8605Smrg{
621848b8605Smrg   if (_mesa_is_winsys_fbo(fb)) {
622848b8605Smrg      /* This is a window-system framebuffer */
623848b8605Smrg      /* Need to update the FB's GL_DRAW_BUFFER state to match the
624848b8605Smrg       * context state (GL_READ_BUFFER too).
625848b8605Smrg       */
626848b8605Smrg      if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
627b8e80941Smrg         _mesa_drawbuffers(ctx, fb, ctx->Const.MaxDrawBuffers,
628848b8605Smrg                           ctx->Color.DrawBuffer, NULL);
629848b8605Smrg      }
630b8e80941Smrg
631b8e80941Smrg      /* Call device driver function if fb is the bound draw buffer. */
632b8e80941Smrg      if (fb == ctx->DrawBuffer) {
633b8e80941Smrg         if (ctx->Driver.DrawBufferAllocate)
634b8e80941Smrg            ctx->Driver.DrawBufferAllocate(ctx);
635b8e80941Smrg      }
636848b8605Smrg   }
637848b8605Smrg   else {
638848b8605Smrg      /* This is a user-created framebuffer.
639848b8605Smrg       * Completeness only matters for user-created framebuffers.
640848b8605Smrg       */
641848b8605Smrg      if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
642848b8605Smrg         _mesa_test_framebuffer_completeness(ctx, fb);
643848b8605Smrg      }
644848b8605Smrg   }
645848b8605Smrg
646848b8605Smrg   /* Strictly speaking, we don't need to update the draw-state
647848b8605Smrg    * if this FB is bound as ctx->ReadBuffer (and conversely, the
648848b8605Smrg    * read-state if this FB is bound as ctx->DrawBuffer), but no
649848b8605Smrg    * harm.
650848b8605Smrg    */
651b8e80941Smrg   update_color_draw_buffers(fb);
652b8e80941Smrg   update_color_read_buffer(fb);
653848b8605Smrg
654848b8605Smrg   compute_depth_max(fb);
655848b8605Smrg}
656848b8605Smrg
657848b8605Smrg
658848b8605Smrg/**
659b8e80941Smrg * Update state related to the draw/read framebuffers.
660848b8605Smrg */
661848b8605Smrgvoid
662b8e80941Smrg_mesa_update_framebuffer(struct gl_context *ctx,
663b8e80941Smrg                         struct gl_framebuffer *readFb,
664b8e80941Smrg                         struct gl_framebuffer *drawFb)
665848b8605Smrg{
666848b8605Smrg   assert(ctx);
667848b8605Smrg
668848b8605Smrg   update_framebuffer(ctx, drawFb);
669848b8605Smrg   if (readFb != drawFb)
670848b8605Smrg      update_framebuffer(ctx, readFb);
671848b8605Smrg
672b8e80941Smrg   _mesa_update_clamp_vertex_color(ctx, drawFb);
673b8e80941Smrg   _mesa_update_clamp_fragment_color(ctx, drawFb);
674848b8605Smrg}
675848b8605Smrg
676848b8605Smrg
677848b8605Smrg/**
678848b8605Smrg * Check if the renderbuffer for a read/draw operation exists.
679848b8605Smrg * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
680848b8605Smrg *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
681848b8605Smrg * \param reading  if TRUE, we're going to read from the buffer,
682848b8605Smrg                   if FALSE, we're going to write to the buffer.
683848b8605Smrg * \return GL_TRUE if buffer exists, GL_FALSE otherwise
684848b8605Smrg */
685848b8605Smrgstatic GLboolean
686848b8605Smrgrenderbuffer_exists(struct gl_context *ctx,
687848b8605Smrg                    struct gl_framebuffer *fb,
688848b8605Smrg                    GLenum format,
689848b8605Smrg                    GLboolean reading)
690848b8605Smrg{
691848b8605Smrg   const struct gl_renderbuffer_attachment *att = fb->Attachment;
692848b8605Smrg
693848b8605Smrg   /* If we don't know the framebuffer status, update it now */
694848b8605Smrg   if (fb->_Status == 0) {
695848b8605Smrg      _mesa_test_framebuffer_completeness(ctx, fb);
696848b8605Smrg   }
697848b8605Smrg
698848b8605Smrg   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
699848b8605Smrg      return GL_FALSE;
700848b8605Smrg   }
701848b8605Smrg
702848b8605Smrg   switch (format) {
703848b8605Smrg   case GL_COLOR:
704848b8605Smrg   case GL_RED:
705848b8605Smrg   case GL_GREEN:
706848b8605Smrg   case GL_BLUE:
707848b8605Smrg   case GL_ALPHA:
708848b8605Smrg   case GL_LUMINANCE:
709848b8605Smrg   case GL_LUMINANCE_ALPHA:
710848b8605Smrg   case GL_INTENSITY:
711848b8605Smrg   case GL_RG:
712848b8605Smrg   case GL_RGB:
713848b8605Smrg   case GL_BGR:
714848b8605Smrg   case GL_RGBA:
715848b8605Smrg   case GL_BGRA:
716848b8605Smrg   case GL_ABGR_EXT:
717848b8605Smrg   case GL_RED_INTEGER_EXT:
718848b8605Smrg   case GL_RG_INTEGER:
719848b8605Smrg   case GL_GREEN_INTEGER_EXT:
720848b8605Smrg   case GL_BLUE_INTEGER_EXT:
721848b8605Smrg   case GL_ALPHA_INTEGER_EXT:
722848b8605Smrg   case GL_RGB_INTEGER_EXT:
723848b8605Smrg   case GL_RGBA_INTEGER_EXT:
724848b8605Smrg   case GL_BGR_INTEGER_EXT:
725848b8605Smrg   case GL_BGRA_INTEGER_EXT:
726848b8605Smrg   case GL_LUMINANCE_INTEGER_EXT:
727848b8605Smrg   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
728848b8605Smrg      if (reading) {
729848b8605Smrg         /* about to read from a color buffer */
730848b8605Smrg         const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer;
731848b8605Smrg         if (!readBuf) {
732848b8605Smrg            return GL_FALSE;
733848b8605Smrg         }
734b8e80941Smrg         assert(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 ||
735848b8605Smrg                _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 ||
736848b8605Smrg                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 ||
737848b8605Smrg                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 ||
738848b8605Smrg                _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0);
739848b8605Smrg      }
740848b8605Smrg      else {
741848b8605Smrg         /* about to draw to zero or more color buffers (none is OK) */
742848b8605Smrg         return GL_TRUE;
743848b8605Smrg      }
744848b8605Smrg      break;
745848b8605Smrg   case GL_DEPTH:
746848b8605Smrg   case GL_DEPTH_COMPONENT:
747848b8605Smrg      if (att[BUFFER_DEPTH].Type == GL_NONE) {
748848b8605Smrg         return GL_FALSE;
749848b8605Smrg      }
750848b8605Smrg      break;
751848b8605Smrg   case GL_STENCIL:
752848b8605Smrg   case GL_STENCIL_INDEX:
753848b8605Smrg      if (att[BUFFER_STENCIL].Type == GL_NONE) {
754848b8605Smrg         return GL_FALSE;
755848b8605Smrg      }
756848b8605Smrg      break;
757848b8605Smrg   case GL_DEPTH_STENCIL_EXT:
758848b8605Smrg      if (att[BUFFER_DEPTH].Type == GL_NONE ||
759848b8605Smrg          att[BUFFER_STENCIL].Type == GL_NONE) {
760848b8605Smrg         return GL_FALSE;
761848b8605Smrg      }
762848b8605Smrg      break;
763848b8605Smrg   default:
764848b8605Smrg      _mesa_problem(ctx,
765848b8605Smrg                    "Unexpected format 0x%x in renderbuffer_exists",
766848b8605Smrg                    format);
767848b8605Smrg      return GL_FALSE;
768848b8605Smrg   }
769848b8605Smrg
770848b8605Smrg   /* OK */
771848b8605Smrg   return GL_TRUE;
772848b8605Smrg}
773848b8605Smrg
774848b8605Smrg
775848b8605Smrg/**
776848b8605Smrg * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
777848b8605Smrg * glCopyTex[Sub]Image, etc) exists.
778848b8605Smrg * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
779848b8605Smrg *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
780848b8605Smrg * \return GL_TRUE if buffer exists, GL_FALSE otherwise
781848b8605Smrg */
782848b8605SmrgGLboolean
783848b8605Smrg_mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
784848b8605Smrg{
785848b8605Smrg   return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE);
786848b8605Smrg}
787848b8605Smrg
788848b8605Smrg
789848b8605Smrg/**
790848b8605Smrg * As above, but for drawing operations.
791848b8605Smrg */
792848b8605SmrgGLboolean
793848b8605Smrg_mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
794848b8605Smrg{
795848b8605Smrg   return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE);
796848b8605Smrg}
797848b8605Smrg
798848b8605Smrg
799848b8605Smrg/**
800b8e80941Smrg * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using
801b8e80941Smrg * GetIntegerv, GetFramebufferParameteriv, etc)
802b8e80941Smrg *
803b8e80941Smrg * If @fb is NULL, the method returns the value for the current bound
804b8e80941Smrg * framebuffer.
805848b8605Smrg */
806848b8605SmrgGLenum
807b8e80941Smrg_mesa_get_color_read_format(struct gl_context *ctx,
808b8e80941Smrg                            struct gl_framebuffer *fb,
809b8e80941Smrg                            const char *caller)
810848b8605Smrg{
811b8e80941Smrg   if (ctx->NewState)
812b8e80941Smrg      _mesa_update_state(ctx);
813b8e80941Smrg
814b8e80941Smrg   if (fb == NULL)
815b8e80941Smrg      fb = ctx->ReadBuffer;
816b8e80941Smrg
817b8e80941Smrg   if (!fb || !fb->_ColorReadBuffer) {
818b8e80941Smrg      /*
819b8e80941Smrg       * From OpenGL 4.5 spec, section 18.2.2 "ReadPixels":
820b8e80941Smrg       *
821b8e80941Smrg       *    "An INVALID_OPERATION error is generated by GetIntegerv if pname
822b8e80941Smrg       *     is IMPLEMENTATION_COLOR_READ_FORMAT or IMPLEMENTATION_COLOR_-
823b8e80941Smrg       *     READ_TYPE and any of:
824b8e80941Smrg       *      * the read framebuffer is not framebuffer complete.
825b8e80941Smrg       *      * the read framebuffer is a framebuffer object, and the selected
826b8e80941Smrg       *        read buffer (see section 18.2.1) has no image attached.
827b8e80941Smrg       *      * the selected read buffer is NONE."
828b8e80941Smrg       *
829b8e80941Smrg       * There is not equivalent quote for GetFramebufferParameteriv or
830b8e80941Smrg       * GetNamedFramebufferParameteriv, but from section 9.2.3 "Framebuffer
831b8e80941Smrg       * Object Queries":
832b8e80941Smrg       *
833b8e80941Smrg       *    "Values of framebuffer-dependent state are identical to those that
834b8e80941Smrg       *     would be obtained were the framebuffer object bound and queried
835b8e80941Smrg       *     using the simple state queries in that table."
836b8e80941Smrg       *
837b8e80941Smrg       * Where "using the simple state queries" refer to use GetIntegerv. So
838b8e80941Smrg       * we will assume that on that situation the same error should be
839b8e80941Smrg       * triggered too.
840848b8605Smrg       */
841848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
842b8e80941Smrg                  "%s(GL_IMPLEMENTATION_COLOR_READ_FORMAT: no GL_READ_BUFFER)",
843b8e80941Smrg                  caller);
844848b8605Smrg      return GL_NONE;
845848b8605Smrg   }
846848b8605Smrg   else {
847b8e80941Smrg      const mesa_format format = fb->_ColorReadBuffer->Format;
848848b8605Smrg
849b8e80941Smrg      switch (format) {
850b8e80941Smrg      case MESA_FORMAT_RGBA_UINT8:
851b8e80941Smrg         return GL_RGBA_INTEGER;
852b8e80941Smrg      case MESA_FORMAT_B8G8R8A8_UNORM:
853848b8605Smrg         return GL_BGRA;
854b8e80941Smrg      case MESA_FORMAT_B5G6R5_UNORM:
855b8e80941Smrg      case MESA_FORMAT_R11G11B10_FLOAT:
856b8e80941Smrg         return GL_RGB;
857b8e80941Smrg      case MESA_FORMAT_RG_FLOAT32:
858b8e80941Smrg      case MESA_FORMAT_RG_FLOAT16:
859b8e80941Smrg      case MESA_FORMAT_R8G8_UNORM:
860b8e80941Smrg      case MESA_FORMAT_R8G8_SNORM:
861b8e80941Smrg         return GL_RG;
862b8e80941Smrg      case MESA_FORMAT_RG_SINT32:
863b8e80941Smrg      case MESA_FORMAT_RG_UINT32:
864b8e80941Smrg      case MESA_FORMAT_RG_SINT16:
865b8e80941Smrg      case MESA_FORMAT_RG_UINT16:
866b8e80941Smrg      case MESA_FORMAT_RG_SINT8:
867b8e80941Smrg      case MESA_FORMAT_RG_UINT8:
868b8e80941Smrg         return GL_RG_INTEGER;
869b8e80941Smrg      case MESA_FORMAT_R_FLOAT32:
870b8e80941Smrg      case MESA_FORMAT_R_FLOAT16:
871b8e80941Smrg      case MESA_FORMAT_R_UNORM16:
872b8e80941Smrg      case MESA_FORMAT_R_UNORM8:
873b8e80941Smrg      case MESA_FORMAT_R_SNORM16:
874b8e80941Smrg      case MESA_FORMAT_R_SNORM8:
875b8e80941Smrg         return GL_RED;
876b8e80941Smrg      case MESA_FORMAT_R_SINT32:
877b8e80941Smrg      case MESA_FORMAT_R_UINT32:
878b8e80941Smrg      case MESA_FORMAT_R_SINT16:
879b8e80941Smrg      case MESA_FORMAT_R_UINT16:
880b8e80941Smrg      case MESA_FORMAT_R_SINT8:
881b8e80941Smrg      case MESA_FORMAT_R_UINT8:
882b8e80941Smrg         return GL_RED_INTEGER;
883b8e80941Smrg      default:
884b8e80941Smrg         break;
885b8e80941Smrg      }
886848b8605Smrg
887b8e80941Smrg      if (_mesa_is_format_integer(format))
888848b8605Smrg         return GL_RGBA_INTEGER;
889b8e80941Smrg      else
890848b8605Smrg         return GL_RGBA;
891848b8605Smrg   }
892848b8605Smrg}
893848b8605Smrg
894848b8605Smrg
895848b8605Smrg/**
896b8e80941Smrg * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES queries (using
897b8e80941Smrg * GetIntegerv, GetFramebufferParameteriv, etc)
898b8e80941Smrg *
899b8e80941Smrg * If @fb is NULL, the method returns the value for the current bound
900b8e80941Smrg * framebuffer.
901848b8605Smrg */
902848b8605SmrgGLenum
903b8e80941Smrg_mesa_get_color_read_type(struct gl_context *ctx,
904b8e80941Smrg                          struct gl_framebuffer *fb,
905b8e80941Smrg                          const char *caller)
906848b8605Smrg{
907b8e80941Smrg   if (ctx->NewState)
908b8e80941Smrg      _mesa_update_state(ctx);
909b8e80941Smrg
910b8e80941Smrg   if (fb == NULL)
911b8e80941Smrg      fb = ctx->ReadBuffer;
912b8e80941Smrg
913b8e80941Smrg   if (!fb || !fb->_ColorReadBuffer) {
914b8e80941Smrg      /*
915b8e80941Smrg       * See comment on _mesa_get_color_read_format
916848b8605Smrg       */
917848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
918b8e80941Smrg                  "%s(GL_IMPLEMENTATION_COLOR_READ_TYPE: no GL_READ_BUFFER)",
919b8e80941Smrg                  caller);
920848b8605Smrg      return GL_NONE;
921848b8605Smrg   }
922848b8605Smrg   else {
923b8e80941Smrg      const mesa_format format = fb->_ColorReadBuffer->Format;
924b8e80941Smrg      GLenum data_type;
925b8e80941Smrg      GLuint comps;
926b8e80941Smrg
927b8e80941Smrg      _mesa_uncompressed_format_to_type_and_comps(format, &data_type, &comps);
928b8e80941Smrg
929b8e80941Smrg      return data_type;
930848b8605Smrg   }
931848b8605Smrg}
932848b8605Smrg
933848b8605Smrg
934848b8605Smrg/**
935848b8605Smrg * Returns the read renderbuffer for the specified format.
936848b8605Smrg */
937848b8605Smrgstruct gl_renderbuffer *
938848b8605Smrg_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx,
939848b8605Smrg                                       GLenum format)
940848b8605Smrg{
941848b8605Smrg   const struct gl_framebuffer *rfb = ctx->ReadBuffer;
942848b8605Smrg
943848b8605Smrg   if (_mesa_is_color_format(format)) {
944848b8605Smrg      return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer;
945848b8605Smrg   } else if (_mesa_is_depth_format(format) ||
946848b8605Smrg              _mesa_is_depthstencil_format(format)) {
947848b8605Smrg      return rfb->Attachment[BUFFER_DEPTH].Renderbuffer;
948848b8605Smrg   } else {
949848b8605Smrg      return rfb->Attachment[BUFFER_STENCIL].Renderbuffer;
950848b8605Smrg   }
951848b8605Smrg}
952848b8605Smrg
953848b8605Smrg
954848b8605Smrg/**
955848b8605Smrg * Print framebuffer info to stderr, for debugging.
956848b8605Smrg */
957848b8605Smrgvoid
958848b8605Smrg_mesa_print_framebuffer(const struct gl_framebuffer *fb)
959848b8605Smrg{
960848b8605Smrg   fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
961848b8605Smrg   fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
962b8e80941Smrg           _mesa_enum_to_string(fb->_Status));
963848b8605Smrg   fprintf(stderr, "  Attachments:\n");
964848b8605Smrg
965b8e80941Smrg   for (unsigned i = 0; i < BUFFER_COUNT; i++) {
966848b8605Smrg      const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
967848b8605Smrg      if (att->Type == GL_TEXTURE) {
968848b8605Smrg         const struct gl_texture_image *texImage = att->Renderbuffer->TexImage;
969848b8605Smrg         fprintf(stderr,
970848b8605Smrg                 "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
971848b8605Smrg                 i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
972848b8605Smrg                 att->Zoffset, att->Complete);
973848b8605Smrg         fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
974848b8605Smrg                 texImage->Width, texImage->Height, texImage->Depth,
975848b8605Smrg                 _mesa_get_format_name(texImage->TexFormat));
976848b8605Smrg      }
977848b8605Smrg      else if (att->Type == GL_RENDERBUFFER) {
978848b8605Smrg         fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
979848b8605Smrg                 i, att->Renderbuffer->Name, att->Complete);
980848b8605Smrg         fprintf(stderr, "       Size: %u x %u  Format %s\n",
981848b8605Smrg                 att->Renderbuffer->Width, att->Renderbuffer->Height,
982848b8605Smrg                 _mesa_get_format_name(att->Renderbuffer->Format));
983848b8605Smrg      }
984848b8605Smrg      else {
985848b8605Smrg         fprintf(stderr, "  %2d: none\n", i);
986848b8605Smrg      }
987848b8605Smrg   }
988848b8605Smrg}
989b8e80941Smrg
990b8e80941Smrgbool
991b8e80941Smrg_mesa_is_front_buffer_reading(const struct gl_framebuffer *fb)
992b8e80941Smrg{
993b8e80941Smrg   if (!fb || _mesa_is_user_fbo(fb))
994b8e80941Smrg      return false;
995b8e80941Smrg
996b8e80941Smrg   return fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT;
997b8e80941Smrg}
998b8e80941Smrg
999b8e80941Smrgbool
1000b8e80941Smrg_mesa_is_front_buffer_drawing(const struct gl_framebuffer *fb)
1001b8e80941Smrg{
1002b8e80941Smrg   if (!fb || _mesa_is_user_fbo(fb))
1003b8e80941Smrg      return false;
1004b8e80941Smrg
1005b8e80941Smrg   return (fb->_NumColorDrawBuffers >= 1 &&
1006b8e80941Smrg           fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT);
1007b8e80941Smrg}
1008b8e80941Smrg
1009b8e80941Smrgstatic inline GLuint
1010b8e80941Smrg_mesa_geometric_nonvalidated_samples(const struct gl_framebuffer *buffer)
1011b8e80941Smrg{
1012b8e80941Smrg   return buffer->_HasAttachments ?
1013b8e80941Smrg      buffer->Visual.samples :
1014b8e80941Smrg      buffer->DefaultGeometry.NumSamples;
1015b8e80941Smrg}
1016b8e80941Smrg
1017b8e80941Smrgbool
1018b8e80941Smrg_mesa_is_multisample_enabled(const struct gl_context *ctx)
1019b8e80941Smrg{
1020b8e80941Smrg   /* The sample count may not be validated by the driver, but when it is set,
1021b8e80941Smrg    * we know that is in a valid range and no driver should ever validate a
1022b8e80941Smrg    * multisampled framebuffer to non-multisampled and vice-versa.
1023b8e80941Smrg    */
1024b8e80941Smrg   return ctx->Multisample.Enabled &&
1025b8e80941Smrg          ctx->DrawBuffer &&
1026b8e80941Smrg          _mesa_geometric_nonvalidated_samples(ctx->DrawBuffer) >= 1;
1027b8e80941Smrg}
1028b8e80941Smrg
1029b8e80941Smrg/**
1030b8e80941Smrg * Is alpha testing enabled and applicable to the currently bound
1031b8e80941Smrg * framebuffer?
1032b8e80941Smrg */
1033b8e80941Smrgbool
1034b8e80941Smrg_mesa_is_alpha_test_enabled(const struct gl_context *ctx)
1035b8e80941Smrg{
1036b8e80941Smrg   bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1;
1037b8e80941Smrg   return (ctx->Color.AlphaEnabled && !buffer0_is_integer);
1038b8e80941Smrg}
1039b8e80941Smrg
1040b8e80941Smrg/**
1041b8e80941Smrg * Is alpha to coverage enabled and applicable to the currently bound
1042b8e80941Smrg * framebuffer?
1043b8e80941Smrg */
1044b8e80941Smrgbool
1045b8e80941Smrg_mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx)
1046b8e80941Smrg{
1047b8e80941Smrg   bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1;
1048b8e80941Smrg   return (ctx->Multisample.SampleAlphaToCoverage &&
1049b8e80941Smrg           _mesa_is_multisample_enabled(ctx) &&
1050b8e80941Smrg           !buffer0_is_integer);
1051b8e80941Smrg}
1052