blob: 228e77543b127f6ceea2dca95f645251963bc279 [file] [log] [blame]
Keith Whitwell6dc85572003-07-17 13:43:59 +00001/**
2 * \file context.c
3 * Mesa context/visual/framebuffer management functions.
4 * \author Brian Paul
5 */
6
jtgafb833d1999-08-19 00:55:39 +00007/*
8 * Mesa 3-D graphics library
Brian145d7622007-08-16 10:05:00 +01009 * Version: 7.1
jtgafb833d1999-08-19 00:55:39 +000010 *
Brian145d7622007-08-16 10:05:00 +010011 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
jtgafb833d1999-08-19 00:55:39 +000012 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included
21 * in all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
27 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
Keith Whitwell6dc85572003-07-17 13:43:59 +000032/**
Brian Paul253204f2004-09-10 00:45:12 +000033 * \mainpage Mesa Main Module
Keith Whitwell6dc85572003-07-17 13:43:59 +000034 *
Brian Paul253204f2004-09-10 00:45:12 +000035 * \section MainIntroduction Introduction
Keith Whitwell6dc85572003-07-17 13:43:59 +000036 *
Brian Paul253204f2004-09-10 00:45:12 +000037 * The Mesa Main module consists of all the files in the main/ directory.
38 * Among the features of this module are:
39 * <UL>
40 * <LI> Structures to represent most GL state </LI>
41 * <LI> State set/get functions </LI>
42 * <LI> Display lists </LI>
43 * <LI> Texture unit, object and image handling </LI>
44 * <LI> Matrix and attribute stacks </LI>
45 * </UL>
Keith Whitwell6dc85572003-07-17 13:43:59 +000046 *
Brian Paul253204f2004-09-10 00:45:12 +000047 * Other modules are responsible for API dispatch, vertex transformation,
48 * point/line/triangle setup, rasterization, vertex array caching,
49 * vertex/fragment programs/shaders, etc.
Keith Whitwell6dc85572003-07-17 13:43:59 +000050 *
51 *
52 * \section AboutDoxygen About Doxygen
53 *
54 * If you're viewing this information as Doxygen-generated HTML you'll
55 * see the documentation index at the top of this page.
56 *
57 * The first line lists the Mesa source code modules.
58 * The second line lists the indexes available for viewing the documentation
59 * for each module.
60 *
61 * Selecting the <b>Main page</b> link will display a summary of the module
62 * (this page).
63 *
Jose Fonseca1a5709d2003-09-17 17:14:11 +000064 * Selecting <b>Data Structures</b> will list all C structures.
Keith Whitwell6dc85572003-07-17 13:43:59 +000065 *
66 * Selecting the <b>File List</b> link will list all the source files in
67 * the module.
68 * Selecting a filename will show a list of all functions defined in that file.
69 *
Jose Fonseca1a5709d2003-09-17 17:14:11 +000070 * Selecting the <b>Data Fields</b> link will display a list of all
Keith Whitwell6dc85572003-07-17 13:43:59 +000071 * documented structure members.
72 *
Jose Fonseca1a5709d2003-09-17 17:14:11 +000073 * Selecting the <b>Globals</b> link will display a list
Keith Whitwell6dc85572003-07-17 13:43:59 +000074 * of all functions, structures, global variables and macros in the module.
75 *
76 */
77
78
Brian Paulfbd8f211999-11-11 01:22:25 +000079#include "glheader.h"
Brian Paul3c634522002-10-24 23:57:19 +000080#include "imports.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070081#if FEATURE_accum
Keith Whitwell6dc85572003-07-17 13:43:59 +000082#include "accum.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070083#endif
Brian Paulc9e56712008-06-09 14:49:04 -060084#include "api_exec.h"
Brian Paulc04bb512006-07-11 21:56:43 +000085#include "arrayobj.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070086#if FEATURE_attrib_stack
Keith Whitwell6dc85572003-07-17 13:43:59 +000087#include "attrib.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070088#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +000089#include "blend.h"
Brian Paulb1394fa2000-09-26 20:53:53 +000090#include "buffers.h"
Brian Paul148a2842003-09-17 03:40:11 +000091#include "bufferobj.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070092#if FEATURE_colortable
Brian Paul4bdcfe52000-04-17 17:57:04 +000093#include "colortab.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070094#endif
jtgafb833d1999-08-19 00:55:39 +000095#include "context.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +000096#include "debug.h"
97#include "depth.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -070098#if FEATURE_dlist
jtgafb833d1999-08-19 00:55:39 +000099#include "dlist.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700100#endif
101#if FEATURE_evaluators
jtgafb833d1999-08-19 00:55:39 +0000102#include "eval.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700103#endif
jtgafb833d1999-08-19 00:55:39 +0000104#include "enums.h"
Brian Paul585a68c1999-09-11 11:31:34 +0000105#include "extensions.h"
Brian Paule4b23562005-05-04 20:11:35 +0000106#include "fbobject.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700107#if FEATURE_feedback
Keith Whitwell6dc85572003-07-17 13:43:59 +0000108#include "feedback.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700109#endif
jtgafb833d1999-08-19 00:55:39 +0000110#include "fog.h"
Briane6a93812007-02-26 11:37:37 -0700111#include "framebuffer.h"
Brian Paulb7a43041999-11-30 20:34:51 +0000112#include "get.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700113#if FEATURE_histogram
Keith Whitwell6dc85572003-07-17 13:43:59 +0000114#include "histogram.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700115#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +0000116#include "hint.h"
jtgafb833d1999-08-19 00:55:39 +0000117#include "hash.h"
118#include "light.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +0000119#include "lines.h"
jtgafb833d1999-08-19 00:55:39 +0000120#include "macros.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +0000121#include "matrix.h"
Brian Paulc132e2b2008-06-09 15:09:21 -0600122#include "multisample.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700123#if FEATURE_pixel_transfer
Keith Whitwell6dc85572003-07-17 13:43:59 +0000124#include "pixel.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700125#endif
Brian Paul533c1db2008-06-09 14:25:23 -0600126#include "pixelstore.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +0000127#include "points.h"
128#include "polygon.h"
Brian74afcab2007-04-21 12:42:54 -0600129#include "queryobj.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700130#if FEATURE_drawpix
Keith Whitwell6dc85572003-07-17 13:43:59 +0000131#include "rastpos.h"
Keith Whitwell34a61c62008-09-21 19:29:15 -0700132#endif
Brian Paul55e341c2008-06-09 14:55:24 -0600133#include "scissor.h"
jtgafb833d1999-08-19 00:55:39 +0000134#include "simple_list.h"
Brian Paulfa9df402000-02-02 19:16:46 +0000135#include "state.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +0000136#include "stencil.h"
Brian Paul8f04c122004-04-27 13:39:20 +0000137#include "texcompress.h"
jtgafb833d1999-08-19 00:55:39 +0000138#include "teximage.h"
139#include "texobj.h"
Brian Paul85d81602002-06-17 23:36:31 +0000140#include "texstate.h"
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000141#include "mtypes.h"
jtgafb833d1999-08-19 00:55:39 +0000142#include "varray.h"
Brian Paul363344f2005-09-13 14:48:28 +0000143#include "version.h"
Gareth Hughesd4eb6652001-03-12 01:32:20 +0000144#include "vtxfmt.h"
Brianc223c6b2007-07-04 13:15:20 -0600145#include "glapi/glthread.h"
Brianc223c6b2007-07-04 13:15:20 -0600146#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
147#include "shader/program.h"
148#endif
149#include "shader/shader_api.h"
150#include "shader/atifragshader.h"
Keith Whitwell6dc85572003-07-17 13:43:59 +0000151#if _HAVE_FULL_GL
Keith Whitwell23caf202000-11-16 21:05:34 +0000152#include "math/m_translate.h"
Keith Whitwell23caf202000-11-16 21:05:34 +0000153#include "math/m_matrix.h"
154#include "math/m_xform.h"
Keith Whitwellf4b02d12001-01-05 05:31:42 +0000155#include "math/mathmod.h"
Brian Paulddc82ee2005-02-05 19:56:45 +0000156#endif
jtgafb833d1999-08-19 00:55:39 +0000157
davem69775355a2001-06-05 23:54:00 +0000158#ifdef USE_SPARC_ASM
Ian Romanicke16f6e32004-06-26 00:02:51 +0000159#include "sparc/sparc.h"
davem69775355a2001-06-05 23:54:00 +0000160#endif
jtgafb833d1999-08-19 00:55:39 +0000161
Keith Whitwell23caf202000-11-16 21:05:34 +0000162#ifndef MESA_VERBOSE
Keith Whitwell306d3fc2002-04-09 16:56:50 +0000163int MESA_VERBOSE = 0;
Keith Whitwell23caf202000-11-16 21:05:34 +0000164#endif
165
166#ifndef MESA_DEBUG_FLAGS
Keith Whitwell306d3fc2002-04-09 16:56:50 +0000167int MESA_DEBUG_FLAGS = 0;
Keith Whitwell23caf202000-11-16 21:05:34 +0000168#endif
Brian Paulb1394fa2000-09-26 20:53:53 +0000169
Brian Paul86b84272001-12-14 02:50:01 +0000170
Brian Paul27558a12003-03-01 01:50:20 +0000171/* ubyte -> float conversion */
172GLfloat _mesa_ubyte_to_float_color_tab[256];
173
Brian Paul9a33a112002-06-13 04:28:29 +0000174
Brian Paul86b84272001-12-14 02:50:01 +0000175
Keith Whitwell6dc85572003-07-17 13:43:59 +0000176/**
177 * Swap buffers notification callback.
178 *
179 * \param gc GL context.
180 *
181 * Called by window system just before swapping buffers.
Brian Paul9a33a112002-06-13 04:28:29 +0000182 * We have to finish any pending rendering.
183 */
184void
185_mesa_notifySwapBuffers(__GLcontext *gc)
186{
187 FLUSH_VERTICES( gc, 0 );
188}
189
Brian Paulb1394fa2000-09-26 20:53:53 +0000190
jtgafb833d1999-08-19 00:55:39 +0000191/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +0000192/** \name GL Visual allocation/destruction */
Brian Paul4d053dd2000-01-14 04:45:47 +0000193/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +0000194/*@{*/
Brian Paul4d053dd2000-01-14 04:45:47 +0000195
Keith Whitwell6dc85572003-07-17 13:43:59 +0000196/**
Brian Paul894844a2004-03-21 17:05:03 +0000197 * Allocates a GLvisual structure and initializes it via
198 * _mesa_initialize_visual().
Keith Whitwell6dc85572003-07-17 13:43:59 +0000199 *
200 * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
201 * \param dbFlag double buffering
202 * \param stereoFlag stereo buffer
203 * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
204 * is acceptable but the actual depth type will be GLushort or GLuint as
205 * needed.
206 * \param stencilBits requested minimum bits per stencil buffer value
207 * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
208 * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
209 * \param redBits number of bits per color component in frame buffer for RGB(A)
210 * mode. We always use 8 in core Mesa though.
211 * \param greenBits same as above.
212 * \param blueBits same as above.
213 * \param alphaBits same as above.
214 * \param numSamples not really used.
215 *
216 * \return pointer to new GLvisual or NULL if requested parameters can't be
217 * met.
218 *
Brian Paul894844a2004-03-21 17:05:03 +0000219 * \note Need to add params for level and numAuxBuffers (at least)
Brian Paul4d053dd2000-01-14 04:45:47 +0000220 */
Brian Paulb371e0d2000-03-31 01:05:51 +0000221GLvisual *
222_mesa_create_visual( GLboolean rgbFlag,
Brian Paulb371e0d2000-03-31 01:05:51 +0000223 GLboolean dbFlag,
224 GLboolean stereoFlag,
225 GLint redBits,
226 GLint greenBits,
227 GLint blueBits,
228 GLint alphaBits,
229 GLint indexBits,
230 GLint depthBits,
231 GLint stencilBits,
232 GLint accumRedBits,
233 GLint accumGreenBits,
234 GLint accumBlueBits,
235 GLint accumAlphaBits,
236 GLint numSamples )
Brian Paul4d053dd2000-01-14 04:45:47 +0000237{
Brian Paulc7e164f2006-06-30 15:44:30 +0000238 GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual));
Brian Paul178a1c52000-04-22 01:05:00 +0000239 if (vis) {
Brian Paule70c6232000-05-04 13:53:55 +0000240 if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
Brian Paul178a1c52000-04-22 01:05:00 +0000241 redBits, greenBits, blueBits, alphaBits,
242 indexBits, depthBits, stencilBits,
243 accumRedBits, accumGreenBits,
244 accumBlueBits, accumAlphaBits,
Brian Paulb1394fa2000-09-26 20:53:53 +0000245 numSamples)) {
Brian Paulc7e164f2006-06-30 15:44:30 +0000246 _mesa_free(vis);
Brian Paul178a1c52000-04-22 01:05:00 +0000247 return NULL;
248 }
249 }
250 return vis;
251}
252
Keith Whitwell6dc85572003-07-17 13:43:59 +0000253/**
Brian Paul894844a2004-03-21 17:05:03 +0000254 * Makes some sanity checks and fills in the fields of the
Brian Paule4b23562005-05-04 20:11:35 +0000255 * GLvisual object with the given parameters. If the caller needs
256 * to set additional fields, he should just probably init the whole GLvisual
257 * object himself.
Keith Whitwell6dc85572003-07-17 13:43:59 +0000258 * \return GL_TRUE on success, or GL_FALSE on failure.
259 *
260 * \sa _mesa_create_visual() above for the parameter description.
Brian Paul178a1c52000-04-22 01:05:00 +0000261 */
262GLboolean
263_mesa_initialize_visual( GLvisual *vis,
264 GLboolean rgbFlag,
Brian Paul178a1c52000-04-22 01:05:00 +0000265 GLboolean dbFlag,
266 GLboolean stereoFlag,
267 GLint redBits,
268 GLint greenBits,
269 GLint blueBits,
270 GLint alphaBits,
271 GLint indexBits,
272 GLint depthBits,
273 GLint stencilBits,
274 GLint accumRedBits,
275 GLint accumGreenBits,
276 GLint accumBlueBits,
277 GLint accumAlphaBits,
278 GLint numSamples )
279{
280 assert(vis);
Brian Paul4d053dd2000-01-14 04:45:47 +0000281
Brian Pauled30dfa2000-03-03 17:47:39 +0000282 if (depthBits < 0 || depthBits > 32) {
Brian Paul178a1c52000-04-22 01:05:00 +0000283 return GL_FALSE;
Brian Paul4d053dd2000-01-14 04:45:47 +0000284 }
Brian Paule4b23562005-05-04 20:11:35 +0000285 if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
Brian Paul178a1c52000-04-22 01:05:00 +0000286 return GL_FALSE;
Brian Paul4d053dd2000-01-14 04:45:47 +0000287 }
Brian Paul978ef2b2005-09-21 03:35:08 +0000288 assert(accumRedBits >= 0);
289 assert(accumGreenBits >= 0);
290 assert(accumBlueBits >= 0);
291 assert(accumAlphaBits >= 0);
Brian Paul4d053dd2000-01-14 04:45:47 +0000292
Brian Paulb6bcae52001-01-23 23:39:36 +0000293 vis->rgbMode = rgbFlag;
294 vis->doubleBufferMode = dbFlag;
295 vis->stereoMode = stereoFlag;
Brian Paul153f1542002-10-29 15:04:35 +0000296
Brian Paulb6bcae52001-01-23 23:39:36 +0000297 vis->redBits = redBits;
298 vis->greenBits = greenBits;
299 vis->blueBits = blueBits;
300 vis->alphaBits = alphaBits;
Brian Paule4b23562005-05-04 20:11:35 +0000301 vis->rgbBits = redBits + greenBits + blueBits;
Brian Paul4d053dd2000-01-14 04:45:47 +0000302
Brian Paulb6bcae52001-01-23 23:39:36 +0000303 vis->indexBits = indexBits;
304 vis->depthBits = depthBits;
Brian Paule4b23562005-05-04 20:11:35 +0000305 vis->stencilBits = stencilBits;
306
307 vis->accumRedBits = accumRedBits;
308 vis->accumGreenBits = accumGreenBits;
309 vis->accumBlueBits = accumBlueBits;
310 vis->accumAlphaBits = accumAlphaBits;
Brian Pauled30dfa2000-03-03 17:47:39 +0000311
Brian Paul153f1542002-10-29 15:04:35 +0000312 vis->haveAccumBuffer = accumRedBits > 0;
313 vis->haveDepthBuffer = depthBits > 0;
314 vis->haveStencilBuffer = stencilBits > 0;
315
316 vis->numAuxBuffers = 0;
317 vis->level = 0;
318 vis->pixmapMode = 0;
Brian Paule4b23562005-05-04 20:11:35 +0000319 vis->sampleBuffers = numSamples > 0 ? 1 : 0;
Brian Paul894844a2004-03-21 17:05:03 +0000320 vis->samples = numSamples;
Brian Paul153f1542002-10-29 15:04:35 +0000321
Brian Paul178a1c52000-04-22 01:05:00 +0000322 return GL_TRUE;
Brian Paul4d053dd2000-01-14 04:45:47 +0000323}
324
Brian Paul894844a2004-03-21 17:05:03 +0000325
Keith Whitwell6dc85572003-07-17 13:43:59 +0000326/**
Brian Paul894844a2004-03-21 17:05:03 +0000327 * Destroy a visual and free its memory.
Keith Whitwell6dc85572003-07-17 13:43:59 +0000328 *
329 * \param vis visual.
330 *
331 * Frees the visual structure.
332 */
Brian Paulb371e0d2000-03-31 01:05:51 +0000333void
334_mesa_destroy_visual( GLvisual *vis )
335{
Brian Paulc7e164f2006-06-30 15:44:30 +0000336 _mesa_free(vis);
Brian Paulb371e0d2000-03-31 01:05:51 +0000337}
338
Keith Whitwell6dc85572003-07-17 13:43:59 +0000339/*@}*/
340
Brian Paulb371e0d2000-03-31 01:05:51 +0000341
Brian Paul4d053dd2000-01-14 04:45:47 +0000342/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +0000343/** \name Context allocation, initialization, destroying
344 *
345 * The purpose of the most initialization functions here is to provide the
346 * default state values according to the OpenGL specification.
347 */
jtgafb833d1999-08-19 00:55:39 +0000348/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +0000349/*@{*/
jtgafb833d1999-08-19 00:55:39 +0000350
Keith Whitwell6dc85572003-07-17 13:43:59 +0000351/**
352 * One-time initialization mutex lock.
353 *
354 * \sa Used by one_time_init().
355 */
Brian Paul9560f052000-01-31 23:11:39 +0000356_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
357
Keith Whitwell6dc85572003-07-17 13:43:59 +0000358/**
359 * Calls all the various one-time-init functions in Mesa.
360 *
361 * While holding a global mutex lock, calls several initialization functions,
362 * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
363 * defined.
364 *
Brian Paula764b7e2006-02-26 17:16:37 +0000365 * \sa _math_init().
jtgafb833d1999-08-19 00:55:39 +0000366 */
Brian Paul178a1c52000-04-22 01:05:00 +0000367static void
Brian Paul4753d602002-06-15 02:38:15 +0000368one_time_init( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +0000369{
370 static GLboolean alreadyCalled = GL_FALSE;
Brian Paula6c423d2004-08-25 15:59:48 +0000371 (void) ctx;
Brian Paul9560f052000-01-31 23:11:39 +0000372 _glthread_LOCK_MUTEX(OneTimeLock);
jtgafb833d1999-08-19 00:55:39 +0000373 if (!alreadyCalled) {
Brian Paul27558a12003-03-01 01:50:20 +0000374 GLuint i;
375
Brian Paul4d053dd2000-01-14 04:45:47 +0000376 /* do some implementation tests */
377 assert( sizeof(GLbyte) == 1 );
Brian Paul4d053dd2000-01-14 04:45:47 +0000378 assert( sizeof(GLubyte) == 1 );
Brian Paul894844a2004-03-21 17:05:03 +0000379 assert( sizeof(GLshort) == 2 );
380 assert( sizeof(GLushort) == 2 );
381 assert( sizeof(GLint) == 4 );
382 assert( sizeof(GLuint) == 4 );
Brian Paul4d053dd2000-01-14 04:45:47 +0000383
Brian33c37392007-04-04 22:18:53 -0600384 _mesa_init_sqrt_table();
385
Keith Whitwell6dc85572003-07-17 13:43:59 +0000386#if _HAVE_FULL_GL
Keith Whitwell23caf202000-11-16 21:05:34 +0000387 _math_init();
Brian Paul27558a12003-03-01 01:50:20 +0000388
389 for (i = 0; i < 256; i++) {
390 _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
391 }
Keith Whitwell6dc85572003-07-17 13:43:59 +0000392#endif
Brian Paul68ee4bc2000-01-28 19:02:22 +0000393
davem69775355a2001-06-05 23:54:00 +0000394#ifdef USE_SPARC_ASM
395 _mesa_init_sparc_glapi_relocs();
396#endif
Brian Paul3c634522002-10-24 23:57:19 +0000397 if (_mesa_getenv("MESA_DEBUG")) {
Brian Paul68ee4bc2000-01-28 19:02:22 +0000398 _glapi_noop_enable_warnings(GL_TRUE);
Brian Paul4e9676f2002-06-29 19:48:15 +0000399 _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
Brian Paul68ee4bc2000-01-28 19:02:22 +0000400 }
401 else {
402 _glapi_noop_enable_warnings(GL_FALSE);
403 }
404
jtgafb833d1999-08-19 00:55:39 +0000405#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
Brian Paul363344f2005-09-13 14:48:28 +0000406 _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
407 MESA_VERSION_STRING, __DATE__, __TIME__);
jtgafb833d1999-08-19 00:55:39 +0000408#endif
Brian Paul68ee4bc2000-01-28 19:02:22 +0000409
410 alreadyCalled = GL_TRUE;
411 }
Brian Paul9560f052000-01-31 23:11:39 +0000412 _glthread_UNLOCK_MUTEX(OneTimeLock);
jtgafb833d1999-08-19 00:55:39 +0000413}
414
Brian Paul894844a2004-03-21 17:05:03 +0000415
Keith Whitwell6dc85572003-07-17 13:43:59 +0000416/**
jtgafb833d1999-08-19 00:55:39 +0000417 * Allocate and initialize a shared context state structure.
Keith Whitwell6dc85572003-07-17 13:43:59 +0000418 * Initializes the display list, texture objects and vertex programs hash
419 * tables, allocates the texture objects. If it runs out of memory, frees
420 * everything already allocated before returning NULL.
Brian Paul894844a2004-03-21 17:05:03 +0000421 *
422 * \return pointer to a gl_shared_state structure on success, or NULL on
423 * failure.
jtgafb833d1999-08-19 00:55:39 +0000424 */
Brian Paula3f13702003-04-01 16:41:50 +0000425static GLboolean
426alloc_shared_state( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +0000427{
Brian Paula3f13702003-04-01 16:41:50 +0000428 struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
jtgafb833d1999-08-19 00:55:39 +0000429 if (!ss)
Brian Paula3f13702003-04-01 16:41:50 +0000430 return GL_FALSE;
431
432 ctx->Shared = ss;
jtgafb833d1999-08-19 00:55:39 +0000433
Brian Paule4b684c2000-09-12 21:07:40 +0000434 _glthread_INIT_MUTEX(ss->Mutex);
jtgafb833d1999-08-19 00:55:39 +0000435
Brian Paule4b684c2000-09-12 21:07:40 +0000436 ss->DisplayList = _mesa_NewHashTable();
Brian Paulbb797902000-01-24 16:19:54 +0000437 ss->TexObjects = _mesa_NewHashTable();
Brian Paul451f3102003-04-17 01:48:19 +0000438#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
Brian Paul610d5992003-01-14 04:55:45 +0000439 ss->Programs = _mesa_NewHashTable();
Brian Paul8dfc5b92002-10-16 17:57:51 +0000440#endif
jtgafb833d1999-08-19 00:55:39 +0000441
Brian Paul451f3102003-04-17 01:48:19 +0000442#if FEATURE_ARB_vertex_program
Briandf43fb62008-05-06 23:08:51 -0600443 ss->DefaultVertexProgram = (struct gl_vertex_program *)
444 ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
Brian Paul451f3102003-04-17 01:48:19 +0000445 if (!ss->DefaultVertexProgram)
446 goto cleanup;
447#endif
448#if FEATURE_ARB_fragment_program
Briandf43fb62008-05-06 23:08:51 -0600449 ss->DefaultFragmentProgram = (struct gl_fragment_program *)
450 ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
Brian Paul451f3102003-04-17 01:48:19 +0000451 if (!ss->DefaultFragmentProgram)
452 goto cleanup;
453#endif
Dave Airlie7f752fe2004-12-19 03:06:59 +0000454#if FEATURE_ATI_fragment_shader
Brian Paul63d68302005-11-19 16:43:04 +0000455 ss->ATIShaders = _mesa_NewHashTable();
456 ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
Dave Airlie7f752fe2004-12-19 03:06:59 +0000457 if (!ss->DefaultFragmentShader)
458 goto cleanup;
459#endif
Brian Paul451f3102003-04-17 01:48:19 +0000460
Tilman Sauerbeck17b50632006-07-11 19:03:21 +0000461#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
Brian Paulddc82ee2005-02-05 19:56:45 +0000462 ss->BufferObjects = _mesa_NewHashTable();
Tilman Sauerbeck17b50632006-07-11 19:03:21 +0000463#endif
464
Ian Romanickee34e6e2006-06-12 16:26:29 +0000465 ss->ArrayObjects = _mesa_NewHashTable();
Brian Paulddc82ee2005-02-05 19:56:45 +0000466
Michal Krol365582d2006-08-01 20:07:31 +0000467#if FEATURE_ARB_shader_objects
Briana90046f2006-12-15 10:07:26 -0700468 ss->ShaderObjects = _mesa_NewHashTable();
Michal Krol365582d2006-08-01 20:07:31 +0000469#endif
Ian Romanick0207b472003-09-09 00:10:12 +0000470
Brian Paula3f13702003-04-01 16:41:50 +0000471 ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
472 if (!ss->Default1D)
473 goto cleanup;
Brian Paula8523782000-11-19 23:10:25 +0000474
Brian Paula3f13702003-04-01 16:41:50 +0000475 ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
476 if (!ss->Default2D)
477 goto cleanup;
jtgafb833d1999-08-19 00:55:39 +0000478
Brian Paula3f13702003-04-01 16:41:50 +0000479 ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
480 if (!ss->Default3D)
481 goto cleanup;
Brian Paula8523782000-11-19 23:10:25 +0000482
Brian Paula3f13702003-04-01 16:41:50 +0000483 ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
484 if (!ss->DefaultCubeMap)
485 goto cleanup;
Brian Paula8523782000-11-19 23:10:25 +0000486
Brian Paula3f13702003-04-01 16:41:50 +0000487 ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
488 if (!ss->DefaultRect)
489 goto cleanup;
Brian Paul413d6a22000-05-26 14:44:59 +0000490
Ian Romanickbb372f12007-05-16 15:34:22 -0700491 ss->Default1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
492 if (!ss->Default1DArray)
493 goto cleanup;
494
495 ss->Default2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
496 if (!ss->Default2DArray)
497 goto cleanup;
498
Brian9e01b912007-08-13 11:29:46 +0100499 /* sanity check */
500 assert(ss->Default1D->RefCount == 1);
Brian Paula3f13702003-04-01 16:41:50 +0000501
Keith Whitwell5ac93f82006-11-01 14:21:57 +0000502 _glthread_INIT_MUTEX(ss->TexMutex);
503 ss->TextureStateStamp = 0;
504
Brian Paulddc82ee2005-02-05 19:56:45 +0000505#if FEATURE_EXT_framebuffer_object
506 ss->FrameBuffers = _mesa_NewHashTable();
507 if (!ss->FrameBuffers)
508 goto cleanup;
509 ss->RenderBuffers = _mesa_NewHashTable();
510 if (!ss->RenderBuffers)
511 goto cleanup;
512#endif
513
Brian Paula3f13702003-04-01 16:41:50 +0000514 return GL_TRUE;
515
Brian9e01b912007-08-13 11:29:46 +0100516cleanup:
Brian Paula3f13702003-04-01 16:41:50 +0000517 /* Ran out of memory at some point. Free everything and return NULL */
518 if (ss->DisplayList)
519 _mesa_DeleteHashTable(ss->DisplayList);
520 if (ss->TexObjects)
521 _mesa_DeleteHashTable(ss->TexObjects);
522#if FEATURE_NV_vertex_program
523 if (ss->Programs)
524 _mesa_DeleteHashTable(ss->Programs);
525#endif
Brian Paul451f3102003-04-17 01:48:19 +0000526#if FEATURE_ARB_vertex_program
Briandf43fb62008-05-06 23:08:51 -0600527 _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
Brian Paul451f3102003-04-17 01:48:19 +0000528#endif
529#if FEATURE_ARB_fragment_program
Briandf43fb62008-05-06 23:08:51 -0600530 _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
Brian Paul451f3102003-04-17 01:48:19 +0000531#endif
Dave Airlie7f752fe2004-12-19 03:06:59 +0000532#if FEATURE_ATI_fragment_shader
533 if (ss->DefaultFragmentShader)
Brian Paul63d68302005-11-19 16:43:04 +0000534 _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
Dave Airlie7f752fe2004-12-19 03:06:59 +0000535#endif
Tilman Sauerbeck17b50632006-07-11 19:03:21 +0000536#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
Ian Romanick0207b472003-09-09 00:10:12 +0000537 if (ss->BufferObjects)
538 _mesa_DeleteHashTable(ss->BufferObjects);
Brian Paulddc82ee2005-02-05 19:56:45 +0000539#endif
540
Tilman Sauerbeckc0eb7772006-07-11 19:36:27 +0000541 if (ss->ArrayObjects)
542 _mesa_DeleteHashTable (ss->ArrayObjects);
543
Michal Krol365582d2006-08-01 20:07:31 +0000544#if FEATURE_ARB_shader_objects
Brian0bf5dbe2006-12-19 18:02:41 -0700545 if (ss->ShaderObjects)
Briana90046f2006-12-15 10:07:26 -0700546 _mesa_DeleteHashTable (ss->ShaderObjects);
Michal Krol365582d2006-08-01 20:07:31 +0000547#endif
Ian Romanick0207b472003-09-09 00:10:12 +0000548
Brian Paulddc82ee2005-02-05 19:56:45 +0000549#if FEATURE_EXT_framebuffer_object
550 if (ss->FrameBuffers)
551 _mesa_DeleteHashTable(ss->FrameBuffers);
552 if (ss->RenderBuffers)
553 _mesa_DeleteHashTable(ss->RenderBuffers);
554#endif
555
Brian Paula3f13702003-04-01 16:41:50 +0000556 if (ss->Default1D)
557 (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
558 if (ss->Default2D)
559 (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
560 if (ss->Default3D)
561 (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
562 if (ss->DefaultCubeMap)
563 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
564 if (ss->DefaultRect)
565 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
Brian6f472502007-08-13 11:09:48 +0100566 if (ss->Default1DArray)
567 (*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray);
568 if (ss->Default2DArray)
569 (*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray);
Briana5c84de2008-01-01 10:20:21 -0700570
571 _mesa_free(ss);
572
Brian Paula3f13702003-04-01 16:41:50 +0000573 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +0000574}
575
Brian Paulc7e164f2006-06-30 15:44:30 +0000576
Keith Whitwell6dc85572003-07-17 13:43:59 +0000577/**
Brian Paulc7e164f2006-06-30 15:44:30 +0000578 * Callback for deleting a display list. Called by _mesa_HashDeleteAll().
579 */
580static void
581delete_displaylist_cb(GLuint id, void *data, void *userData)
582{
Keith Whitwell34a61c62008-09-21 19:29:15 -0700583#if FEATURE_dlist
Brian Paulc7e164f2006-06-30 15:44:30 +0000584 struct mesa_display_list *list = (struct mesa_display_list *) data;
585 GLcontext *ctx = (GLcontext *) userData;
586 _mesa_delete_list(ctx, list);
Keith Whitwell34a61c62008-09-21 19:29:15 -0700587#endif
Brian Paulc7e164f2006-06-30 15:44:30 +0000588}
589
590/**
591 * Callback for deleting a texture object. Called by _mesa_HashDeleteAll().
592 */
593static void
594delete_texture_cb(GLuint id, void *data, void *userData)
595{
596 struct gl_texture_object *texObj = (struct gl_texture_object *) data;
597 GLcontext *ctx = (GLcontext *) userData;
598 ctx->Driver.DeleteTexture(ctx, texObj);
599}
600
601/**
602 * Callback for deleting a program object. Called by _mesa_HashDeleteAll().
603 */
604static void
605delete_program_cb(GLuint id, void *data, void *userData)
606{
Brian Paul122629f2006-07-20 16:49:57 +0000607 struct gl_program *prog = (struct gl_program *) data;
Brian Paulc7e164f2006-06-30 15:44:30 +0000608 GLcontext *ctx = (GLcontext *) userData;
Brian Paulfbfe2a52008-05-19 08:43:36 -0600609 ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
610 prog->RefCount = 0; /* now going away */
Brian Paulc7e164f2006-06-30 15:44:30 +0000611 ctx->Driver.DeleteProgram(ctx, prog);
612}
613
614/**
615 * Callback for deleting an ATI fragment shader object.
616 * Called by _mesa_HashDeleteAll().
617 */
618static void
619delete_fragshader_cb(GLuint id, void *data, void *userData)
620{
621 struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
622 GLcontext *ctx = (GLcontext *) userData;
623 _mesa_delete_ati_fragment_shader(ctx, shader);
624}
625
626/**
627 * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll().
628 */
629static void
630delete_bufferobj_cb(GLuint id, void *data, void *userData)
631{
632 struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
633 GLcontext *ctx = (GLcontext *) userData;
634 ctx->Driver.DeleteBuffer(ctx, bufObj);
635}
636
Brian Paulc04bb512006-07-11 21:56:43 +0000637/**
638 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
639 */
640static void
641delete_arrayobj_cb(GLuint id, void *data, void *userData)
642{
643 struct gl_array_object *arrayObj = (struct gl_array_object *) data;
644 GLcontext *ctx = (GLcontext *) userData;
645 _mesa_delete_array_object(ctx, arrayObj);
646}
647
Brian Paul4d4373b2006-11-18 17:44:28 +0000648/**
Xiang, Haihao63d8a842008-03-31 17:02:47 +0800649 * Callback for freeing shader program data. Call it before delete_shader_cb
650 * to avoid memory access error.
651 */
652static void
653free_shader_program_data_cb(GLuint id, void *data, void *userData)
654{
655 GLcontext *ctx = (GLcontext *) userData;
656 struct gl_shader_program *shProg = (struct gl_shader_program *) data;
657
658 if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
659 _mesa_free_shader_program_data(ctx, shProg);
660 }
661}
662
663/**
Brian9e4bae92006-12-20 09:27:42 -0700664 * Callback for deleting shader and shader programs objects.
665 * Called by _mesa_HashDeleteAll().
Brian Paul4d4373b2006-11-18 17:44:28 +0000666 */
667static void
Brian9e4bae92006-12-20 09:27:42 -0700668delete_shader_cb(GLuint id, void *data, void *userData)
Brian Paul4d4373b2006-11-18 17:44:28 +0000669{
Brian9e4bae92006-12-20 09:27:42 -0700670 GLcontext *ctx = (GLcontext *) userData;
671 struct gl_shader *sh = (struct gl_shader *) data;
Xiang, Haihaoaef47c42008-03-31 16:27:47 +0800672 if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
673 _mesa_free_shader(ctx, sh);
674 }
675 else {
676 struct gl_shader_program *shProg = (struct gl_shader_program *) data;
677 ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
678 _mesa_free_shader_program(ctx, shProg);
679 }
Brian Paul4d4373b2006-11-18 17:44:28 +0000680}
681
Brian393a6252007-08-13 17:37:30 +0100682/**
683 * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll()
684 */
685static void
686delete_framebuffer_cb(GLuint id, void *data, void *userData)
687{
688 struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
Briandc732172007-08-14 11:56:59 +0100689 /* The fact that the framebuffer is in the hashtable means its refcount
690 * is one, but we're removing from the hashtable now. So clear refcount.
691 */
692 /*assert(fb->RefCount == 1);*/
693 fb->RefCount = 0;
Brian2f7c8042008-01-30 08:08:23 -0700694
695 /* NOTE: Delete should always be defined but there are two reports
696 * of it being NULL (bugs 13507, 14293). Work-around for now.
697 */
698 if (fb->Delete)
699 fb->Delete(fb);
Brian393a6252007-08-13 17:37:30 +0100700}
701
702/**
703 * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
704 */
705static void
706delete_renderbuffer_cb(GLuint id, void *data, void *userData)
707{
708 struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
Briandc732172007-08-14 11:56:59 +0100709 rb->RefCount = 0; /* see comment for FBOs above */
Brian Paul61b3ce82008-08-03 11:13:12 -0600710 if (rb->Delete)
711 rb->Delete(rb);
Brian393a6252007-08-13 17:37:30 +0100712}
713
714
Brian Paulc7e164f2006-06-30 15:44:30 +0000715
716/**
717 * Deallocate a shared state object and all children structures.
Keith Whitwell6dc85572003-07-17 13:43:59 +0000718 *
719 * \param ctx GL context.
720 * \param ss shared state pointer.
721 *
722 * Frees the display lists, the texture objects (calling the driver texture
723 * deletion callback to free its private data) and the vertex programs, as well
724 * as their hash tables.
725 *
726 * \sa alloc_shared_state().
jtgafb833d1999-08-19 00:55:39 +0000727 */
Brian Paul178a1c52000-04-22 01:05:00 +0000728static void
729free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
jtgafb833d1999-08-19 00:55:39 +0000730{
Brian Paulc7e164f2006-06-30 15:44:30 +0000731 /*
732 * Free display lists
733 */
734 _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
Brian Paulbb797902000-01-24 16:19:54 +0000735 _mesa_DeleteHashTable(ss->DisplayList);
jtgafb833d1999-08-19 00:55:39 +0000736
Brian Paulfbfe2a52008-05-19 08:43:36 -0600737#if FEATURE_ARB_shader_objects
738 _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
739 _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
740 _mesa_DeleteHashTable(ss->ShaderObjects);
741#endif
742
Brian Paul1096eae2006-01-16 16:35:13 +0000743#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
Brian Paulc7e164f2006-06-30 15:44:30 +0000744 _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
Brian Paul610d5992003-01-14 04:55:45 +0000745 _mesa_DeleteHashTable(ss->Programs);
Brian Paul8dfc5b92002-10-16 17:57:51 +0000746#endif
Brian Paul21841f02004-08-14 14:28:11 +0000747#if FEATURE_ARB_vertex_program
Briandf43fb62008-05-06 23:08:51 -0600748 _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
Brian Paul21841f02004-08-14 14:28:11 +0000749#endif
750#if FEATURE_ARB_fragment_program
Briandf43fb62008-05-06 23:08:51 -0600751 _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
Brian Paul21841f02004-08-14 14:28:11 +0000752#endif
Brian Paul1096eae2006-01-16 16:35:13 +0000753
Dave Airlie7f752fe2004-12-19 03:06:59 +0000754#if FEATURE_ATI_fragment_shader
Brian Paulc7e164f2006-06-30 15:44:30 +0000755 _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx);
Brian Paul1096eae2006-01-16 16:35:13 +0000756 _mesa_DeleteHashTable(ss->ATIShaders);
757 _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
Dave Airlie7f752fe2004-12-19 03:06:59 +0000758#endif
Brian Paul30f51ae2001-12-18 04:06:44 +0000759
Tilman Sauerbeck17b50632006-07-11 19:03:21 +0000760#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
Brian Paulc7e164f2006-06-30 15:44:30 +0000761 _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx);
Ian Romanick0207b472003-09-09 00:10:12 +0000762 _mesa_DeleteHashTable(ss->BufferObjects);
Brian Paulddc82ee2005-02-05 19:56:45 +0000763#endif
764
Brian Paulc04bb512006-07-11 21:56:43 +0000765 _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
Tilman Sauerbeckc0eb7772006-07-11 19:36:27 +0000766 _mesa_DeleteHashTable(ss->ArrayObjects);
767
Brian Paulddc82ee2005-02-05 19:56:45 +0000768#if FEATURE_EXT_framebuffer_object
Brian393a6252007-08-13 17:37:30 +0100769 _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
Brian Paulddc82ee2005-02-05 19:56:45 +0000770 _mesa_DeleteHashTable(ss->FrameBuffers);
Brian393a6252007-08-13 17:37:30 +0100771 _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx);
Brian Paulddc82ee2005-02-05 19:56:45 +0000772 _mesa_DeleteHashTable(ss->RenderBuffers);
773#endif
Michal Krol9b3752c2005-01-13 14:08:47 +0000774
Briandc732172007-08-14 11:56:59 +0100775 /*
776 * Free texture objects (after FBOs since some textures might have
777 * been bound to FBOs).
778 */
779 ASSERT(ctx->Driver.DeleteTexture);
780 /* the default textures */
781 ctx->Driver.DeleteTexture(ctx, ss->Default1D);
782 ctx->Driver.DeleteTexture(ctx, ss->Default2D);
783 ctx->Driver.DeleteTexture(ctx, ss->Default3D);
784 ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
785 ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
786 ctx->Driver.DeleteTexture(ctx, ss->Default1DArray);
787 ctx->Driver.DeleteTexture(ctx, ss->Default2DArray);
788 /* all other textures */
789 _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
790 _mesa_DeleteHashTable(ss->TexObjects);
791
Keith Whitwelle15fd852002-12-12 13:03:15 +0000792 _glthread_DESTROY_MUTEX(ss->Mutex);
793
Brian Paulc7e164f2006-06-30 15:44:30 +0000794 _mesa_free(ss);
jtgafb833d1999-08-19 00:55:39 +0000795}
796
797
Brian Paul4d859f72004-01-23 18:57:05 +0000798/**
799 * Initialize fields of gl_current_attrib (aka ctx->Current.*)
800 */
801static void
Briand881a9c2006-12-20 09:31:07 -0700802_mesa_init_current(GLcontext *ctx)
jtgafb833d1999-08-19 00:55:39 +0000803{
Brian Paul88bf0382004-02-13 15:30:08 +0000804 GLuint i;
jtgafb833d1999-08-19 00:55:39 +0000805
Brian Paul94b30dc2006-04-25 00:53:25 +0000806 /* Init all to (0,0,0,1) */
Keith Whitwell6dc85572003-07-17 13:43:59 +0000807 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
808 ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
jtgafb833d1999-08-19 00:55:39 +0000809 }
Brian Paul94b30dc2006-04-25 00:53:25 +0000810
811 /* redo special cases: */
Markus Amsler507da2472008-03-09 17:51:11 -0600812 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
Keith Whitwell6dc85572003-07-17 13:43:59 +0000813 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
814 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
Brian Paul88bf0382004-02-13 15:30:08 +0000815 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
Keith Whitwellfd275602006-10-30 20:16:35 +0000816 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
817 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
jtgafb833d1999-08-19 00:55:39 +0000818}
819
820
Brian Paul4d859f72004-01-23 18:57:05 +0000821/**
Brian Paul05051032005-11-01 04:36:33 +0000822 * Init vertex/fragment program native limits from logical limits.
823 */
824static void
825init_natives(struct gl_program_constants *prog)
826{
827 prog->MaxNativeInstructions = prog->MaxInstructions;
828 prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
829 prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
830 prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
831 prog->MaxNativeAttribs = prog->MaxAttribs;
832 prog->MaxNativeTemps = prog->MaxTemps;
833 prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
834 prog->MaxNativeParameters = prog->MaxParameters;
835}
836
837
838/**
Brian Paul4d859f72004-01-23 18:57:05 +0000839 * Initialize fields of gl_constants (aka ctx->Const.*).
840 * Use defaults from config.h. The device drivers will often override
841 * some of these values (such as number of texture units).
842 */
Keith Whitwell6dc85572003-07-17 13:43:59 +0000843static void
Briand881a9c2006-12-20 09:31:07 -0700844_mesa_init_constants(GLcontext *ctx)
jtgafb833d1999-08-19 00:55:39 +0000845{
Brian Paul4d053dd2000-01-14 04:45:47 +0000846 assert(ctx);
jtgafb833d1999-08-19 00:55:39 +0000847
Brian Paulcd1cefa2001-06-13 14:56:14 +0000848 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
849 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
850
Brian Paulda238ee2006-04-13 19:21:58 +0000851 assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_COORD_UNITS);
852 assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_IMAGE_UNITS);
853
Brian Paul53f82c52004-10-02 16:39:09 +0000854 /* Constants, may be overriden (usually only reduced) by device drivers */
Brian Paul4d053dd2000-01-14 04:45:47 +0000855 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
Brian Paulcd1cefa2001-06-13 14:56:14 +0000856 ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
857 ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
Brian Paul8afe7de2002-06-15 03:03:06 +0000858 ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
Ian Romanickbb372f12007-05-16 15:34:22 -0700859 ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
Brian Paul610d5992003-01-14 04:55:45 +0000860 ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
861 ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
Brian Paulda238ee2006-04-13 19:21:58 +0000862 ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
863 ctx->Const.MaxTextureImageUnits);
Gareth Hughes2c3d34c2001-03-18 08:53:49 +0000864 ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
Brian Paul87c964d2001-11-06 15:53:00 +0000865 ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
Brian Paul4d053dd2000-01-14 04:45:47 +0000866 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
Brian Paul539cce52000-02-03 19:40:07 +0000867 ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
868 ctx->Const.MinPointSize = MIN_POINT_SIZE;
869 ctx->Const.MaxPointSize = MAX_POINT_SIZE;
870 ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
871 ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
Brian Paulfde5e2c2001-09-15 18:02:49 +0000872 ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
Brian Paul539cce52000-02-03 19:40:07 +0000873 ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
874 ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
875 ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
876 ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
Brian Paulfde5e2c2001-09-15 18:02:49 +0000877 ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
Brian Paul4bdcfe52000-04-17 17:57:04 +0000878 ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
Brian Paul82b02f02000-05-07 20:37:40 +0000879 ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
880 ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
Brian Paula8644322000-11-27 18:22:13 +0000881 ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
882 ctx->Const.MaxLights = MAX_LIGHTS;
Ian Romanick882caa12003-05-30 21:37:14 +0000883 ctx->Const.MaxShininess = 128.0;
Brian Paul53f82c52004-10-02 16:39:09 +0000884 ctx->Const.MaxSpotExponent = 128.0;
885 ctx->Const.MaxViewportWidth = MAX_WIDTH;
886 ctx->Const.MaxViewportHeight = MAX_HEIGHT;
Brian Pauld0492cf2003-04-11 01:20:06 +0000887#if FEATURE_ARB_vertex_program
Brian Paul05051032005-11-01 04:36:33 +0000888 ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
889 ctx->Const.VertexProgram.MaxAluInstructions = 0;
890 ctx->Const.VertexProgram.MaxTexInstructions = 0;
891 ctx->Const.VertexProgram.MaxTexIndirections = 0;
892 ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
Brian64e80882007-04-16 10:36:28 -0600893 ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS;
Brian Paul05051032005-11-01 04:36:33 +0000894 ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
895 ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
Brian64e80882007-04-16 10:36:28 -0600896 ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
Brian Paul05051032005-11-01 04:36:33 +0000897 ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
Briana90046f2006-12-15 10:07:26 -0700898 ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
Brian Paul05051032005-11-01 04:36:33 +0000899 init_natives(&ctx->Const.VertexProgram);
Brian Pauld0492cf2003-04-11 01:20:06 +0000900#endif
Briana90046f2006-12-15 10:07:26 -0700901
Brian Pauld0492cf2003-04-11 01:20:06 +0000902#if FEATURE_ARB_fragment_program
Brian Paul05051032005-11-01 04:36:33 +0000903 ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
904 ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
905 ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
906 ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
907 ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
Brian64e80882007-04-16 10:36:28 -0600908 ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS;
Brian Paul05051032005-11-01 04:36:33 +0000909 ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
910 ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
Brian64e80882007-04-16 10:36:28 -0600911 ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
Brian Paul05051032005-11-01 04:36:33 +0000912 ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
Briana90046f2006-12-15 10:07:26 -0700913 ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
Brian Paul05051032005-11-01 04:36:33 +0000914 init_natives(&ctx->Const.FragmentProgram);
Brian Pauld0492cf2003-04-11 01:20:06 +0000915#endif
Brian Pauledd67742003-04-18 18:02:43 +0000916 ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
917 ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
Brian Pauld0492cf2003-04-11 01:20:06 +0000918
George Sapountzis507167d2006-12-06 06:54:13 +0200919 /* CheckArrayBounds is overriden by drivers/x11 for X server */
Brian Paula2b9bad2003-11-10 19:08:37 +0000920 ctx->Const.CheckArrayBounds = GL_FALSE;
Brian Paula2b9bad2003-11-10 19:08:37 +0000921
Brian Paul05051032005-11-01 04:36:33 +0000922 /* GL_ARB_draw_buffers */
Brian Paul53f82c52004-10-02 16:39:09 +0000923 ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
924
Brian Paul3deaa012005-02-07 05:08:24 +0000925 /* GL_OES_read_format */
Ian Romanick33899b72004-10-16 01:16:54 +0000926 ctx->Const.ColorReadFormat = GL_RGBA;
927 ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
928
Brian Paul3deaa012005-02-07 05:08:24 +0000929#if FEATURE_EXT_framebuffer_object
930 ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
931 ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
932#endif
933
Brian Paul90fcf6c2006-11-01 00:12:41 +0000934#if FEATURE_ARB_vertex_shader
935 ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
Briana90046f2006-12-15 10:07:26 -0700936 ctx->Const.MaxVarying = MAX_VARYING;
Brian Paul90fcf6c2006-11-01 00:12:41 +0000937#endif
938
Brian Paul53f82c52004-10-02 16:39:09 +0000939 /* sanity checks */
Brian Paulda238ee2006-04-13 19:21:58 +0000940 ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
941 ctx->Const.MaxTextureCoordUnits));
Brian Paul05051032005-11-01 04:36:33 +0000942 ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
943 ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
Briana90046f2006-12-15 10:07:26 -0700944
945 ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
946 ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
947 ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
948 ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
Keith Whitwell6dc85572003-07-17 13:43:59 +0000949}
jtgafb833d1999-08-19 00:55:39 +0000950
Brian Paul4d859f72004-01-23 18:57:05 +0000951
Keith Whitwell6dc85572003-07-17 13:43:59 +0000952/**
Brian Paul5e2e96b2006-05-15 15:26:04 +0000953 * Do some sanity checks on the limits/constants for the given context.
954 * Only called the first time a context is bound.
955 */
956static void
957check_context_limits(GLcontext *ctx)
958{
959 /* Many context limits/constants are limited by the size of
960 * internal arrays.
961 */
962 assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
963 assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
964 assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
965 assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
966
967 assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
968 assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
969
970 /* make sure largest texture image is <= MAX_WIDTH in size */
971 assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH);
972 assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH);
973 assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH);
974
975 assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
976
977 /* XXX probably add more tests */
978}
979
980
981/**
Keith Whitwell6dc85572003-07-17 13:43:59 +0000982 * Initialize the attribute groups in a GL context.
983 *
984 * \param ctx GL context.
985 *
986 * Initializes all the attributes, calling the respective <tt>init*</tt>
987 * functions for the more complex data structures.
988 */
989static GLboolean
Briand881a9c2006-12-20 09:31:07 -0700990init_attrib_groups(GLcontext *ctx)
Keith Whitwell6dc85572003-07-17 13:43:59 +0000991{
992 assert(ctx);
Brian Paul4d053dd2000-01-14 04:45:47 +0000993
Keith Whitwell6dc85572003-07-17 13:43:59 +0000994 /* Constants */
995 _mesa_init_constants( ctx );
Brian Paul0771d152000-04-07 00:19:41 +0000996
Brian Paul4d053dd2000-01-14 04:45:47 +0000997 /* Extensions */
Brian Paulde4f4602003-07-03 02:15:06 +0000998 _mesa_init_extensions( ctx );
jtgafb833d1999-08-19 00:55:39 +0000999
Keith Whitwell6dc85572003-07-17 13:43:59 +00001000 /* Attribute Groups */
Keith Whitwell34a61c62008-09-21 19:29:15 -07001001#if FEATURE_accum
Keith Whitwell6dc85572003-07-17 13:43:59 +00001002 _mesa_init_accum( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001003#endif
1004#if FEATURE_attrib_stack
Keith Whitwell6dc85572003-07-17 13:43:59 +00001005 _mesa_init_attrib( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001006#endif
Brian Paul148a2842003-09-17 03:40:11 +00001007 _mesa_init_buffer_objects( ctx );
Keith Whitwell6dc85572003-07-17 13:43:59 +00001008 _mesa_init_color( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001009#if FEATURE_colortable
Brian Paul05944c02003-07-22 03:51:46 +00001010 _mesa_init_colortables( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001011#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +00001012 _mesa_init_current( ctx );
1013 _mesa_init_depth( ctx );
1014 _mesa_init_debug( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001015#if FEATURE_dlist
Keith Whitwell6dc85572003-07-17 13:43:59 +00001016 _mesa_init_display_list( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001017#endif
1018#if FEATURE_evaluators
Keith Whitwell6dc85572003-07-17 13:43:59 +00001019 _mesa_init_eval( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001020#endif
Brian Paul3dc65912008-07-03 15:40:38 -06001021 _mesa_init_fbobjects( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001022#if FEATURE_feedback
Keith Whitwell6dc85572003-07-17 13:43:59 +00001023 _mesa_init_feedback( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001024#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +00001025 _mesa_init_fog( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001026#if FEATURE_histogram
Keith Whitwell6dc85572003-07-17 13:43:59 +00001027 _mesa_init_histogram( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001028#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +00001029 _mesa_init_hint( ctx );
1030 _mesa_init_line( ctx );
1031 _mesa_init_lighting( ctx );
1032 _mesa_init_matrix( ctx );
Brian Paul67742382005-02-26 17:16:12 +00001033 _mesa_init_multisample( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001034#if FEATURE_pixel_transfer
Keith Whitwell6dc85572003-07-17 13:43:59 +00001035 _mesa_init_pixel( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001036#endif
Brian Paul533c1db2008-06-09 14:25:23 -06001037 _mesa_init_pixelstore( ctx );
Keith Whitwell6dc85572003-07-17 13:43:59 +00001038 _mesa_init_point( ctx );
1039 _mesa_init_polygon( ctx );
Brian Paul05944c02003-07-22 03:51:46 +00001040 _mesa_init_program( ctx );
Brian Paul4fb99502005-09-02 13:42:49 +00001041 _mesa_init_query( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001042#if FEATURE_drawpix
Brian Paulddc82ee2005-02-05 19:56:45 +00001043 _mesa_init_rastpos( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001044#endif
Brian Paul67742382005-02-26 17:16:12 +00001045 _mesa_init_scissor( ctx );
Brian0bf5dbe2006-12-19 18:02:41 -07001046 _mesa_init_shader_state( ctx );
Keith Whitwell6dc85572003-07-17 13:43:59 +00001047 _mesa_init_stencil( ctx );
1048 _mesa_init_transform( ctx );
1049 _mesa_init_varray( ctx );
1050 _mesa_init_viewport( ctx );
jtgafb833d1999-08-19 00:55:39 +00001051
Keith Whitwell6dc85572003-07-17 13:43:59 +00001052 if (!_mesa_init_texture( ctx ))
1053 return GL_FALSE;
Brian Paulb17a7222003-06-13 02:37:27 +00001054
Keith Whitwell34a61c62008-09-21 19:29:15 -07001055#if FEATURE_texture_s3tc
Brian Paul8f04c122004-04-27 13:39:20 +00001056 _mesa_init_texture_s3tc( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001057#endif
1058#if FEATURE_texture_fxt1
Brian Paul8f04c122004-04-27 13:39:20 +00001059 _mesa_init_texture_fxt1( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001060#endif
Brian Paul8f04c122004-04-27 13:39:20 +00001061
Brian Paul4d053dd2000-01-14 04:45:47 +00001062 /* Miscellaneous */
Keith Whitwella96308c2000-10-30 13:31:59 +00001063 ctx->NewState = _NEW_ALL;
Brian Paul4d053dd2000-01-14 04:45:47 +00001064 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
Brian Paul4d053dd2000-01-14 04:45:47 +00001065
Brian Paula3f13702003-04-01 16:41:50 +00001066 return GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +00001067}
1068
1069
Brian Paulf44898c2003-07-18 15:44:57 +00001070/**
Brian4b654d42007-08-23 08:53:43 +01001071 * Update default objects in a GL context with respect to shared state.
1072 *
1073 * \param ctx GL context.
1074 *
1075 * Removes references to old default objects, (texture objects, program
1076 * objects, etc.) and changes to reference those from the current shared
1077 * state.
1078 */
1079static GLboolean
1080update_default_objects(GLcontext *ctx)
1081{
1082 assert(ctx);
1083
1084 _mesa_update_default_objects_program(ctx);
1085 _mesa_update_default_objects_texture(ctx);
1086 _mesa_update_default_objects_buffer_objects(ctx);
1087
1088 return GL_TRUE;
1089}
1090
1091
1092/**
Brian Paul21f69782004-11-27 05:05:32 +00001093 * This is the default function we plug into all dispatch table slots
1094 * This helps prevents a segfault when someone calls a GL function without
1095 * first checking if the extension's supported.
1096 */
1097static int
1098generic_nop(void)
1099{
Briancf239ce2007-06-11 10:57:01 -06001100 _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
Brian Paul21f69782004-11-27 05:05:32 +00001101 return 0;
1102}
1103
1104
1105/**
1106 * Allocate and initialize a new dispatch table.
1107 */
1108static struct _glapi_table *
1109alloc_dispatch_table(void)
1110{
1111 /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
1112 * In practice, this'll be the same for stand-alone Mesa. But for DRI
1113 * Mesa we do this to accomodate different versions of libGL and various
1114 * DRI drivers.
1115 */
1116 GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
1117 sizeof(struct _glapi_table) / sizeof(_glapi_proc));
1118 struct _glapi_table *table =
1119 (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
1120 if (table) {
1121 _glapi_proc *entry = (_glapi_proc *) table;
Brian Paula760ccf2004-12-03 15:24:34 +00001122 GLint i;
Brian Paul21f69782004-11-27 05:05:32 +00001123 for (i = 0; i < numEntries; i++) {
1124 entry[i] = (_glapi_proc) generic_nop;
1125 }
1126 }
1127 return table;
1128}
1129
1130
1131/**
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001132 * Initialize a GLcontext struct (rendering context).
Keith Whitwell6dc85572003-07-17 13:43:59 +00001133 *
1134 * This includes allocating all the other structs and arrays which hang off of
1135 * the context by pointers.
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001136 * Note that the driver needs to pass in its dd_function_table here since
1137 * we need to at least call driverFunctions->NewTextureObject to create the
1138 * default texture objects.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001139 *
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001140 * Called by _mesa_create_context().
Keith Whitwell6dc85572003-07-17 13:43:59 +00001141 *
1142 * Performs the imports and exports callback tables initialization, and
1143 * miscellaneous one-time initializations. If no shared context is supplied one
1144 * is allocated, and increase its reference count. Setups the GL API dispatch
1145 * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
1146 * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
1147 * for debug flags.
1148 *
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001149 * \param ctx the context to initialize
1150 * \param visual describes the visual attributes for this context
1151 * \param share_list points to context to share textures, display lists,
1152 * etc with, or NULL
1153 * \param driverFunctions table of device driver functions for this context
1154 * to use
1155 * \param driverContext pointer to driver-specific context data
jtgafb833d1999-08-19 00:55:39 +00001156 */
Brian Paul178a1c52000-04-22 01:05:00 +00001157GLboolean
Briand881a9c2006-12-20 09:31:07 -07001158_mesa_initialize_context(GLcontext *ctx,
1159 const GLvisual *visual,
1160 GLcontext *share_list,
1161 const struct dd_function_table *driverFunctions,
1162 void *driverContext)
jtgafb833d1999-08-19 00:55:39 +00001163{
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001164 ASSERT(driverContext);
1165 assert(driverFunctions->NewTextureObject);
Keith Whitwell3e62d3a2005-03-22 14:27:10 +00001166 assert(driverFunctions->FreeTexImageData);
jtgafb833d1999-08-19 00:55:39 +00001167
Brian Paul4753d602002-06-15 02:38:15 +00001168 /* misc one-time initializations */
1169 one_time_init(ctx);
Brian Paul9a33a112002-06-13 04:28:29 +00001170
Brian Paulb1394fa2000-09-26 20:53:53 +00001171 ctx->Visual = *visual;
Brian Paul3f02f901999-11-24 18:48:30 +00001172 ctx->DrawBuffer = NULL;
1173 ctx->ReadBuffer = NULL;
Brian Paule4b23562005-05-04 20:11:35 +00001174 ctx->WinSysDrawBuffer = NULL;
1175 ctx->WinSysReadBuffer = NULL;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001176
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001177 /* Plug in driver functions and context pointer here.
1178 * This is important because when we call alloc_shared_state() below
1179 * we'll call ctx->Driver.NewTextureObject() to create the default
1180 * textures.
Brian Paula3f13702003-04-01 16:41:50 +00001181 */
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001182 ctx->Driver = *driverFunctions;
1183 ctx->DriverCtx = driverContext;
Brian Paula3f13702003-04-01 16:41:50 +00001184
jtgafb833d1999-08-19 00:55:39 +00001185 if (share_list) {
Brian Paul5a2f32b2001-04-25 18:21:05 +00001186 /* share state with another context */
jtgafb833d1999-08-19 00:55:39 +00001187 ctx->Shared = share_list->Shared;
1188 }
1189 else {
Brian Paul5a2f32b2001-04-25 18:21:05 +00001190 /* allocate new, unshared state */
Brian Paula3f13702003-04-01 16:41:50 +00001191 if (!alloc_shared_state( ctx )) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001192 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001193 }
1194 }
Brian Paul9560f052000-01-31 23:11:39 +00001195 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
jtgafb833d1999-08-19 00:55:39 +00001196 ctx->Shared->RefCount++;
Brian Paul9560f052000-01-31 23:11:39 +00001197 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
jtgafb833d1999-08-19 00:55:39 +00001198
Keith Whitwell6dc85572003-07-17 13:43:59 +00001199 if (!init_attrib_groups( ctx )) {
jtgafb833d1999-08-19 00:55:39 +00001200 free_shared_state(ctx, ctx->Shared);
Brian Paul4d053dd2000-01-14 04:45:47 +00001201 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001202 }
jtgafb833d1999-08-19 00:55:39 +00001203
Brian Paul21f69782004-11-27 05:05:32 +00001204 /* setup the API dispatch tables */
1205 ctx->Exec = alloc_dispatch_table();
1206 ctx->Save = alloc_dispatch_table();
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001207 if (!ctx->Exec || !ctx->Save) {
1208 free_shared_state(ctx, ctx->Shared);
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001209 if (ctx->Exec)
Brian Paul21f69782004-11-27 05:05:32 +00001210 _mesa_free(ctx->Exec);
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001211 }
Brian Paul21f69782004-11-27 05:05:32 +00001212 _mesa_init_exec_table(ctx->Exec);
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001213 ctx->CurrentDispatch = ctx->Exec;
Keith Whitwell34a61c62008-09-21 19:29:15 -07001214#if FEATURE_dlist
Brian Paul21f69782004-11-27 05:05:32 +00001215 _mesa_init_dlist_table(ctx->Save);
Keith Whitwellae0eaf92003-11-24 15:23:18 +00001216 _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001217#endif
Gareth Hughesd8aa0262001-03-11 18:49:11 +00001218 /* Neutral tnl module stuff */
Keith Whitwell6dc85572003-07-17 13:43:59 +00001219 _mesa_init_exec_vtxfmt( ctx );
Gareth Hughesd8aa0262001-03-11 18:49:11 +00001220 ctx->TnlModule.Current = NULL;
1221 ctx->TnlModule.SwapCount = 0;
Brian Paulb6bcae52001-01-23 23:39:36 +00001222
Brian3e45db62007-03-27 09:51:52 -06001223 ctx->FragmentProgram._MaintainTexEnvProgram
1224 = (_mesa_getenv("MESA_TEX_PROG") != NULL);
1225 ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram;
1226
Briana90046f2006-12-15 10:07:26 -07001227 ctx->VertexProgram._MaintainTnlProgram
1228 = (_mesa_getenv("MESA_TNL_PROG") != NULL);
Brian3e45db62007-03-27 09:51:52 -06001229 if (ctx->VertexProgram._MaintainTnlProgram) {
Briana90046f2006-12-15 10:07:26 -07001230 /* this is required... */
1231 ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
Brian3e45db62007-03-27 09:51:52 -06001232 }
Keith Whitwell47b29f52005-05-04 11:44:44 +00001233
Brian Paula96f8892005-09-13 01:19:29 +00001234 ctx->FirstTimeCurrent = GL_TRUE;
1235
Brian Paul4d053dd2000-01-14 04:45:47 +00001236 return GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +00001237}
1238
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001239
Brian Paulde4f4602003-07-03 02:15:06 +00001240/**
Brian Paul4d053dd2000-01-14 04:45:47 +00001241 * Allocate and initialize a GLcontext structure.
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001242 * Note that the driver needs to pass in its dd_function_table here since
1243 * we need to at least call driverFunctions->NewTextureObject to initialize
1244 * the rendering context.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001245 *
1246 * \param visual a GLvisual pointer (we copy the struct contents)
1247 * \param share_list another context to share display lists with or NULL
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001248 * \param driverFunctions points to the dd_function_table into which the
1249 * driver has plugged in all its special functions.
1250 * \param driverCtx points to the device driver's private context state
Keith Whitwell6dc85572003-07-17 13:43:59 +00001251 *
1252 * \return pointer to a new __GLcontextRec or NULL if error.
Brian Paul4d053dd2000-01-14 04:45:47 +00001253 */
Brian Paul178a1c52000-04-22 01:05:00 +00001254GLcontext *
Briand881a9c2006-12-20 09:31:07 -07001255_mesa_create_context(const GLvisual *visual,
1256 GLcontext *share_list,
1257 const struct dd_function_table *driverFunctions,
1258 void *driverContext)
Brian Paul4d053dd2000-01-14 04:45:47 +00001259{
Brian Paul4753d602002-06-15 02:38:15 +00001260 GLcontext *ctx;
1261
1262 ASSERT(visual);
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001263 ASSERT(driverContext);
Brian Paul4753d602002-06-15 02:38:15 +00001264
Brian Paul3c634522002-10-24 23:57:19 +00001265 ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
Brian Paul4753d602002-06-15 02:38:15 +00001266 if (!ctx)
Brian Paul4d053dd2000-01-14 04:45:47 +00001267 return NULL;
Brian Paul4753d602002-06-15 02:38:15 +00001268
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001269 if (_mesa_initialize_context(ctx, visual, share_list,
1270 driverFunctions, driverContext)) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001271 return ctx;
1272 }
1273 else {
Brian Paul3c634522002-10-24 23:57:19 +00001274 _mesa_free(ctx);
Brian Paul4d053dd2000-01-14 04:45:47 +00001275 return NULL;
1276 }
1277}
1278
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001279
Keith Whitwell6dc85572003-07-17 13:43:59 +00001280/**
Brian Paul4d053dd2000-01-14 04:45:47 +00001281 * Free the data associated with the given context.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001282 *
1283 * But doesn't free the GLcontext struct itself.
1284 *
1285 * \sa _mesa_initialize_context() and init_attrib_groups().
Brian Paul4d053dd2000-01-14 04:45:47 +00001286 */
Brian Paul178a1c52000-04-22 01:05:00 +00001287void
Brian Paulb1394fa2000-09-26 20:53:53 +00001288_mesa_free_context_data( GLcontext *ctx )
Brian Paul4d053dd2000-01-14 04:45:47 +00001289{
Briandc732172007-08-14 11:56:59 +01001290 if (!_mesa_get_current_context()){
1291 /* No current context, but we may need one in order to delete
1292 * texture objs, etc. So temporarily bind the context now.
1293 */
1294 _mesa_make_current(ctx, NULL, NULL);
Brian Paul4d053dd2000-01-14 04:45:47 +00001295 }
Briandc732172007-08-14 11:56:59 +01001296
1297 /* unreference WinSysDraw/Read buffers */
1298 _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
1299 _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
1300 _mesa_unreference_framebuffer(&ctx->DrawBuffer);
1301 _mesa_unreference_framebuffer(&ctx->ReadBuffer);
Brian Paul4d053dd2000-01-14 04:45:47 +00001302
Briandf43fb62008-05-06 23:08:51 -06001303 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
1304 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
1305 _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1306
1307 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
1308 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
1309 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
1310
Brian145d7622007-08-16 10:05:00 +01001311 _mesa_free_attrib_data(ctx);
Keith Whitwell6dc85572003-07-17 13:43:59 +00001312 _mesa_free_lighting_data( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001313#if FEATURE_evaluators
Keith Whitwell6dc85572003-07-17 13:43:59 +00001314 _mesa_free_eval_data( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001315#endif
Keith Whitwell6dc85572003-07-17 13:43:59 +00001316 _mesa_free_texture_data( ctx );
1317 _mesa_free_matrix_data( ctx );
1318 _mesa_free_viewport_data( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001319#if FEATURE_colortable
Brian Paul05944c02003-07-22 03:51:46 +00001320 _mesa_free_colortables_data( ctx );
Keith Whitwell34a61c62008-09-21 19:29:15 -07001321#endif
Brian Paul21841f02004-08-14 14:28:11 +00001322 _mesa_free_program_data(ctx);
Brian935f93f2007-03-24 16:20:02 -06001323 _mesa_free_shader_state(ctx);
Brian Paul4fb99502005-09-02 13:42:49 +00001324 _mesa_free_query_data(ctx);
Brian Paul21841f02004-08-14 14:28:11 +00001325
1326#if FEATURE_ARB_vertex_buffer_object
1327 _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
Brian Paul8dfc5b92002-10-16 17:57:51 +00001328#endif
Brian Paulc04bb512006-07-11 21:56:43 +00001329 _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
Brian Paulfd284452001-07-19 15:54:34 +00001330
Brian Paul65a66f52004-11-27 22:47:59 +00001331 /* free dispatch tables */
1332 _mesa_free(ctx->Exec);
1333 _mesa_free(ctx->Save);
1334
Brian Paul30f51ae2001-12-18 04:06:44 +00001335 /* Shared context state (display lists, textures, etc) */
Brian Paul9560f052000-01-31 23:11:39 +00001336 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
Brian Paul4d053dd2000-01-14 04:45:47 +00001337 ctx->Shared->RefCount--;
Brian Paul9560f052000-01-31 23:11:39 +00001338 assert(ctx->Shared->RefCount >= 0);
1339 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1340 if (ctx->Shared->RefCount == 0) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001341 /* free shared state */
1342 free_shared_state( ctx, ctx->Shared );
1343 }
1344
Brian Paul702ca202003-07-18 15:22:16 +00001345 if (ctx->Extensions.String)
Brian Paulc7e164f2006-06-30 15:44:30 +00001346 _mesa_free((void *) ctx->Extensions.String);
Briandc732172007-08-14 11:56:59 +01001347
1348 /* unbind the context if it's currently bound */
1349 if (ctx == _mesa_get_current_context()) {
1350 _mesa_make_current(NULL, NULL, NULL);
1351 }
Brian Paul4d053dd2000-01-14 04:45:47 +00001352}
1353
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001354
Keith Whitwell6dc85572003-07-17 13:43:59 +00001355/**
Brian Paul4d053dd2000-01-14 04:45:47 +00001356 * Destroy a GLcontext structure.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001357 *
1358 * \param ctx GL context.
1359 *
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001360 * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
jtgafb833d1999-08-19 00:55:39 +00001361 */
Brian Paul178a1c52000-04-22 01:05:00 +00001362void
Brian Paulb1394fa2000-09-26 20:53:53 +00001363_mesa_destroy_context( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001364{
1365 if (ctx) {
Brian Paulb1394fa2000-09-26 20:53:53 +00001366 _mesa_free_context_data(ctx);
Brian Paulc7e164f2006-06-30 15:44:30 +00001367 _mesa_free( (void *) ctx );
jtgafb833d1999-08-19 00:55:39 +00001368 }
1369}
1370
Brian Pauld3fd7ba2004-01-20 02:49:27 +00001371
Keith Whitwell6dc85572003-07-17 13:43:59 +00001372#if _HAVE_FULL_GL
1373/**
jtgafb833d1999-08-19 00:55:39 +00001374 * Copy attribute groups from one context to another.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001375 *
1376 * \param src source context
1377 * \param dst destination context
1378 * \param mask bitwise OR of GL_*_BIT flags
1379 *
1380 * According to the bits specified in \p mask, copies the corresponding
Jose Fonseca375457b2004-09-09 22:23:24 +00001381 * attributes from \p src into \p dst. For many of the attributes a simple \c
Keith Whitwell6dc85572003-07-17 13:43:59 +00001382 * memcpy is not enough due to the existence of internal pointers in their data
1383 * structures.
jtgafb833d1999-08-19 00:55:39 +00001384 */
Brian Paul178a1c52000-04-22 01:05:00 +00001385void
Brian Paulb1394fa2000-09-26 20:53:53 +00001386_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
jtgafb833d1999-08-19 00:55:39 +00001387{
1388 if (mask & GL_ACCUM_BUFFER_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001389 /* OK to memcpy */
1390 dst->Accum = src->Accum;
jtgafb833d1999-08-19 00:55:39 +00001391 }
1392 if (mask & GL_COLOR_BUFFER_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001393 /* OK to memcpy */
1394 dst->Color = src->Color;
jtgafb833d1999-08-19 00:55:39 +00001395 }
1396 if (mask & GL_CURRENT_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001397 /* OK to memcpy */
1398 dst->Current = src->Current;
jtgafb833d1999-08-19 00:55:39 +00001399 }
1400 if (mask & GL_DEPTH_BUFFER_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001401 /* OK to memcpy */
1402 dst->Depth = src->Depth;
jtgafb833d1999-08-19 00:55:39 +00001403 }
1404 if (mask & GL_ENABLE_BIT) {
1405 /* no op */
1406 }
1407 if (mask & GL_EVAL_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001408 /* OK to memcpy */
1409 dst->Eval = src->Eval;
jtgafb833d1999-08-19 00:55:39 +00001410 }
1411 if (mask & GL_FOG_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001412 /* OK to memcpy */
1413 dst->Fog = src->Fog;
jtgafb833d1999-08-19 00:55:39 +00001414 }
1415 if (mask & GL_HINT_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001416 /* OK to memcpy */
1417 dst->Hint = src->Hint;
jtgafb833d1999-08-19 00:55:39 +00001418 }
1419 if (mask & GL_LIGHTING_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001420 GLuint i;
1421 /* begin with memcpy */
Brian Paul2aabdc72006-02-24 18:19:11 +00001422 dst->Light = src->Light;
Brian Paul85d81602002-06-17 23:36:31 +00001423 /* fixup linked lists to prevent pointer insanity */
1424 make_empty_list( &(dst->Light.EnabledList) );
1425 for (i = 0; i < MAX_LIGHTS; i++) {
1426 if (dst->Light.Light[i].Enabled) {
1427 insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
1428 }
1429 }
jtgafb833d1999-08-19 00:55:39 +00001430 }
1431 if (mask & GL_LINE_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001432 /* OK to memcpy */
1433 dst->Line = src->Line;
jtgafb833d1999-08-19 00:55:39 +00001434 }
1435 if (mask & GL_LIST_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001436 /* OK to memcpy */
1437 dst->List = src->List;
jtgafb833d1999-08-19 00:55:39 +00001438 }
1439 if (mask & GL_PIXEL_MODE_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001440 /* OK to memcpy */
1441 dst->Pixel = src->Pixel;
jtgafb833d1999-08-19 00:55:39 +00001442 }
1443 if (mask & GL_POINT_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001444 /* OK to memcpy */
1445 dst->Point = src->Point;
jtgafb833d1999-08-19 00:55:39 +00001446 }
1447 if (mask & GL_POLYGON_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001448 /* OK to memcpy */
1449 dst->Polygon = src->Polygon;
jtgafb833d1999-08-19 00:55:39 +00001450 }
1451 if (mask & GL_POLYGON_STIPPLE_BIT) {
1452 /* Use loop instead of MEMCPY due to problem with Portland Group's
1453 * C compiler. Reported by John Stone.
1454 */
Brian Paul85d81602002-06-17 23:36:31 +00001455 GLuint i;
1456 for (i = 0; i < 32; i++) {
jtgafb833d1999-08-19 00:55:39 +00001457 dst->PolygonStipple[i] = src->PolygonStipple[i];
1458 }
1459 }
1460 if (mask & GL_SCISSOR_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001461 /* OK to memcpy */
1462 dst->Scissor = src->Scissor;
jtgafb833d1999-08-19 00:55:39 +00001463 }
1464 if (mask & GL_STENCIL_BUFFER_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001465 /* OK to memcpy */
1466 dst->Stencil = src->Stencil;
jtgafb833d1999-08-19 00:55:39 +00001467 }
1468 if (mask & GL_TEXTURE_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001469 /* Cannot memcpy because of pointers */
1470 _mesa_copy_texture_state(src, dst);
jtgafb833d1999-08-19 00:55:39 +00001471 }
1472 if (mask & GL_TRANSFORM_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001473 /* OK to memcpy */
1474 dst->Transform = src->Transform;
jtgafb833d1999-08-19 00:55:39 +00001475 }
1476 if (mask & GL_VIEWPORT_BIT) {
Brian Paul85d81602002-06-17 23:36:31 +00001477 /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1478 dst->Viewport.X = src->Viewport.X;
1479 dst->Viewport.Y = src->Viewport.Y;
1480 dst->Viewport.Width = src->Viewport.Width;
1481 dst->Viewport.Height = src->Viewport.Height;
1482 dst->Viewport.Near = src->Viewport.Near;
1483 dst->Viewport.Far = src->Viewport.Far;
1484 _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
jtgafb833d1999-08-19 00:55:39 +00001485 }
Brian Paul85d81602002-06-17 23:36:31 +00001486
Keith Whitwella96308c2000-10-30 13:31:59 +00001487 /* XXX FIXME: Call callbacks?
1488 */
1489 dst->NewState = _NEW_ALL;
jtgafb833d1999-08-19 00:55:39 +00001490}
Keith Whitwell23caf202000-11-16 21:05:34 +00001491#endif
Keith Whitwell23caf202000-11-16 21:05:34 +00001492
1493
Brian Paulb1d53d92003-06-11 18:48:19 +00001494/**
1495 * Check if the given context can render into the given framebuffer
1496 * by checking visual attributes.
Brian Paulca007cb2006-03-07 03:01:26 +00001497 *
Brianee170f22007-06-08 14:12:27 -06001498 * Most of these tests could go away because Mesa is now pretty flexible
1499 * in terms of mixing rendering contexts with framebuffers. As long
1500 * as RGB vs. CI mode agree, we're probably good.
Brian Paulca007cb2006-03-07 03:01:26 +00001501 *
Brian Paulb1d53d92003-06-11 18:48:19 +00001502 * \return GL_TRUE if compatible, GL_FALSE otherwise.
1503 */
1504static GLboolean
1505check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
1506{
1507 const GLvisual *ctxvis = &ctx->Visual;
1508 const GLvisual *bufvis = &buffer->Visual;
1509
1510 if (ctxvis == bufvis)
1511 return GL_TRUE;
1512
1513 if (ctxvis->rgbMode != bufvis->rgbMode)
1514 return GL_FALSE;
Brian Pauld75963d2006-03-07 02:57:04 +00001515#if 0
1516 /* disabling this fixes the fgl_glxgears pbuffer demo */
Brian Paulb1d53d92003-06-11 18:48:19 +00001517 if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
1518 return GL_FALSE;
Brian Pauld75963d2006-03-07 02:57:04 +00001519#endif
Brian Paulb1d53d92003-06-11 18:48:19 +00001520 if (ctxvis->stereoMode && !bufvis->stereoMode)
1521 return GL_FALSE;
1522 if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
1523 return GL_FALSE;
1524 if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
1525 return GL_FALSE;
1526 if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
1527 return GL_FALSE;
1528 if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
1529 return GL_FALSE;
1530 if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
1531 return GL_FALSE;
1532 if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
1533 return GL_FALSE;
Brianee170f22007-06-08 14:12:27 -06001534#if 0
1535 /* disabled (see bug 11161) */
Brian Paulb1d53d92003-06-11 18:48:19 +00001536 if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
1537 return GL_FALSE;
Brianee170f22007-06-08 14:12:27 -06001538#endif
Brian Paulb1d53d92003-06-11 18:48:19 +00001539 if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
1540 return GL_FALSE;
1541
1542 return GL_TRUE;
1543}
1544
1545
Keith Whitwell6dc85572003-07-17 13:43:59 +00001546/**
Brian Paula702bbf2005-09-14 03:11:36 +00001547 * Do one-time initialization for the given framebuffer. Specifically,
1548 * ask the driver for the window's current size and update the framebuffer
1549 * object to match.
1550 * Really, the device driver should totally take care of this.
1551 */
1552static void
1553initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
1554{
1555 GLuint width, height;
Brian Paul55e42e52006-10-17 17:43:47 +00001556 if (ctx->Driver.GetBufferSize) {
1557 ctx->Driver.GetBufferSize(fb, &width, &height);
1558 if (ctx->Driver.ResizeBuffers)
1559 ctx->Driver.ResizeBuffers(ctx, fb, width, height);
1560 fb->Initialized = GL_TRUE;
1561 }
Brian Paula702bbf2005-09-14 03:11:36 +00001562}
1563
1564
1565/**
1566 * Bind the given context to the given drawBuffer and readBuffer and
1567 * make it the current context for the calling thread.
1568 * We'll render into the drawBuffer and read pixels from the
1569 * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
Keith Whitwell6dc85572003-07-17 13:43:59 +00001570 *
Brian Paula702bbf2005-09-14 03:11:36 +00001571 * We check that the context's and framebuffer's visuals are compatible
1572 * and return immediately if they're not.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001573 *
Brian Paula702bbf2005-09-14 03:11:36 +00001574 * \param newCtx the new GL context. If NULL then there will be no current GL
1575 * context.
1576 * \param drawBuffer the drawing framebuffer
1577 * \param readBuffer the reading framebuffer
Brian Paul00037781999-12-17 14:52:35 +00001578 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001579void
Brian Paule4b23562005-05-04 20:11:35 +00001580_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
1581 GLframebuffer *readBuffer )
Brian Paul00037781999-12-17 14:52:35 +00001582{
Keith Whitwell5c728372005-05-12 10:22:29 +00001583 if (MESA_VERBOSE & VERBOSE_API)
Brian Paule4b23562005-05-04 20:11:35 +00001584 _mesa_debug(newCtx, "_mesa_make_current()\n");
Brian Paul00037781999-12-17 14:52:35 +00001585
Brian Paulbe3602d2001-02-28 00:27:48 +00001586 /* Check that the context's and framebuffer's visuals are compatible.
Brian Paulbe3602d2001-02-28 00:27:48 +00001587 */
Brian Paulf1038f82006-03-20 15:20:57 +00001588 if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
Brian Pauld75963d2006-03-07 02:57:04 +00001589 if (!check_compatible(newCtx, drawBuffer)) {
1590 _mesa_warning(newCtx,
1591 "MakeCurrent: incompatible visuals for context and drawbuffer");
Brian Paulb1d53d92003-06-11 18:48:19 +00001592 return;
Brian Pauld75963d2006-03-07 02:57:04 +00001593 }
Brian Paulb1d53d92003-06-11 18:48:19 +00001594 }
Brian Paulf1038f82006-03-20 15:20:57 +00001595 if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
Brian Pauld75963d2006-03-07 02:57:04 +00001596 if (!check_compatible(newCtx, readBuffer)) {
1597 _mesa_warning(newCtx,
1598 "MakeCurrent: incompatible visuals for context and readbuffer");
Brian Paulb1d53d92003-06-11 18:48:19 +00001599 return;
Brian Pauld75963d2006-03-07 02:57:04 +00001600 }
Brian Paulbe3602d2001-02-28 00:27:48 +00001601 }
1602
Brian Paulc6c0f942006-03-16 18:05:25 +00001603 /* We used to call _glapi_check_multithread() here. Now do it in drivers */
Brian Paulf9b97d92000-01-28 20:17:42 +00001604 _glapi_set_context((void *) newCtx);
Brian Paulb1394fa2000-09-26 20:53:53 +00001605 ASSERT(_mesa_get_current_context() == newCtx);
Keith Whitwell23caf202000-11-16 21:05:34 +00001606
Keith Whitwell23caf202000-11-16 21:05:34 +00001607 if (!newCtx) {
Brian Paul00037781999-12-17 14:52:35 +00001608 _glapi_set_dispatch(NULL); /* none current */
1609 }
Keith Whitwell23caf202000-11-16 21:05:34 +00001610 else {
1611 _glapi_set_dispatch(newCtx->CurrentDispatch);
Brian Paul00037781999-12-17 14:52:35 +00001612
Keith Whitwell23caf202000-11-16 21:05:34 +00001613 if (drawBuffer && readBuffer) {
1614 /* TODO: check if newCtx and buffer's visual match??? */
Brian Paule4b23562005-05-04 20:11:35 +00001615
Brian Paule4b23562005-05-04 20:11:35 +00001616 ASSERT(drawBuffer->Name == 0);
1617 ASSERT(readBuffer->Name == 0);
Briana510bc32007-03-06 10:07:59 -07001618 _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
1619 _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
Brian Paulf1038f82006-03-20 15:20:57 +00001620
1621 /*
1622 * Only set the context's Draw/ReadBuffer fields if they're NULL
1623 * or not bound to a user-created FBO.
1624 */
Brian Paule4b23562005-05-04 20:11:35 +00001625 if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
Briana510bc32007-03-06 10:07:59 -07001626 _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
Brian Paulf1038f82006-03-20 15:20:57 +00001627 }
1628 if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
Briana510bc32007-03-06 10:07:59 -07001629 _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
Brian Paule4b23562005-05-04 20:11:35 +00001630 }
Brian Paulbb5c84f2005-07-01 01:22:25 +00001631
Brian32d86eb2007-08-16 18:52:48 +01001632 /* XXX only set this flag if we're really changing the draw/read
1633 * framebuffer bindings.
1634 */
Keith Whitwell23caf202000-11-16 21:05:34 +00001635 newCtx->NewState |= _NEW_BUFFERS;
Brian Paul10d7f542002-06-17 23:38:14 +00001636
Brian Paul4d4add02006-10-15 19:26:43 +00001637#if 1
1638 /* We want to get rid of these lines: */
1639
Keith Whitwell6dc85572003-07-17 13:43:59 +00001640#if _HAVE_FULL_GL
Brian Paul65a66f52004-11-27 22:47:59 +00001641 if (!drawBuffer->Initialized) {
Brian Paula702bbf2005-09-14 03:11:36 +00001642 initialize_framebuffer_size(newCtx, drawBuffer);
Brian Paul10d7f542002-06-17 23:38:14 +00001643 }
Brian Paul65a66f52004-11-27 22:47:59 +00001644 if (readBuffer != drawBuffer && !readBuffer->Initialized) {
Brian Paula702bbf2005-09-14 03:11:36 +00001645 initialize_framebuffer_size(newCtx, readBuffer);
Brian Paul10d7f542002-06-17 23:38:14 +00001646 }
Keith Whitwellf9bfdb12006-09-22 11:36:30 +00001647
1648 _mesa_resizebuffers(newCtx);
Keith Whitwell6dc85572003-07-17 13:43:59 +00001649#endif
Brian Paul4d4add02006-10-15 19:26:43 +00001650
1651#else
1652 /* We want the drawBuffer and readBuffer to be initialized by
1653 * the driver.
1654 * This generally means the Width and Height match the actual
1655 * window size and the renderbuffers (both hardware and software
1656 * based) are allocated to match. The later can generally be
1657 * done with a call to _mesa_resize_framebuffer().
1658 *
1659 * It's theoretically possible for a buffer to have zero width
1660 * or height, but for now, assert check that the driver did what's
1661 * expected of it.
1662 */
1663 ASSERT(drawBuffer->Width > 0);
1664 ASSERT(drawBuffer->Height > 0);
1665#endif
1666
Brian Paul65a66f52004-11-27 22:47:59 +00001667 if (newCtx->FirstTimeCurrent) {
1668 /* set initial viewport and scissor size now */
Brian Paula702bbf2005-09-14 03:11:36 +00001669 _mesa_set_viewport(newCtx, 0, 0,
1670 drawBuffer->Width, drawBuffer->Height);
Brian Pauldb79d2a2006-03-29 18:41:19 +00001671 _mesa_set_scissor(newCtx, 0, 0,
1672 drawBuffer->Width, drawBuffer->Height );
Brian Paul5e2e96b2006-05-15 15:26:04 +00001673 check_context_limits(newCtx);
Brian Paul65a66f52004-11-27 22:47:59 +00001674 }
Brian Paul00037781999-12-17 14:52:35 +00001675 }
Keith Whitwell23caf202000-11-16 21:05:34 +00001676
Keith Whitwell23caf202000-11-16 21:05:34 +00001677 /* We can use this to help debug user's problems. Tell them to set
1678 * the MESA_INFO env variable before running their app. Then the
1679 * first time each context is made current we'll print some useful
1680 * information.
1681 */
1682 if (newCtx->FirstTimeCurrent) {
Brian Paul3c634522002-10-24 23:57:19 +00001683 if (_mesa_getenv("MESA_INFO")) {
Keith Whitwell6dc85572003-07-17 13:43:59 +00001684 _mesa_print_info();
Keith Whitwell23caf202000-11-16 21:05:34 +00001685 }
1686 newCtx->FirstTimeCurrent = GL_FALSE;
1687 }
Brian Paul00037781999-12-17 14:52:35 +00001688 }
1689}
1690
Brian Paul635ee2d2005-04-15 17:25:07 +00001691
1692/**
1693 * Make context 'ctx' share the display lists, textures and programs
1694 * that are associated with 'ctxToShare'.
1695 * Any display lists, textures or programs associated with 'ctx' will
1696 * be deleted if nobody else is sharing them.
1697 */
1698GLboolean
1699_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
1700{
1701 if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
Brian4b654d42007-08-23 08:53:43 +01001702 struct gl_shared_state *oldSharedState = ctx->Shared;
1703
Brian Paul635ee2d2005-04-15 17:25:07 +00001704 ctx->Shared = ctxToShare->Shared;
1705 ctx->Shared->RefCount++;
Brian4b654d42007-08-23 08:53:43 +01001706
1707 update_default_objects(ctx);
1708
1709 oldSharedState->RefCount--;
1710 if (oldSharedState->RefCount == 0) {
1711 free_shared_state(ctx, oldSharedState);
1712 }
1713
Brian Paul635ee2d2005-04-15 17:25:07 +00001714 return GL_TRUE;
1715 }
1716 else {
1717 return GL_FALSE;
1718 }
1719}
1720
1721
1722
Keith Whitwell6dc85572003-07-17 13:43:59 +00001723/**
Briand881a9c2006-12-20 09:31:07 -07001724 * \return pointer to the current GL context for this thread.
Keith Whitwell6dc85572003-07-17 13:43:59 +00001725 *
1726 * Calls _glapi_get_context(). This isn't the fastest way to get the current
Briand881a9c2006-12-20 09:31:07 -07001727 * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in
1728 * context.h.
Brian Paul00037781999-12-17 14:52:35 +00001729 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001730GLcontext *
1731_mesa_get_current_context( void )
Brian Paul00037781999-12-17 14:52:35 +00001732{
Brian Paulf9b97d92000-01-28 20:17:42 +00001733 return (GLcontext *) _glapi_get_context();
Brian Paul00037781999-12-17 14:52:35 +00001734}
1735
Briand881a9c2006-12-20 09:31:07 -07001736
Keith Whitwell6dc85572003-07-17 13:43:59 +00001737/**
1738 * Get context's current API dispatch table.
1739 *
1740 * It'll either be the immediate-mode execute dispatcher or the display list
1741 * compile dispatcher.
1742 *
1743 * \param ctx GL context.
1744 *
1745 * \return pointer to dispatch_table.
1746 *
1747 * Simply returns __GLcontextRec::CurrentDispatch.
Brian Paulfbd8f211999-11-11 01:22:25 +00001748 */
1749struct _glapi_table *
1750_mesa_get_dispatch(GLcontext *ctx)
1751{
1752 return ctx->CurrentDispatch;
1753}
1754
Keith Whitwell6dc85572003-07-17 13:43:59 +00001755/*@}*/
Brian Paulfbd8f211999-11-11 01:22:25 +00001756
1757
jtgafb833d1999-08-19 00:55:39 +00001758/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +00001759/** \name Miscellaneous functions */
jtgafb833d1999-08-19 00:55:39 +00001760/**********************************************************************/
Keith Whitwell6dc85572003-07-17 13:43:59 +00001761/*@{*/
jtgafb833d1999-08-19 00:55:39 +00001762
Keith Whitwell6dc85572003-07-17 13:43:59 +00001763/**
1764 * Record an error.
1765 *
1766 * \param ctx GL context.
1767 * \param error error code.
1768 *
1769 * Records the given error code and call the driver's dd_function_table::Error
1770 * function if defined.
1771 *
1772 * \sa
Brian Paul4e9676f2002-06-29 19:48:15 +00001773 * This is called via _mesa_error().
jtgafb833d1999-08-19 00:55:39 +00001774 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001775void
Briand881a9c2006-12-20 09:31:07 -07001776_mesa_record_error(GLcontext *ctx, GLenum error)
jtgafb833d1999-08-19 00:55:39 +00001777{
Brian Paul18a285a2002-03-16 00:53:15 +00001778 if (!ctx)
1779 return;
1780
Brian Paul7eb06032000-07-14 04:13:40 +00001781 if (ctx->ErrorValue == GL_NO_ERROR) {
jtgafb833d1999-08-19 00:55:39 +00001782 ctx->ErrorValue = error;
1783 }
1784
1785 /* Call device driver's error handler, if any. This is used on the Mac. */
1786 if (ctx->Driver.Error) {
Briand881a9c2006-12-20 09:31:07 -07001787 ctx->Driver.Error(ctx);
jtgafb833d1999-08-19 00:55:39 +00001788 }
1789}
1790
Briand881a9c2006-12-20 09:31:07 -07001791
Keith Whitwell6dc85572003-07-17 13:43:59 +00001792/**
1793 * Execute glFinish().
1794 *
1795 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1796 * dd_function_table::Finish driver callback, if not NULL.
1797 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +00001798void GLAPIENTRY
Briand881a9c2006-12-20 09:31:07 -07001799_mesa_Finish(void)
jtgafb833d1999-08-19 00:55:39 +00001800{
Brian Paulfa9df402000-02-02 19:16:46 +00001801 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +00001802 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
Brian Paulfa9df402000-02-02 19:16:46 +00001803 if (ctx->Driver.Finish) {
Briand881a9c2006-12-20 09:31:07 -07001804 ctx->Driver.Finish(ctx);
jtgafb833d1999-08-19 00:55:39 +00001805 }
1806}
1807
Briand881a9c2006-12-20 09:31:07 -07001808
Keith Whitwell6dc85572003-07-17 13:43:59 +00001809/**
1810 * Execute glFlush().
1811 *
1812 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1813 * dd_function_table::Flush driver callback, if not NULL.
1814 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +00001815void GLAPIENTRY
Briand881a9c2006-12-20 09:31:07 -07001816_mesa_Flush(void)
jtgafb833d1999-08-19 00:55:39 +00001817{
Brian Paulfa9df402000-02-02 19:16:46 +00001818 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +00001819 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
Brian Paulfa9df402000-02-02 19:16:46 +00001820 if (ctx->Driver.Flush) {
Briand881a9c2006-12-20 09:31:07 -07001821 ctx->Driver.Flush(ctx);
jtgafb833d1999-08-19 00:55:39 +00001822 }
jtgafb833d1999-08-19 00:55:39 +00001823}
Brian Paul48c6a6e2000-09-08 21:28:04 +00001824
1825
Keith Whitwell6dc85572003-07-17 13:43:59 +00001826/*@}*/