1e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/*
2e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Mesa 3-D graphics library
30fd1a8c4a1201f3508cb6a98dc1c66ab9ebd919fBrian Paul * Version:  7.2
4e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
50fd1a8c4a1201f3508cb6a98dc1c66ab9ebd919fBrian Paul * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
7e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
8e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * copy of this software and associated documentation files (the "Software"),
9e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * to deal in the Software without restriction, including without limitation
10e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
12e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Software is furnished to do so, subject to the following conditions:
13e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
14e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The above copyright notice and this permission notice shall be included
15e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * in all copies or substantial portions of the Software.
16e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
17e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
24e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
25e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
26e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
27e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Functions for allocating/managing framebuffers and renderbuffers.
28e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Also, routines for reading/writing renderbuffer data as ubytes,
29e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * ushorts, uints, etc.
30e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
31e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
32e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
33e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "glheader.h"
34e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "imports.h"
3532d86eb28aedd01a03ceab746214a8db2a4cbbabBrian#include "buffers.h"
36e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "context.h"
37421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul#include "enums.h"
3845e76d2665b38ba3787548310efc59e969124c01Brian Paul#include "formats.h"
39283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul#include "macros.h"
40e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "mtypes.h"
41e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "fbobject.h"
42e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "framebuffer.h"
43e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "renderbuffer.h"
449e01b915f1243a3f551cb795b7124bd1e52ca15fBrian#include "texobj.h"
45e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
46e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
47e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
48e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
49e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Compute/set the _DepthMax field for the given framebuffer.
50e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * This value depends on the Z buffer resolution.
51e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
52e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void
53e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulcompute_depth_max(struct gl_framebuffer *fb)
54e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
55e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (fb->Visual.depthBits == 0) {
56e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Special case.  Even if we don't have a depth buffer we need
57e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       * good values for DepthMax for Z vertex transformation purposes
58e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       * and for per-fragment fog computation.
59e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       */
60e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->_DepthMax = (1 << 16) - 1;
61e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
62e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else if (fb->Visual.depthBits < 32) {
63e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
64e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
65e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else {
66e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Special case since shift values greater than or equal to the
67e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       * number of bits in the left hand expression's type are undefined.
68e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       */
69e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->_DepthMax = 0xffffffff;
70e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
71e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
72b755a2d9de5b7977c410a904a8adb7c07c88f82aBrian
73b755a2d9de5b7977c410a904a8adb7c07c88f82aBrian   /* Minimum resolvable depth value, for polygon offset */
74452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca   fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
75e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
76e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
77e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
78e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Create and initialize a gl_framebuffer object.
79e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * This is intended for creating _window_system_ framebuffers, not generic
80e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * framebuffer objects ala GL_EXT_framebuffer_object.
81e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
82e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * \sa _mesa_new_framebuffer
83e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
84e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstruct gl_framebuffer *
85d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsberg_mesa_create_framebuffer(const struct gl_config *visual)
86e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
87e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
88e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   assert(visual);
89e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (fb) {
902ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez      _mesa_initialize_window_framebuffer(fb, visual);
91e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
92e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return fb;
93e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
94e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
95e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
96e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
97e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Allocate a new gl_framebuffer object.
98e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * This is the default function for ctx->Driver.NewFramebuffer().
99e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * This is for allocating user-created framebuffers, not window-system
100e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * framebuffers!
101e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * \sa _mesa_create_framebuffer
102e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
103e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstruct gl_framebuffer *
104f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
105e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
106e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct gl_framebuffer *fb;
10728b014ee256290eb0494b967e40c475c0c895f57Brian Paul   (void) ctx;
108e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   assert(name != 0);
109e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb = CALLOC_STRUCT(gl_framebuffer);
110e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (fb) {
1112ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez      _mesa_initialize_user_framebuffer(fb, name);
112e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
113e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return fb;
114e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
115e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
116e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
117e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
118f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul * Initialize a gl_framebuffer object.  Typically used to initialize
119f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul * window system-created framebuffers, not user-created framebuffers.
1202ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez * \sa _mesa_initialize_user_framebuffer
121e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
122e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
1232ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
124d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsberg				     const struct gl_config *visual)
125e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
126e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   assert(fb);
127e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   assert(visual);
128e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1296bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(fb, 0, sizeof(struct gl_framebuffer));
130e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
131ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   _glthread_INIT_MUTEX(fb->Mutex);
132ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
133e6a9381f78605072cab52447fce35eaa98c1e75cBrian   fb->RefCount = 1;
134e6a9381f78605072cab52447fce35eaa98c1e75cBrian
135e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   /* save the visual */
136e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb->Visual = *visual;
137e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
138c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian   /* Init read/draw renderbuffer state */
139e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (visual->doubleBufferMode) {
140601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      fb->_NumColorDrawBuffers = 1;
141e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->ColorDrawBuffer[0] = GL_BACK;
142601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
143e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->ColorReadBuffer = GL_BACK;
144048b13df65f222b10564091df3dfa2b6cab77631Brian Paul      fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
145e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
146e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else {
147601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      fb->_NumColorDrawBuffers = 1;
148e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->ColorDrawBuffer[0] = GL_FRONT;
149601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
150e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->ColorReadBuffer = GL_FRONT;
151048b13df65f222b10564091df3dfa2b6cab77631Brian Paul      fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
152e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
153e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
154e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb->Delete = _mesa_destroy_framebuffer;
155d95000da2fdad78f25618fe9703f23806587b65aBrian Paul   fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
156e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
157e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   compute_depth_max(fb);
158e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
159e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
160e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
161e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
1622ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez * Initialize a user-created gl_framebuffer object.
1632ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez * \sa _mesa_initialize_window_framebuffer
1642ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez */
1652ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerezvoid
1662ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
1672ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez{
1682ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   assert(fb);
1692ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   assert(name);
1702ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez
1716bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(fb, 0, sizeof(struct gl_framebuffer));
1722ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez
1732ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->Name = name;
1742ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->RefCount = 1;
1752ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->_NumColorDrawBuffers = 1;
1762ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
1772ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
1782ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
1792ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->_ColorReadBufferIndex = BUFFER_COLOR0;
1802ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   fb->Delete = _mesa_destroy_framebuffer;
1812ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez   _glthread_INIT_MUTEX(fb->Mutex);
1822ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez}
1832ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez
1842ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez
1852ec50d256d49ff3b987459ed42a5dc66f02a6b9dFrancisco Jerez/**
186e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Deallocate buffer and everything attached to it.
187f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul * Typically called via the gl_framebuffer->Delete() method.
188e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
189e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
190f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
191e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
192f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul   if (fb) {
193f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul      _mesa_free_framebuffer_data(fb);
19432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(fb);
195e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
196e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
197e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
198e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
199e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
200e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Free all the data hanging off the given gl_framebuffer, but don't free
201e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the gl_framebuffer object itself.
202e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
203e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
204e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
205e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
206e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLuint i;
207e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
208e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   assert(fb);
209f30e31276304696558abffdd9a6e3df21d41c0f5Brian   assert(fb->RefCount == 0);
210e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
211e6a9381f78605072cab52447fce35eaa98c1e75cBrian   _glthread_DESTROY_MUTEX(fb->Mutex);
212e6a9381f78605072cab52447fce35eaa98c1e75cBrian
213e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   for (i = 0; i < BUFFER_COUNT; i++) {
214e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
215753af3a206e3976be9a0954578d866218fdbf30aBrian Paul      if (att->Renderbuffer) {
21642aaa548a1020be5d40b3dce9448d8004b1ef947Brian         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
217593802c0b0f451299ac2598c6de61e884fb44830Brian      }
218593802c0b0f451299ac2598c6de61e884fb44830Brian      if (att->Texture) {
2199e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         _mesa_reference_texobj(&att->Texture, NULL);
220e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
2219e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      ASSERT(!att->Renderbuffer);
2229e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      ASSERT(!att->Texture);
223e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      att->Type = GL_NONE;
224e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
225e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
226e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
227e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
228e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
229a510bc3ee1a696da120c09ee4ec33dc033f671acBrian * Set *ptr to point to fb, with refcounting and locking.
2305db7723ada0be301b7f8eed754cb62f8a84d6768Brian Paul * This is normally only called from the _mesa_reference_framebuffer() macro
2315db7723ada0be301b7f8eed754cb62f8a84d6768Brian Paul * when there's a real pointer change.
232a510bc3ee1a696da120c09ee4ec33dc033f671acBrian */
233a510bc3ee1a696da120c09ee4ec33dc033f671acBrianvoid
2345db7723ada0be301b7f8eed754cb62f8a84d6768Brian Paul_mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
2355db7723ada0be301b7f8eed754cb62f8a84d6768Brian Paul                             struct gl_framebuffer *fb)
236a510bc3ee1a696da120c09ee4ec33dc033f671acBrian{
2371a6baf092b4c31d5fd30c934f1a17d69c9689f12Brian   if (*ptr) {
23849002698193784dacffcbf993de26fcdd42c523eBrian Paul      /* unreference old renderbuffer */
23949002698193784dacffcbf993de26fcdd42c523eBrian Paul      GLboolean deleteFlag = GL_FALSE;
24049002698193784dacffcbf993de26fcdd42c523eBrian Paul      struct gl_framebuffer *oldFb = *ptr;
24149002698193784dacffcbf993de26fcdd42c523eBrian Paul
24249002698193784dacffcbf993de26fcdd42c523eBrian Paul      _glthread_LOCK_MUTEX(oldFb->Mutex);
24349002698193784dacffcbf993de26fcdd42c523eBrian Paul      ASSERT(oldFb->RefCount > 0);
24449002698193784dacffcbf993de26fcdd42c523eBrian Paul      oldFb->RefCount--;
24549002698193784dacffcbf993de26fcdd42c523eBrian Paul      deleteFlag = (oldFb->RefCount == 0);
24649002698193784dacffcbf993de26fcdd42c523eBrian Paul      _glthread_UNLOCK_MUTEX(oldFb->Mutex);
24749002698193784dacffcbf993de26fcdd42c523eBrian Paul
24849002698193784dacffcbf993de26fcdd42c523eBrian Paul      if (deleteFlag)
24949002698193784dacffcbf993de26fcdd42c523eBrian Paul         oldFb->Delete(oldFb);
25049002698193784dacffcbf993de26fcdd42c523eBrian Paul
25149002698193784dacffcbf993de26fcdd42c523eBrian Paul      *ptr = NULL;
2521a6baf092b4c31d5fd30c934f1a17d69c9689f12Brian   }
253a510bc3ee1a696da120c09ee4ec33dc033f671acBrian   assert(!*ptr);
25449002698193784dacffcbf993de26fcdd42c523eBrian Paul
25549002698193784dacffcbf993de26fcdd42c523eBrian Paul   if (fb) {
25649002698193784dacffcbf993de26fcdd42c523eBrian Paul      _glthread_LOCK_MUTEX(fb->Mutex);
25749002698193784dacffcbf993de26fcdd42c523eBrian Paul      fb->RefCount++;
25849002698193784dacffcbf993de26fcdd42c523eBrian Paul      _glthread_UNLOCK_MUTEX(fb->Mutex);
25949002698193784dacffcbf993de26fcdd42c523eBrian Paul      *ptr = fb;
26049002698193784dacffcbf993de26fcdd42c523eBrian Paul   }
261a510bc3ee1a696da120c09ee4ec33dc033f671acBrian}
262a510bc3ee1a696da120c09ee4ec33dc033f671acBrian
263a510bc3ee1a696da120c09ee4ec33dc033f671acBrian
264a510bc3ee1a696da120c09ee4ec33dc033f671acBrian/**
265e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Resize the given framebuffer's renderbuffers to the new width and height.
266e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * This should only be used for window-system framebuffers, not
267e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
268847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul * This will typically be called via ctx->Driver.ResizeBuffers() or directly
269847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul * from a device driver.
270847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul *
271847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul * \note it's possible for ctx to be null since a window can be resized
272847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul * without a currently bound rendering context.
273e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
274e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
275f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
276e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                         GLuint width, GLuint height)
277e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
278e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLuint i;
279e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
280ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   /* XXX I think we could check if the size is not changing
281ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul    * and return early.
282ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul    */
283ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
28436ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul   /* Can only resize win-sys framebuffer objects */
28536ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul   assert(_mesa_is_winsys_fbo(fb));
286e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
287e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   for (i = 0; i < BUFFER_COUNT; i++) {
288e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
289e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
290e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         struct gl_renderbuffer *rb = att->Renderbuffer;
291e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         /* only resize if size is changing */
292e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         if (rb->Width != width || rb->Height != height) {
293e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
294ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               ASSERT(rb->Width == width);
295ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               ASSERT(rb->Height == height);
296e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            }
297e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            else {
298e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul               _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
299ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               /* no return */
300e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            }
301e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         }
302e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
303e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
304e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
305e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb->Width = width;
306e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   fb->Height = height;
30752f686c48080cec9a26aa23d16bc14bd3d302d70Brian Paul
308041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul   if (ctx) {
309041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul      /* update scissor / window bounds */
310feb0ff11e5d429e1444f9987137c929adfb09bc8Alan Hourihane      _mesa_update_draw_buffer_bounds(ctx);
311041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul      /* Signal new buffer state so that swrast will update its clipping
312041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul       * info (the CLIP_BIT flag).
313041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul       */
314041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul      ctx->NewState |= _NEW_BUFFERS;
315041d64812e4fa7a0444aa35c59d14ce85240b5deBrian Paul   }
316e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
317e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
318e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
319e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
320e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul/**
321e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * XXX THIS IS OBSOLETE - drivers should take care of detecting window
322e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * size changes and act accordingly, likely calling _mesa_resize_framebuffer().
323e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul *
324e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * GL_MESA_resize_buffers extension.
325e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul *
326e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * When this function is called, we'll ask the window system how large
327e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * the current window is.  If it's a new size, we'll call the driver's
328e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * ResizeBuffers function.  The driver will then resize its color buffers
329e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * as needed, and maybe call the swrast's routine for reallocating
330e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * swrast-managed depth/stencil/accum/etc buffers.
331e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * \note This function should only be called through the GL API, not
332e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * from device drivers (as was done in the past).
333e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul */
334e48defc98045f419e71ca13e4f45470b2336ecafBrian Paulvoid
335f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_resizebuffers( struct gl_context *ctx )
336e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul{
337e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
338e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
339e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   if (MESA_VERBOSE & VERBOSE_API)
340e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      _mesa_debug(ctx, "glResizeBuffersMESA\n");
341e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
342e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   if (!ctx->Driver.GetBufferSize) {
343e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      return;
344e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   }
345e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
346e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   if (ctx->WinSysDrawBuffer) {
347e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      GLuint newWidth, newHeight;
34831aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg      struct gl_framebuffer *buffer = ctx->WinSysDrawBuffer;
349e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
350284ad9c3b29a6d6f0bade050ea9e949d67967983Paul Berry      assert(_mesa_is_winsys_fbo(buffer));
351e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
352e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      /* ask device driver for size of output buffer */
353e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
354e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
355e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      /* see if size of device driver's color buffer (window) has changed */
356e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      if (buffer->Width != newWidth || buffer->Height != newHeight) {
357e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul         if (ctx->Driver.ResizeBuffers)
358e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
359e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      }
360e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   }
361e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
362e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   if (ctx->WinSysReadBuffer
363e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul       && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
364e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      GLuint newWidth, newHeight;
36531aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg      struct gl_framebuffer *buffer = ctx->WinSysReadBuffer;
366e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
367284ad9c3b29a6d6f0bade050ea9e949d67967983Paul Berry      assert(_mesa_is_winsys_fbo(buffer));
368e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
369e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      /* ask device driver for size of read buffer */
370e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
371e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
372e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      /* see if size of device driver's color buffer (window) has changed */
373e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      if (buffer->Width != newWidth || buffer->Height != newHeight) {
374e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul         if (ctx->Driver.ResizeBuffers)
375e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
376e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      }
377e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   }
378e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
379e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
380e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul}
381e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
382e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
383e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul/*
384e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul * XXX THIS IS OBSOLETE
385e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul */
386e48defc98045f419e71ca13e4f45470b2336ecafBrian Paulvoid GLAPIENTRY
387e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul_mesa_ResizeBuffersMESA( void )
388e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul{
389e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   GET_CURRENT_CONTEXT(ctx);
390e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
391e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul   if (ctx->Extensions.MESA_resize_buffers)
392e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul      _mesa_resizebuffers( ctx );
393e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul}
394e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
395e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
396e48defc98045f419e71ca13e4f45470b2336ecafBrian Paul
397e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
398e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Examine all the framebuffer's renderbuffers to update the Width/Height
399e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * fields of the framebuffer.  If we have renderbuffers with different
400283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul * sizes, set the framebuffer's width and height to the min size.
401e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Note: this is only intended for user-created framebuffers, not
402e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * window-system framebuffes.
403e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
404e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void
405f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergupdate_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
406e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
407283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul   GLuint minWidth = ~0, minHeight = ~0;
408e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLuint i;
409e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
410e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   /* user-created framebuffers only */
41136ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul   assert(_mesa_is_user_fbo(fb));
412e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
413e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   for (i = 0; i < BUFFER_COUNT; i++) {
414e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
415e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      const struct gl_renderbuffer *rb = att->Renderbuffer;
416e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (rb) {
417283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul         minWidth = MIN2(minWidth, rb->Width);
418283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul         minHeight = MIN2(minHeight, rb->Height);
419e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
420e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
421283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul
422283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul   if (minWidth != ~0) {
423283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul      fb->Width = minWidth;
424283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul      fb->Height = minHeight;
425283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul   }
426283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul   else {
427283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul      fb->Width = 0;
428283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul      fb->Height = 0;
429283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul   }
430e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
431e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
432e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
433e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
434e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
435e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * These values are computed from the buffer's width and height and
436e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the scissor box, if it's enabled.
437e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * \param ctx  the GL context.
438e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
439e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
440f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_update_draw_buffer_bounds(struct gl_context *ctx)
441e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
442e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct gl_framebuffer *buffer = ctx->DrawBuffer;
443e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
444161de10ce885e73ca07a0c851d63bf1a732c1ea8Alan Hourihane   if (!buffer)
445161de10ce885e73ca07a0c851d63bf1a732c1ea8Alan Hourihane      return;
446161de10ce885e73ca07a0c851d63bf1a732c1ea8Alan Hourihane
447284ad9c3b29a6d6f0bade050ea9e949d67967983Paul Berry   if (_mesa_is_user_fbo(buffer)) {
448e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* user-created framebuffer size depends on the renderbuffers */
449283edbe31177522d006ab37ebaf33a6e31f0a34eBrian Paul      update_framebuffer_size(ctx, buffer);
450e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
451e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
452e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   buffer->_Xmin = 0;
453e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   buffer->_Ymin = 0;
454e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   buffer->_Xmax = buffer->Width;
455e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   buffer->_Ymax = buffer->Height;
456e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
457e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (ctx->Scissor.Enabled) {
458e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (ctx->Scissor.X > buffer->_Xmin) {
459e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul	 buffer->_Xmin = ctx->Scissor.X;
460e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
461e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (ctx->Scissor.Y > buffer->_Ymin) {
462e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul	 buffer->_Ymin = ctx->Scissor.Y;
463e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
464e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
465e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul	 buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
466e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
467e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
468e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul	 buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
469e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
470e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* finally, check for empty region */
471e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (buffer->_Xmin > buffer->_Xmax) {
472e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         buffer->_Xmin = buffer->_Xmax;
473e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
474e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (buffer->_Ymin > buffer->_Ymax) {
475e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         buffer->_Ymin = buffer->_Ymax;
476e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
477e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
478e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
479e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   ASSERT(buffer->_Xmin <= buffer->_Xmax);
480e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   ASSERT(buffer->_Ymin <= buffer->_Ymax);
481e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
482e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
483e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
484e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
485e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The glGet queries of the framebuffer red/green/blue size, stencil size,
486e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
487f084f60f8bdba23b3f6125549045c0791d3fe138Brian Paul * change depending on the renderbuffer bindings.  This function updates
488e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the given framebuffer's Visual from the current renderbuffer bindings.
48902aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul *
49002aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul * This may apply to user-created framebuffers or window system framebuffers.
491eb063cfa386ccf64e01be2fc6e6a44f702d19da5Brian Paul *
492eb063cfa386ccf64e01be2fc6e6a44f702d19da5Brian Paul * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
493eb063cfa386ccf64e01be2fc6e6a44f702d19da5Brian Paul * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
494eb063cfa386ccf64e01be2fc6e6a44f702d19da5Brian Paul * The former one is used to convert floating point depth values into
495eb063cfa386ccf64e01be2fc6e6a44f702d19da5Brian Paul * integer Z values.
496e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
497e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulvoid
498059cca92a819e20e0d834605a3a7d277eaf88d9fEric Anholt_mesa_update_framebuffer_visual(struct gl_context *ctx,
499059cca92a819e20e0d834605a3a7d277eaf88d9fEric Anholt				struct gl_framebuffer *fb)
500e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
501474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul   GLuint i;
502474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul
5036bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(&fb->Visual, 0, sizeof(fb->Visual));
504474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul   fb->Visual.rgbMode = GL_TRUE; /* assume this */
505474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul
50634b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul#if 0 /* this _might_ be needed */
50734b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
50834b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul      /* leave visual fields zero'd */
50934b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul      return;
51034b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul   }
51134b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul#endif
51234b3b40af97d2db6d46dcce46c4c49c198621fceBrian Paul
51322a96f305898b5d1aa26809c7156a01686eb9bf0Ian Romanick   /* find first RGB renderbuffer */
514474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul   for (i = 0; i < BUFFER_COUNT; i++) {
515474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul      if (fb->Attachment[i].Renderbuffer) {
516474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
51745e76d2665b38ba3787548310efc59e969124c01Brian Paul         const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
51845e76d2665b38ba3787548310efc59e969124c01Brian Paul         const gl_format fmt = rb->Format;
519059cca92a819e20e0d834605a3a7d277eaf88d9fEric Anholt
52048fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry         /* Grab samples and sampleBuffers from any attachment point (assuming
52148fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry          * the framebuffer is complete, we'll get the same answer from all
52248fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry          * attachments).
52348fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry          */
52448fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry         fb->Visual.samples = rb->NumSamples;
52548fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry         fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
52648fdfbcb58929f1c20cb21190846faa388b1abbaPaul Berry
527059cca92a819e20e0d834605a3a7d277eaf88d9fEric Anholt         if (_mesa_is_legal_color_format(ctx, baseFormat)) {
52845e76d2665b38ba3787548310efc59e969124c01Brian Paul            fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
52945e76d2665b38ba3787548310efc59e969124c01Brian Paul            fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
53045e76d2665b38ba3787548310efc59e969124c01Brian Paul            fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
53145e76d2665b38ba3787548310efc59e969124c01Brian Paul            fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
532474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul            fb->Visual.rgbBits = fb->Visual.redBits
533474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul               + fb->Visual.greenBits + fb->Visual.blueBits;
53488ffa9ce5b8e5fe2b93238f8b9a7a888be28324eDave Airlie            if (_mesa_get_format_color_encoding(fmt) == GL_SRGB)
53569c8f468ba93dc2999d4fde8909f8051e910929aMarek Olšák                fb->Visual.sRGBCapable = ctx->Extensions.EXT_framebuffer_sRGB;
536474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul            break;
537474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul         }
538474f28e57ca750ca39d7f684904a3c0e69a03f62Brian Paul      }
539e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
540e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
54115f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák   fb->Visual.floatMode = GL_FALSE;
54215f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák   for (i = 0; i < BUFFER_COUNT; i++) {
54315f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák      if (fb->Attachment[i].Renderbuffer) {
54415f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
54515f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák         const gl_format fmt = rb->Format;
54615f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák
54715f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák         if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
54815f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák            fb->Visual.floatMode = GL_TRUE;
54915f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák            break;
55015f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák         }
55115f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák      }
55215f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák   }
55315f99d13626b42f517467fd884a379cc7475e5d1Marek Olšák
554e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
55545e76d2665b38ba3787548310efc59e969124c01Brian Paul      const struct gl_renderbuffer *rb =
55645e76d2665b38ba3787548310efc59e969124c01Brian Paul         fb->Attachment[BUFFER_DEPTH].Renderbuffer;
55745e76d2665b38ba3787548310efc59e969124c01Brian Paul      const gl_format fmt = rb->Format;
558e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->Visual.haveDepthBuffer = GL_TRUE;
55945e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
560e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
561e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
562e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
56345e76d2665b38ba3787548310efc59e969124c01Brian Paul      const struct gl_renderbuffer *rb =
56445e76d2665b38ba3787548310efc59e969124c01Brian Paul         fb->Attachment[BUFFER_STENCIL].Renderbuffer;
56545e76d2665b38ba3787548310efc59e969124c01Brian Paul      const gl_format fmt = rb->Format;
566e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->Visual.haveStencilBuffer = GL_TRUE;
56745e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
568e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
569e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
57002aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul   if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
57145e76d2665b38ba3787548310efc59e969124c01Brian Paul      const struct gl_renderbuffer *rb =
57245e76d2665b38ba3787548310efc59e969124c01Brian Paul         fb->Attachment[BUFFER_ACCUM].Renderbuffer;
57345e76d2665b38ba3787548310efc59e969124c01Brian Paul      const gl_format fmt = rb->Format;
57402aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul      fb->Visual.haveAccumBuffer = GL_TRUE;
57545e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
57645e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
57745e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
57845e76d2665b38ba3787548310efc59e969124c01Brian Paul      fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
57902aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul   }
58002aa5fba0375a6013cc7cbaeb4883cc1263bbef4Brian Paul
581e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   compute_depth_max(fb);
582e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
583e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
584e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
585ff73c783cc47361ff0dd819c82d067b4b85870ddBrian/*
586ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * Example DrawBuffers scenarios:
587ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
588ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
589ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * "gl_FragColor" or program writes to the "result.color" register:
590ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
591ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   fragment color output   renderbuffer
592ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   ---------------------   ---------------
593ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   color[0]                Front, Back
594ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
595ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
596ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
597ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * gl_FragData[i] or program writes to result.color[i] registers:
598ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
599ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   fragment color output   renderbuffer
600ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   ---------------------   ---------------
601ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   color[0]                Front
602ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   color[1]                Aux0
603ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   color[3]                Aux1
604ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
605ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
606ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
607ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * gl_FragColor, or fixed function:
608ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
609ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   fragment color output   renderbuffer
610ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   ---------------------   ---------------
611ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   color[0]                Front, Aux0, Aux1
612ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
613ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
614ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * In either case, the list of renderbuffers is stored in the
615ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * framebuffer->_ColorDrawBuffers[] array and
616ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
617ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * The renderer (like swrast) has to look at the current fragment shader
618ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
619ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * how to map color outputs to renderbuffers.
620ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *
621ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * Note that these two calls are equivalent (for fixed function fragment
622ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * shading anyway):
623ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
624ff73c783cc47361ff0dd819c82d067b4b85870ddBrian *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
625ff73c783cc47361ff0dd819c82d067b4b85870ddBrian */
626ff73c783cc47361ff0dd819c82d067b4b85870ddBrian
627ff73c783cc47361ff0dd819c82d067b4b85870ddBrian
628ff73c783cc47361ff0dd819c82d067b4b85870ddBrian
629ff73c783cc47361ff0dd819c82d067b4b85870ddBrian
630847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul/**
63132d86eb28aedd01a03ceab746214a8db2a4cbbabBrian * Update the (derived) list of color drawing renderbuffer pointers.
632ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
633ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * writing colors.
634e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
635ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paulstatic void
636f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergupdate_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
637e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
638601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian   GLuint output;
639e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
6402a077500a84819d1e6ac62e84ded130aa655c5e9Brian   /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
6412a077500a84819d1e6ac62e84ded130aa655c5e9Brian   fb->_ColorDrawBuffers[0] = NULL;
6422a077500a84819d1e6ac62e84ded130aa655c5e9Brian
643601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian   for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
644601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      GLint buf = fb->_ColorDrawBufferIndexes[output];
645601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      if (buf >= 0) {
646601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian         fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
647ff73c783cc47361ff0dd819c82d067b4b85870ddBrian      }
648601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian      else {
649601a6b872c33bfe3cb4ea03a5a8ba5ebe92dedafBrian         fb->_ColorDrawBuffers[output] = NULL;
650e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
651e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
652ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul}
653e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
654ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
655ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul/**
65632d86eb28aedd01a03ceab746214a8db2a4cbbabBrian * Update the (derived) color read renderbuffer pointer.
657ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
658ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul */
659ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paulstatic void
660f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergupdate_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
661ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul{
66228b014ee256290eb0494b967e40c475c0c895f57Brian Paul   (void) ctx;
663e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian   if (fb->_ColorReadBufferIndex == -1 ||
664e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian       fb->DeletePending ||
665e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian       fb->Width == 0 ||
666e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian       fb->Height == 0) {
667e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      fb->_ColorReadBuffer = NULL; /* legal! */
668048b13df65f222b10564091df3dfa2b6cab77631Brian Paul   }
669048b13df65f222b10564091df3dfa2b6cab77631Brian Paul   else {
670048b13df65f222b10564091df3dfa2b6cab77631Brian Paul      ASSERT(fb->_ColorReadBufferIndex >= 0);
671048b13df65f222b10564091df3dfa2b6cab77631Brian Paul      ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
672048b13df65f222b10564091df3dfa2b6cab77631Brian Paul      fb->_ColorReadBuffer
673048b13df65f222b10564091df3dfa2b6cab77631Brian Paul         = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
674048b13df65f222b10564091df3dfa2b6cab77631Brian Paul   }
675ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul}
676847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul
677847160466cb7d1af55f294578c328b01fb3fd3d3Brian Paul
678c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian/**
679c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * Update a gl_framebuffer's derived state.
680c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *
681c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * Specifically, update these framebuffer fields:
682c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *    _ColorDrawBuffers
683c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *    _NumColorDrawBuffers
684c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *    _ColorReadBuffer
685c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *
686c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * If the framebuffer is user-created, make sure it's complete.
687c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian *
688c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * The following functions (at least) can effect framebuffer state:
689c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
690c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian * glRenderbufferStorageEXT.
691c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian */
692f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheideggerstatic void
693f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergupdate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
694f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger{
69536ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul   if (_mesa_is_winsys_fbo(fb)) {
69632d86eb28aedd01a03ceab746214a8db2a4cbbabBrian      /* This is a window-system framebuffer */
69732d86eb28aedd01a03ceab746214a8db2a4cbbabBrian      /* Need to update the FB's GL_DRAW_BUFFER state to match the
69832d86eb28aedd01a03ceab746214a8db2a4cbbabBrian       * context state (GL_READ_BUFFER too).
69932d86eb28aedd01a03ceab746214a8db2a4cbbabBrian       */
70032d86eb28aedd01a03ceab746214a8db2a4cbbabBrian      if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
70132d86eb28aedd01a03ceab746214a8db2a4cbbabBrian         _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
70232d86eb28aedd01a03ceab746214a8db2a4cbbabBrian                           ctx->Color.DrawBuffer, NULL);
70332d86eb28aedd01a03ceab746214a8db2a4cbbabBrian      }
70432d86eb28aedd01a03ceab746214a8db2a4cbbabBrian   }
70532d86eb28aedd01a03ceab746214a8db2a4cbbabBrian   else {
70632d86eb28aedd01a03ceab746214a8db2a4cbbabBrian      /* This is a user-created framebuffer.
70732d86eb28aedd01a03ceab746214a8db2a4cbbabBrian       * Completeness only matters for user-created framebuffers.
70832d86eb28aedd01a03ceab746214a8db2a4cbbabBrian       */
7095f4d0cc6bcfb34a68a72ebc4091f3ab0cf43f90cBrian Paul      if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
7107296636ad03f58c7b7f673109515c1659a36a899Brian Paul         _mesa_test_framebuffer_completeness(ctx, fb);
7117296636ad03f58c7b7f673109515c1659a36a899Brian Paul      }
712f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger   }
713f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger
714c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian   /* Strictly speaking, we don't need to update the draw-state
715c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian    * if this FB is bound as ctx->ReadBuffer (and conversely, the
716c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian    * read-state if this FB is bound as ctx->DrawBuffer), but no
717c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian    * harm.
718c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian    */
719f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger   update_color_draw_buffers(ctx, fb);
720f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger   update_color_read_buffer(ctx, fb);
721f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger
722f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger   compute_depth_max(fb);
723f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger}
724f9ac01eac511aa9ea0b8b48774022a08d0fc2f3bRoland Scheidegger
725c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian
726ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul/**
727ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * Update state related to the current draw/read framebuffers.
728ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul */
729ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paulvoid
730f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_update_framebuffer(struct gl_context *ctx)
731ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul{
7327da9da190f44f504db13570c0cec05dffa240caeVinson Lee   struct gl_framebuffer *drawFb;
7337da9da190f44f504db13570c0cec05dffa240caeVinson Lee   struct gl_framebuffer *readFb;
7347da9da190f44f504db13570c0cec05dffa240caeVinson Lee
7357da9da190f44f504db13570c0cec05dffa240caeVinson Lee   assert(ctx);
7367da9da190f44f504db13570c0cec05dffa240caeVinson Lee   drawFb = ctx->DrawBuffer;
7377da9da190f44f504db13570c0cec05dffa240caeVinson Lee   readFb = ctx->ReadBuffer;
738ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
739c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian   update_framebuffer(ctx, drawFb);
740c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian   if (readFb != drawFb)
741c033ccc36d08c669dcdfbfc1cf89e472e8211c5fBrian      update_framebuffer(ctx, readFb);
742e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
7437275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
7447275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
7457275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul/**
746e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * Check if the renderbuffer for a read/draw operation exists.
7477275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
7487275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
749e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * \param reading  if TRUE, we're going to read from the buffer,
750e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                   if FALSE, we're going to write to the buffer.
7517275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul * \return GL_TRUE if buffer exists, GL_FALSE otherwise
7527275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul */
753e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paulstatic GLboolean
754e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paulrenderbuffer_exists(struct gl_context *ctx,
755e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                    struct gl_framebuffer *fb,
756e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                    GLenum format,
757e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                    GLboolean reading)
7587275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul{
759e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul   const struct gl_renderbuffer_attachment *att = fb->Attachment;
76094504be63a9a70263a0eb2872295867c989be2b1Brian Paul
761483a7916d1c93d1edf125dc671dcfbff42a9fc5eBrian Paul   /* If we don't know the framebuffer status, update it now */
762e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul   if (fb->_Status == 0) {
763e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul      _mesa_test_framebuffer_completeness(ctx, fb);
764483a7916d1c93d1edf125dc671dcfbff42a9fc5eBrian Paul   }
7657275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
766e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
7677275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      return GL_FALSE;
7687275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   }
7697275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
7707275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   switch (format) {
7717275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_COLOR:
772590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_RED:
773590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_GREEN:
774590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_BLUE:
7757275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_ALPHA:
7767275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_LUMINANCE:
7777275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_LUMINANCE_ALPHA:
7787275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_INTENSITY:
779d4c1bcce44add7642e857237dfe69bf1fc4511d9Brian Paul   case GL_RG:
7807275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_RGB:
781590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_BGR:
7827275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_RGBA:
783590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_BGRA:
784590cd26006959ba390d5ebe337cb363827087941Brian Paul   case GL_ABGR_EXT:
7857a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_RED_INTEGER_EXT:
786f767e96131ba69cf61aa9f848d5f24e4396ac920Dave Airlie   case GL_RG_INTEGER:
7877a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_GREEN_INTEGER_EXT:
7887a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_BLUE_INTEGER_EXT:
7897a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_ALPHA_INTEGER_EXT:
7907a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_RGB_INTEGER_EXT:
7917a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_RGBA_INTEGER_EXT:
7927a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_BGR_INTEGER_EXT:
7937a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_BGRA_INTEGER_EXT:
7947a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_LUMINANCE_INTEGER_EXT:
7957a60512f849f052a7abc2ad0aa42a0c152e5c5e6Brian Paul   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
796e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul      if (reading) {
797e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         /* about to read from a color buffer */
798e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer;
799e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         if (!readBuf) {
800e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul            return GL_FALSE;
801e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         }
802e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         ASSERT(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 ||
803e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 ||
804e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 ||
805e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 ||
806e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0);
807e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul      }
808e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul      else {
809e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         /* about to draw to zero or more color buffers (none is OK) */
810e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul         return GL_TRUE;
8117275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      }
8127275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      break;
8137275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_DEPTH:
8147275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_DEPTH_COMPONENT:
815504d0add1257f63d72d320f99f182412358dc40fBrian Paul      if (att[BUFFER_DEPTH].Type == GL_NONE) {
8167275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul         return GL_FALSE;
8177275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      }
8187275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      break;
8197275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_STENCIL:
8207275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_STENCIL_INDEX:
821504d0add1257f63d72d320f99f182412358dc40fBrian Paul      if (att[BUFFER_STENCIL].Type == GL_NONE) {
8227275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul         return GL_FALSE;
8237275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      }
8247275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      break;
8257275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   case GL_DEPTH_STENCIL_EXT:
826504d0add1257f63d72d320f99f182412358dc40fBrian Paul      if (att[BUFFER_DEPTH].Type == GL_NONE ||
827504d0add1257f63d72d320f99f182412358dc40fBrian Paul          att[BUFFER_STENCIL].Type == GL_NONE) {
8287275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul         return GL_FALSE;
8297275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      }
8307275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      break;
8317275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   default:
8327275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      _mesa_problem(ctx,
833e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul                    "Unexpected format 0x%x in renderbuffer_exists",
834590cd26006959ba390d5ebe337cb363827087941Brian Paul                    format);
8357275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul      return GL_FALSE;
8367275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   }
8377275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
8387275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   /* OK */
8397275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul   return GL_TRUE;
8407275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul}
8417275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
8427275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul
8437275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul/**
844e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
845e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * glCopyTex[Sub]Image, etc) exists.
846e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
847e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
848e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul * \return GL_TRUE if buffer exists, GL_FALSE otherwise
849e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul */
850e5fef34c2132e29b6cecfda525dfa956c4477d75Brian PaulGLboolean
851e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul_mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
852e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul{
853e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul   return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE);
854e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul}
855e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul
856e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul
857e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul/**
8587275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul * As above, but for drawing operations.
8597275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul */
8607275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian PaulGLboolean
861f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
8627275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul{
863e5fef34c2132e29b6cecfda525dfa956c4477d75Brian Paul   return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE);
8647275d4d097f97a2154dfe8fa573dc193cb5b4bf1Brian Paul}
865cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt
866b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul
867b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul/**
868b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES query.
869b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul */
870cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric AnholtGLenum
871f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_get_color_read_format(struct gl_context *ctx)
872cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt{
873cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
874cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   case MESA_FORMAT_ARGB8888:
875cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_BGRA;
876cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   case MESA_FORMAT_RGB565:
877cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_BGR;
878cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   default:
879cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_RGBA;
880cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   }
881cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt}
882cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt
883b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul
884b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul/**
885b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES query.
886b318039e9a790d9d90bd524c79af2d9a444d0093Brian Paul */
887cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric AnholtGLenum
888f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_get_color_read_type(struct gl_context *ctx)
889cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt{
890cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
891cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   case MESA_FORMAT_ARGB8888:
892cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_UNSIGNED_BYTE;
893cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   case MESA_FORMAT_RGB565:
894cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_UNSIGNED_SHORT_5_6_5_REV;
895cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   default:
896cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt      return GL_UNSIGNED_BYTE;
897cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt   }
898cd6b8dd9e82fedc55d033131fbc0f8ee950567c8Eric Anholt}
899421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul
900421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul
901421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul/**
902421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul * Print framebuffer info to stderr, for debugging.
903421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul */
904421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paulvoid
905421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul_mesa_print_framebuffer(const struct gl_framebuffer *fb)
906421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul{
907421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   GLuint i;
908421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul
909421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
910421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
911421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul           _mesa_lookup_enum_by_nr(fb->_Status));
912421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   fprintf(stderr, "  Attachments:\n");
913421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul
914421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   for (i = 0; i < BUFFER_COUNT; i++) {
915421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
916421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      if (att->Type == GL_TEXTURE) {
917db0f9e701d59dcfcd3b50f4d245897692f27fec9Brian Paul         const struct gl_texture_image *texImage =
918db0f9e701d59dcfcd3b50f4d245897692f27fec9Brian Paul            _mesa_get_attachment_teximage_const(att);
919421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul         fprintf(stderr,
920421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
921421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
922421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 att->Zoffset, att->Complete);
923421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul         fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
924421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 texImage->Width, texImage->Height, texImage->Depth,
925421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 _mesa_get_format_name(texImage->TexFormat));
926421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      }
927421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      else if (att->Type == GL_RENDERBUFFER) {
928421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul         fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
929421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 i, att->Renderbuffer->Name, att->Complete);
930421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul         fprintf(stderr, "       Size: %u x %u  Format %s\n",
931421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 att->Renderbuffer->Width, att->Renderbuffer->Height,
932421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul                 _mesa_get_format_name(att->Renderbuffer->Format));
933421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      }
934421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      else {
935421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul         fprintf(stderr, "  %2d: none\n", i);
936421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul      }
937421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul   }
938421e9aa71c9dc1c1462e55338dc5ceafb773e201Brian Paul}
939