1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.2
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Functions for allocating/managing framebuffers and renderbuffers.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Also, routines for reading/writing renderbuffer data as ubytes,
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ushorts, uints, etc.
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glheader.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "imports.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "buffers.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "enums.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "formats.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "macros.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "fbobject.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "framebuffer.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "renderbuffer.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "texobj.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute/set the _DepthMax field for the given framebuffer.
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This value depends on the Z buffer resolution.
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompute_depth_max(struct gl_framebuffer *fb)
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->Visual.depthBits == 0) {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Special case.  Even if we don't have a depth buffer we need
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * good values for DepthMax for Z vertex transformation purposes
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * and for per-fragment fog computation.
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_DepthMax = (1 << 16) - 1;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (fb->Visual.depthBits < 32) {
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Special case since shift values greater than or equal to the
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * number of bits in the left hand expression's type are undefined.
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_DepthMax = 0xffffffff;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Minimum resolvable depth value, for polygon offset */
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create and initialize a gl_framebuffer object.
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is intended for creating _window_system_ framebuffers, not generic
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * framebuffer objects ala GL_EXT_framebuffer_object.
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_new_framebuffer
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_framebuffer *
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_create_framebuffer(const struct gl_config *visual)
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(visual);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb) {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_initialize_window_framebuffer(fb, visual);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fb;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate a new gl_framebuffer object.
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is the default function for ctx->Driver.NewFramebuffer().
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is for allocating user-created framebuffers, not window-system
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * framebuffers!
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_create_framebuffer
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_framebuffer *
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *fb;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(name != 0);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb = CALLOC_STRUCT(gl_framebuffer);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb) {
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_initialize_user_framebuffer(fb, name);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fb;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize a gl_framebuffer object.  Typically used to initialize
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * window system-created framebuffers, not user-created framebuffers.
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_initialize_user_framebuffer
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     const struct gl_config *visual)
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fb);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(visual);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(fb, 0, sizeof(struct gl_framebuffer));
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _glthread_INIT_MUTEX(fb->Mutex);
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->RefCount = 1;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* save the visual */
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Visual = *visual;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Init read/draw renderbuffer state */
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visual->doubleBufferMode) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_NumColorDrawBuffers = 1;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->ColorDrawBuffer[0] = GL_BACK;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->ColorReadBuffer = GL_BACK;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_NumColorDrawBuffers = 1;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->ColorDrawBuffer[0] = GL_FRONT;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->ColorReadBuffer = GL_FRONT;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Delete = _mesa_destroy_framebuffer;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_depth_max(fb);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize a user-created gl_framebuffer object.
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_initialize_window_framebuffer
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fb);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(name);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(fb, 0, sizeof(struct gl_framebuffer));
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Name = name;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->RefCount = 1;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_NumColorDrawBuffers = 1;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_ColorReadBufferIndex = BUFFER_COLOR0;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Delete = _mesa_destroy_framebuffer;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _glthread_INIT_MUTEX(fb->Mutex);
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Deallocate buffer and everything attached to it.
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Typically called via the gl_framebuffer->Delete() method.
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb) {
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_free_framebuffer_data(fb);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(fb);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free all the data hanging off the given gl_framebuffer, but don't free
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the gl_framebuffer object itself.
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fb);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(fb->RefCount == 0);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _glthread_DESTROY_MUTEX(fb->Mutex);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att->Renderbuffer) {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att->Texture) {
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_reference_texobj(&att->Texture, NULL);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(!att->Renderbuffer);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(!att->Texture);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      att->Type = GL_NONE;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set *ptr to point to fb, with refcounting and locking.
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is normally only called from the _mesa_reference_framebuffer() macro
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * when there's a real pointer change.
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             struct gl_framebuffer *fb)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (*ptr) {
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* unreference old renderbuffer */
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLboolean deleteFlag = GL_FALSE;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_framebuffer *oldFb = *ptr;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _glthread_LOCK_MUTEX(oldFb->Mutex);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(oldFb->RefCount > 0);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      oldFb->RefCount--;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      deleteFlag = (oldFb->RefCount == 0);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _glthread_UNLOCK_MUTEX(oldFb->Mutex);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (deleteFlag)
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         oldFb->Delete(oldFb);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *ptr = NULL;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!*ptr);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb) {
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _glthread_LOCK_MUTEX(fb->Mutex);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->RefCount++;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _glthread_UNLOCK_MUTEX(fb->Mutex);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *ptr = fb;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Resize the given framebuffer's renderbuffers to the new width and height.
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This should only be used for window-system framebuffers, not
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This will typically be called via ctx->Driver.ResizeBuffers() or directly
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from a device driver.
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \note it's possible for ctx to be null since a window can be resized
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without a currently bound rendering context.
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         GLuint width, GLuint height)
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX I think we could check if the size is not changing
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and return early.
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Can only resize win-sys framebuffer objects */
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(_mesa_is_winsys_fbo(fb));
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct gl_renderbuffer *rb = att->Renderbuffer;
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* only resize if size is changing */
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (rb->Width != width || rb->Height != height) {
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               ASSERT(rb->Width == width);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               ASSERT(rb->Height == height);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* no return */
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Width = width;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Height = height;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx) {
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* update scissor / window bounds */
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_update_draw_buffer_bounds(ctx);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Signal new buffer state so that swrast will update its clipping
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * info (the CLIP_BIT flag).
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->NewState |= _NEW_BUFFERS;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX THIS IS OBSOLETE - drivers should take care of detecting window
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * size changes and act accordingly, likely calling _mesa_resize_framebuffer().
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_MESA_resize_buffers extension.
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When this function is called, we'll ask the window system how large
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the current window is.  If it's a new size, we'll call the driver's
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ResizeBuffers function.  The driver will then resize its color buffers
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as needed, and maybe call the swrast's routine for reallocating
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swrast-managed depth/stencil/accum/etc buffers.
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \note This function should only be called through the GL API, not
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from device drivers (as was done in the past).
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_resizebuffers( struct gl_context *ctx )
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (MESA_VERBOSE & VERBOSE_API)
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_debug(ctx, "glResizeBuffersMESA\n");
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx->Driver.GetBufferSize) {
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->WinSysDrawBuffer) {
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint newWidth, newHeight;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_framebuffer *buffer = ctx->WinSysDrawBuffer;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(_mesa_is_winsys_fbo(buffer));
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* ask device driver for size of output buffer */
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* see if size of device driver's color buffer (window) has changed */
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (buffer->Width != newWidth || buffer->Height != newHeight) {
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (ctx->Driver.ResizeBuffers)
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->WinSysReadBuffer
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint newWidth, newHeight;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_framebuffer *buffer = ctx->WinSysReadBuffer;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(_mesa_is_winsys_fbo(buffer));
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* ask device driver for size of read buffer */
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* see if size of device driver's color buffer (window) has changed */
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (buffer->Width != newWidth || buffer->Height != newHeight) {
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (ctx->Driver.ResizeBuffers)
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX THIS IS OBSOLETE
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GLAPIENTRY
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_ResizeBuffersMESA( void )
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GET_CURRENT_CONTEXT(ctx);
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Extensions.MESA_resize_buffers)
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_resizebuffers( ctx );
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examine all the framebuffer's renderbuffers to update the Width/Height
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fields of the framebuffer.  If we have renderbuffers with different
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sizes, set the framebuffer's width and height to the min size.
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: this is only intended for user-created framebuffers, not
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * window-system framebuffes.
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minWidth = ~0, minHeight = ~0;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* user-created framebuffers only */
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(_mesa_is_user_fbo(fb));
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_renderbuffer *rb = att->Renderbuffer;
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rb) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         minWidth = MIN2(minWidth, rb->Width);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         minHeight = MIN2(minHeight, rb->Height);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minWidth != ~0) {
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Width = minWidth;
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Height = minHeight;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Width = 0;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Height = 0;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * These values are computed from the buffer's width and height and
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the scissor box, if it's enabled.
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx  the GL context.
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_update_draw_buffer_bounds(struct gl_context *ctx)
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *buffer = ctx->DrawBuffer;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!buffer)
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_user_fbo(buffer)) {
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* user-created framebuffer size depends on the renderbuffers */
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      update_framebuffer_size(ctx, buffer);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->_Xmin = 0;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->_Ymin = 0;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->_Xmax = buffer->Width;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->_Ymax = buffer->Height;
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Scissor.Enabled) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->Scissor.X > buffer->_Xmin) {
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 buffer->_Xmin = ctx->Scissor.X;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->Scissor.Y > buffer->_Ymin) {
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 buffer->_Ymin = ctx->Scissor.Y;
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* finally, check for empty region */
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (buffer->_Xmin > buffer->_Xmax) {
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         buffer->_Xmin = buffer->_Xmax;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (buffer->_Ymin > buffer->_Ymax) {
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         buffer->_Ymin = buffer->_Ymax;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(buffer->_Xmin <= buffer->_Xmax);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(buffer->_Ymin <= buffer->_Ymax);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glGet queries of the framebuffer red/green/blue size, stencil size,
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * change depending on the renderbuffer bindings.  This function updates
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the given framebuffer's Visual from the current renderbuffer bindings.
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This may apply to user-created framebuffers or window system framebuffers.
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The former one is used to convert floating point depth values into
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer Z values.
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_update_framebuffer_visual(struct gl_context *ctx,
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				struct gl_framebuffer *fb)
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&fb->Visual, 0, sizeof(fb->Visual));
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Visual.rgbMode = GL_TRUE; /* assume this */
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 /* this _might_ be needed */
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* leave visual fields zero'd */
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* find first RGB renderbuffer */
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fb->Attachment[i].Renderbuffer) {
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const gl_format fmt = rb->Format;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Grab samples and sampleBuffers from any attachment point (assuming
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the framebuffer is complete, we'll get the same answer from all
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * attachments).
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->Visual.samples = rb->NumSamples;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (_mesa_is_legal_color_format(ctx, baseFormat)) {
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.rgbBits = fb->Visual.redBits
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               + fb->Visual.greenBits + fb->Visual.blueBits;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (_mesa_get_format_color_encoding(fmt) == GL_SRGB)
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                fb->Visual.sRGBCapable = ctx->Extensions.EXT_framebuffer_sRGB;
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->Visual.floatMode = GL_FALSE;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fb->Attachment[i].Renderbuffer) {
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const gl_format fmt = rb->Format;
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fb->Visual.floatMode = GL_TRUE;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_renderbuffer *rb =
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->Attachment[BUFFER_DEPTH].Renderbuffer;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const gl_format fmt = rb->Format;
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.haveDepthBuffer = GL_TRUE;
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_renderbuffer *rb =
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->Attachment[BUFFER_STENCIL].Renderbuffer;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const gl_format fmt = rb->Format;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.haveStencilBuffer = GL_TRUE;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_renderbuffer *rb =
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->Attachment[BUFFER_ACCUM].Renderbuffer;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const gl_format fmt = rb->Format;
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.haveAccumBuffer = GL_TRUE;
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_depth_max(fb);
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Example DrawBuffers scenarios:
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "gl_FragColor" or program writes to the "result.color" register:
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   fragment color output   renderbuffer
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   ---------------------   ---------------
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   color[0]                Front, Back
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_FragData[i] or program writes to result.color[i] registers:
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   fragment color output   renderbuffer
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   ---------------------   ---------------
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   color[0]                Front
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   color[1]                Aux0
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   color[3]                Aux1
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_FragColor, or fixed function:
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   fragment color output   renderbuffer
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   ---------------------   ---------------
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   color[0]                Front, Aux0, Aux1
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In either case, the list of renderbuffers is stored in the
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * framebuffer->_ColorDrawBuffers[] array and
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The renderer (like swrast) has to look at the current fragment shader
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * how to map color outputs to renderbuffers.
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that these two calls are equivalent (for fixed function fragment
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shading anyway):
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the (derived) list of color drawing renderbuffer pointers.
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writing colors.
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint output;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fb->_ColorDrawBuffers[0] = NULL;
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint buf = fb->_ColorDrawBufferIndexes[output];
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (buf >= 0) {
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fb->_ColorDrawBuffers[output] = NULL;
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the (derived) color read renderbuffer pointer.
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->_ColorReadBufferIndex == -1 ||
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       fb->DeletePending ||
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       fb->Width == 0 ||
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       fb->Height == 0) {
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorReadBuffer = NULL; /* legal! */
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(fb->_ColorReadBufferIndex >= 0);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fb->_ColorReadBuffer
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update a gl_framebuffer's derived state.
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Specifically, update these framebuffer fields:
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    _ColorDrawBuffers
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    _NumColorDrawBuffers
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    _ColorReadBuffer
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the framebuffer is user-created, make sure it's complete.
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The following functions (at least) can effect framebuffer state:
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glRenderbufferStorageEXT.
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_winsys_fbo(fb)) {
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This is a window-system framebuffer */
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need to update the FB's GL_DRAW_BUFFER state to match the
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * context state (GL_READ_BUFFER too).
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           ctx->Color.DrawBuffer, NULL);
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This is a user-created framebuffer.
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Completeness only matters for user-created framebuffers.
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_test_framebuffer_completeness(ctx, fb);
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Strictly speaking, we don't need to update the draw-state
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * if this FB is bound as ctx->ReadBuffer (and conversely, the
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * read-state if this FB is bound as ctx->DrawBuffer), but no
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * harm.
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   update_color_draw_buffers(ctx, fb);
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   update_color_read_buffer(ctx, fb);
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_depth_max(fb);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update state related to the current draw/read framebuffers.
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_update_framebuffer(struct gl_context *ctx)
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *drawFb;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *readFb;
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(ctx);
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drawFb = ctx->DrawBuffer;
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   readFb = ctx->ReadBuffer;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   update_framebuffer(ctx, drawFb);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (readFb != drawFb)
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      update_framebuffer(ctx, readFb);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check if the renderbuffer for a read/draw operation exists.
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param reading  if TRUE, we're going to read from the buffer,
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   if FALSE, we're going to write to the buffer.
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if buffer exists, GL_FALSE otherwise
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrenderbuffer_exists(struct gl_context *ctx,
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    struct gl_framebuffer *fb,
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    GLenum format,
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    GLboolean reading)
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_renderbuffer_attachment *att = fb->Attachment;
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If we don't know the framebuffer status, update it now */
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->_Status == 0) {
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_test_framebuffer_completeness(ctx, fb);
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (format) {
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_COLOR:
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RED:
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GREEN:
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BLUE:
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALPHA:
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE:
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE_ALPHA:
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INTENSITY:
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RG:
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB:
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BGR:
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA:
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BGRA:
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ABGR_EXT:
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RED_INTEGER_EXT:
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RG_INTEGER:
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GREEN_INTEGER_EXT:
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BLUE_INTEGER_EXT:
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALPHA_INTEGER_EXT:
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB_INTEGER_EXT:
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGBA_INTEGER_EXT:
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BGR_INTEGER_EXT:
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BGRA_INTEGER_EXT:
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE_INTEGER_EXT:
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reading) {
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* about to read from a color buffer */
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!readBuf) {
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return GL_FALSE;
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 ||
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 ||
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 ||
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 ||
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0);
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* about to draw to zero or more color buffers (none is OK) */
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_TRUE;
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH:
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_COMPONENT:
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att[BUFFER_DEPTH].Type == GL_NONE) {
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_FALSE;
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL:
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_STENCIL_INDEX:
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att[BUFFER_STENCIL].Type == GL_NONE) {
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_FALSE;
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_DEPTH_STENCIL_EXT:
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att[BUFFER_DEPTH].Type == GL_NONE ||
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          att[BUFFER_STENCIL].Type == GL_NONE) {
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_FALSE;
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(ctx,
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    "Unexpected format 0x%x in renderbuffer_exists",
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    format);
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* OK */
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glCopyTex[Sub]Image, etc) exists.
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if buffer exists, GL_FALSE otherwise
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE);
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but for drawing operations.
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE);
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES query.
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLenum
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_color_read_format(struct gl_context *ctx)
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case MESA_FORMAT_ARGB8888:
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_BGRA;
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case MESA_FORMAT_RGB565:
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_BGR;
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_RGBA;
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES query.
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLenum
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_color_read_type(struct gl_context *ctx)
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case MESA_FORMAT_ARGB8888:
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_UNSIGNED_BYTE;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case MESA_FORMAT_RGB565:
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_UNSIGNED_SHORT_5_6_5_REV;
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_UNSIGNED_BYTE;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Print framebuffer info to stderr, for debugging.
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_print_framebuffer(const struct gl_framebuffer *fb)
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           _mesa_lookup_enum_by_nr(fb->_Status));
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fprintf(stderr, "  Attachments:\n");
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < BUFFER_COUNT; i++) {
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (att->Type == GL_TEXTURE) {
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct gl_texture_image *texImage =
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _mesa_get_attachment_teximage_const(att);
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr,
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 att->Zoffset, att->Complete);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 texImage->Width, texImage->Height, texImage->Depth,
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 _mesa_get_format_name(texImage->TexFormat));
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (att->Type == GL_RENDERBUFFER) {
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 i, att->Renderbuffer->Name, att->Complete);
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "       Size: %u x %u  Format %s\n",
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 att->Renderbuffer->Width, att->Renderbuffer->Height,
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 _mesa_get_format_name(att->Renderbuffer->Format));
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "  %2d: none\n", i);
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
939