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