context.c revision 848b8605
1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5848b8605Smrg * Copyright (C) 2008  VMware, Inc.  All Rights Reserved.
6848b8605Smrg *
7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg * copy of this software and associated documentation files (the "Software"),
9848b8605Smrg * to deal in the Software without restriction, including without limitation
10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
12848b8605Smrg * Software is furnished to do so, subject to the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice shall be included
15848b8605Smrg * in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
24848b8605Smrg */
25848b8605Smrg
26848b8605Smrg/**
27848b8605Smrg * \file context.c
28848b8605Smrg * Mesa context/visual/framebuffer management functions.
29848b8605Smrg * \author Brian Paul
30848b8605Smrg */
31848b8605Smrg
32848b8605Smrg/**
33848b8605Smrg * \mainpage Mesa Main Module
34848b8605Smrg *
35848b8605Smrg * \section MainIntroduction Introduction
36848b8605Smrg *
37848b8605Smrg * The Mesa Main module consists of all the files in the main/ directory.
38848b8605Smrg * Among the features of this module are:
39848b8605Smrg * <UL>
40848b8605Smrg * <LI> Structures to represent most GL state </LI>
41848b8605Smrg * <LI> State set/get functions </LI>
42848b8605Smrg * <LI> Display lists </LI>
43848b8605Smrg * <LI> Texture unit, object and image handling </LI>
44848b8605Smrg * <LI> Matrix and attribute stacks </LI>
45848b8605Smrg * </UL>
46848b8605Smrg *
47848b8605Smrg * Other modules are responsible for API dispatch, vertex transformation,
48848b8605Smrg * point/line/triangle setup, rasterization, vertex array caching,
49848b8605Smrg * vertex/fragment programs/shaders, etc.
50848b8605Smrg *
51848b8605Smrg *
52848b8605Smrg * \section AboutDoxygen About Doxygen
53848b8605Smrg *
54848b8605Smrg * If you're viewing this information as Doxygen-generated HTML you'll
55848b8605Smrg * see the documentation index at the top of this page.
56848b8605Smrg *
57848b8605Smrg * The first line lists the Mesa source code modules.
58848b8605Smrg * The second line lists the indexes available for viewing the documentation
59848b8605Smrg * for each module.
60848b8605Smrg *
61848b8605Smrg * Selecting the <b>Main page</b> link will display a summary of the module
62848b8605Smrg * (this page).
63848b8605Smrg *
64848b8605Smrg * Selecting <b>Data Structures</b> will list all C structures.
65848b8605Smrg *
66848b8605Smrg * Selecting the <b>File List</b> link will list all the source files in
67848b8605Smrg * the module.
68848b8605Smrg * Selecting a filename will show a list of all functions defined in that file.
69848b8605Smrg *
70848b8605Smrg * Selecting the <b>Data Fields</b> link will display a list of all
71848b8605Smrg * documented structure members.
72848b8605Smrg *
73848b8605Smrg * Selecting the <b>Globals</b> link will display a list
74848b8605Smrg * of all functions, structures, global variables and macros in the module.
75848b8605Smrg *
76848b8605Smrg */
77848b8605Smrg
78848b8605Smrg
79848b8605Smrg#include "glheader.h"
80848b8605Smrg#include "imports.h"
81848b8605Smrg#include "accum.h"
82848b8605Smrg#include "api_exec.h"
83848b8605Smrg#include "api_loopback.h"
84848b8605Smrg#include "arrayobj.h"
85848b8605Smrg#include "attrib.h"
86848b8605Smrg#include "blend.h"
87848b8605Smrg#include "buffers.h"
88848b8605Smrg#include "bufferobj.h"
89848b8605Smrg#include "context.h"
90848b8605Smrg#include "cpuinfo.h"
91848b8605Smrg#include "debug.h"
92848b8605Smrg#include "depth.h"
93848b8605Smrg#include "dlist.h"
94848b8605Smrg#include "eval.h"
95848b8605Smrg#include "extensions.h"
96848b8605Smrg#include "fbobject.h"
97848b8605Smrg#include "feedback.h"
98848b8605Smrg#include "fog.h"
99848b8605Smrg#include "formats.h"
100848b8605Smrg#include "framebuffer.h"
101848b8605Smrg#include "hint.h"
102848b8605Smrg#include "hash.h"
103848b8605Smrg#include "light.h"
104848b8605Smrg#include "lines.h"
105848b8605Smrg#include "macros.h"
106848b8605Smrg#include "matrix.h"
107848b8605Smrg#include "multisample.h"
108848b8605Smrg#include "performance_monitor.h"
109848b8605Smrg#include "pipelineobj.h"
110848b8605Smrg#include "pixel.h"
111848b8605Smrg#include "pixelstore.h"
112848b8605Smrg#include "points.h"
113848b8605Smrg#include "polygon.h"
114848b8605Smrg#include "queryobj.h"
115848b8605Smrg#include "syncobj.h"
116848b8605Smrg#include "rastpos.h"
117848b8605Smrg#include "remap.h"
118848b8605Smrg#include "scissor.h"
119848b8605Smrg#include "shared.h"
120848b8605Smrg#include "shaderobj.h"
121848b8605Smrg#include "simple_list.h"
122848b8605Smrg#include "state.h"
123848b8605Smrg#include "stencil.h"
124848b8605Smrg#include "texcompress_s3tc.h"
125848b8605Smrg#include "texstate.h"
126848b8605Smrg#include "transformfeedback.h"
127848b8605Smrg#include "mtypes.h"
128848b8605Smrg#include "varray.h"
129848b8605Smrg#include "version.h"
130848b8605Smrg#include "viewport.h"
131848b8605Smrg#include "vtxfmt.h"
132848b8605Smrg#include "program/program.h"
133848b8605Smrg#include "program/prog_print.h"
134848b8605Smrg#include "math/m_matrix.h"
135848b8605Smrg#include "main/dispatch.h" /* for _gloffset_COUNT */
136848b8605Smrg
137848b8605Smrg#ifdef USE_SPARC_ASM
138848b8605Smrg#include "sparc/sparc.h"
139848b8605Smrg#endif
140848b8605Smrg
141848b8605Smrg#include "glsl_parser_extras.h"
142848b8605Smrg#include <stdbool.h>
143848b8605Smrg
144848b8605Smrg
145848b8605Smrg#ifndef MESA_VERBOSE
146848b8605Smrgint MESA_VERBOSE = 0;
147848b8605Smrg#endif
148848b8605Smrg
149848b8605Smrg#ifndef MESA_DEBUG_FLAGS
150848b8605Smrgint MESA_DEBUG_FLAGS = 0;
151848b8605Smrg#endif
152848b8605Smrg
153848b8605Smrg
154848b8605Smrg/* ubyte -> float conversion */
155848b8605SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
156848b8605Smrg
157848b8605Smrg
158848b8605Smrg
159848b8605Smrg/**
160848b8605Smrg * Swap buffers notification callback.
161848b8605Smrg *
162848b8605Smrg * \param ctx GL context.
163848b8605Smrg *
164848b8605Smrg * Called by window system just before swapping buffers.
165848b8605Smrg * We have to finish any pending rendering.
166848b8605Smrg */
167848b8605Smrgvoid
168848b8605Smrg_mesa_notifySwapBuffers(struct gl_context *ctx)
169848b8605Smrg{
170848b8605Smrg   if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
171848b8605Smrg      _mesa_debug(ctx, "SwapBuffers\n");
172848b8605Smrg   FLUSH_CURRENT( ctx, 0 );
173848b8605Smrg   if (ctx->Driver.Flush) {
174848b8605Smrg      ctx->Driver.Flush(ctx);
175848b8605Smrg   }
176848b8605Smrg}
177848b8605Smrg
178848b8605Smrg
179848b8605Smrg/**********************************************************************/
180848b8605Smrg/** \name GL Visual allocation/destruction                            */
181848b8605Smrg/**********************************************************************/
182848b8605Smrg/*@{*/
183848b8605Smrg
184848b8605Smrg/**
185848b8605Smrg * Allocates a struct gl_config structure and initializes it via
186848b8605Smrg * _mesa_initialize_visual().
187848b8605Smrg *
188848b8605Smrg * \param dbFlag double buffering
189848b8605Smrg * \param stereoFlag stereo buffer
190848b8605Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
191848b8605Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
192848b8605Smrg * needed.
193848b8605Smrg * \param stencilBits requested minimum bits per stencil buffer value
194848b8605Smrg * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number
195848b8605Smrg * of bits per color component in accum buffer.
196848b8605Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
197848b8605Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
198848b8605Smrg * mode.  We always use 8 in core Mesa though.
199848b8605Smrg * \param greenBits same as above.
200848b8605Smrg * \param blueBits same as above.
201848b8605Smrg * \param alphaBits same as above.
202848b8605Smrg * \param numSamples not really used.
203848b8605Smrg *
204848b8605Smrg * \return pointer to new struct gl_config or NULL if requested parameters
205848b8605Smrg * can't be met.
206848b8605Smrg *
207848b8605Smrg * \note Need to add params for level and numAuxBuffers (at least)
208848b8605Smrg */
209848b8605Smrgstruct gl_config *
210848b8605Smrg_mesa_create_visual( GLboolean dbFlag,
211848b8605Smrg                     GLboolean stereoFlag,
212848b8605Smrg                     GLint redBits,
213848b8605Smrg                     GLint greenBits,
214848b8605Smrg                     GLint blueBits,
215848b8605Smrg                     GLint alphaBits,
216848b8605Smrg                     GLint depthBits,
217848b8605Smrg                     GLint stencilBits,
218848b8605Smrg                     GLint accumRedBits,
219848b8605Smrg                     GLint accumGreenBits,
220848b8605Smrg                     GLint accumBlueBits,
221848b8605Smrg                     GLint accumAlphaBits,
222848b8605Smrg                     GLint numSamples )
223848b8605Smrg{
224848b8605Smrg   struct gl_config *vis = CALLOC_STRUCT(gl_config);
225848b8605Smrg   if (vis) {
226848b8605Smrg      if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
227848b8605Smrg                                   redBits, greenBits, blueBits, alphaBits,
228848b8605Smrg                                   depthBits, stencilBits,
229848b8605Smrg                                   accumRedBits, accumGreenBits,
230848b8605Smrg                                   accumBlueBits, accumAlphaBits,
231848b8605Smrg                                   numSamples)) {
232848b8605Smrg         free(vis);
233848b8605Smrg         return NULL;
234848b8605Smrg      }
235848b8605Smrg   }
236848b8605Smrg   return vis;
237848b8605Smrg}
238848b8605Smrg
239848b8605Smrg
240848b8605Smrg/**
241848b8605Smrg * Makes some sanity checks and fills in the fields of the struct
242848b8605Smrg * gl_config object with the given parameters.  If the caller needs to
243848b8605Smrg * set additional fields, he should just probably init the whole
244848b8605Smrg * gl_config object himself.
245848b8605Smrg *
246848b8605Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
247848b8605Smrg *
248848b8605Smrg * \sa _mesa_create_visual() above for the parameter description.
249848b8605Smrg */
250848b8605SmrgGLboolean
251848b8605Smrg_mesa_initialize_visual( struct gl_config *vis,
252848b8605Smrg                         GLboolean dbFlag,
253848b8605Smrg                         GLboolean stereoFlag,
254848b8605Smrg                         GLint redBits,
255848b8605Smrg                         GLint greenBits,
256848b8605Smrg                         GLint blueBits,
257848b8605Smrg                         GLint alphaBits,
258848b8605Smrg                         GLint depthBits,
259848b8605Smrg                         GLint stencilBits,
260848b8605Smrg                         GLint accumRedBits,
261848b8605Smrg                         GLint accumGreenBits,
262848b8605Smrg                         GLint accumBlueBits,
263848b8605Smrg                         GLint accumAlphaBits,
264848b8605Smrg                         GLint numSamples )
265848b8605Smrg{
266848b8605Smrg   assert(vis);
267848b8605Smrg
268848b8605Smrg   if (depthBits < 0 || depthBits > 32) {
269848b8605Smrg      return GL_FALSE;
270848b8605Smrg   }
271848b8605Smrg   if (stencilBits < 0 || stencilBits > 8) {
272848b8605Smrg      return GL_FALSE;
273848b8605Smrg   }
274848b8605Smrg   assert(accumRedBits >= 0);
275848b8605Smrg   assert(accumGreenBits >= 0);
276848b8605Smrg   assert(accumBlueBits >= 0);
277848b8605Smrg   assert(accumAlphaBits >= 0);
278848b8605Smrg
279848b8605Smrg   vis->rgbMode          = GL_TRUE;
280848b8605Smrg   vis->doubleBufferMode = dbFlag;
281848b8605Smrg   vis->stereoMode       = stereoFlag;
282848b8605Smrg
283848b8605Smrg   vis->redBits          = redBits;
284848b8605Smrg   vis->greenBits        = greenBits;
285848b8605Smrg   vis->blueBits         = blueBits;
286848b8605Smrg   vis->alphaBits        = alphaBits;
287848b8605Smrg   vis->rgbBits          = redBits + greenBits + blueBits;
288848b8605Smrg
289848b8605Smrg   vis->indexBits      = 0;
290848b8605Smrg   vis->depthBits      = depthBits;
291848b8605Smrg   vis->stencilBits    = stencilBits;
292848b8605Smrg
293848b8605Smrg   vis->accumRedBits   = accumRedBits;
294848b8605Smrg   vis->accumGreenBits = accumGreenBits;
295848b8605Smrg   vis->accumBlueBits  = accumBlueBits;
296848b8605Smrg   vis->accumAlphaBits = accumAlphaBits;
297848b8605Smrg
298848b8605Smrg   vis->haveAccumBuffer   = accumRedBits > 0;
299848b8605Smrg   vis->haveDepthBuffer   = depthBits > 0;
300848b8605Smrg   vis->haveStencilBuffer = stencilBits > 0;
301848b8605Smrg
302848b8605Smrg   vis->numAuxBuffers = 0;
303848b8605Smrg   vis->level = 0;
304848b8605Smrg   vis->sampleBuffers = numSamples > 0 ? 1 : 0;
305848b8605Smrg   vis->samples = numSamples;
306848b8605Smrg
307848b8605Smrg   return GL_TRUE;
308848b8605Smrg}
309848b8605Smrg
310848b8605Smrg
311848b8605Smrg/**
312848b8605Smrg * Destroy a visual and free its memory.
313848b8605Smrg *
314848b8605Smrg * \param vis visual.
315848b8605Smrg *
316848b8605Smrg * Frees the visual structure.
317848b8605Smrg */
318848b8605Smrgvoid
319848b8605Smrg_mesa_destroy_visual( struct gl_config *vis )
320848b8605Smrg{
321848b8605Smrg   free(vis);
322848b8605Smrg}
323848b8605Smrg
324848b8605Smrg/*@}*/
325848b8605Smrg
326848b8605Smrg
327848b8605Smrg/**********************************************************************/
328848b8605Smrg/** \name Context allocation, initialization, destroying
329848b8605Smrg *
330848b8605Smrg * The purpose of the most initialization functions here is to provide the
331848b8605Smrg * default state values according to the OpenGL specification.
332848b8605Smrg */
333848b8605Smrg/**********************************************************************/
334848b8605Smrg/*@{*/
335848b8605Smrg
336848b8605Smrg
337848b8605Smrg/**
338848b8605Smrg * This is lame.  gdb only seems to recognize enum types that are
339848b8605Smrg * actually used somewhere.  We want to be able to print/use enum
340848b8605Smrg * values such as TEXTURE_2D_INDEX in gdb.  But we don't actually use
341848b8605Smrg * the gl_texture_index type anywhere.  Thus, this lame function.
342848b8605Smrg */
343848b8605Smrgstatic void
344848b8605Smrgdummy_enum_func(void)
345848b8605Smrg{
346848b8605Smrg   gl_buffer_index bi = BUFFER_FRONT_LEFT;
347848b8605Smrg   gl_face_index fi = FACE_POS_X;
348848b8605Smrg   gl_frag_result fr = FRAG_RESULT_DEPTH;
349848b8605Smrg   gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
350848b8605Smrg   gl_vert_attrib va = VERT_ATTRIB_POS;
351848b8605Smrg   gl_varying_slot vs = VARYING_SLOT_POS;
352848b8605Smrg
353848b8605Smrg   (void) bi;
354848b8605Smrg   (void) fi;
355848b8605Smrg   (void) fr;
356848b8605Smrg   (void) ti;
357848b8605Smrg   (void) va;
358848b8605Smrg   (void) vs;
359848b8605Smrg}
360848b8605Smrg
361848b8605Smrg
362848b8605Smrg/**
363848b8605Smrg * One-time initialization mutex lock.
364848b8605Smrg *
365848b8605Smrg * \sa Used by one_time_init().
366848b8605Smrg */
367848b8605Smrgmtx_t OneTimeLock = _MTX_INITIALIZER_NP;
368848b8605Smrg
369848b8605Smrg
370848b8605Smrg
371848b8605Smrg/**
372848b8605Smrg * Calls all the various one-time-init functions in Mesa.
373848b8605Smrg *
374848b8605Smrg * While holding a global mutex lock, calls several initialization functions,
375848b8605Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
376848b8605Smrg * defined.
377848b8605Smrg *
378848b8605Smrg * \sa _math_init().
379848b8605Smrg */
380848b8605Smrgstatic void
381848b8605Smrgone_time_init( struct gl_context *ctx )
382848b8605Smrg{
383848b8605Smrg   static GLbitfield api_init_mask = 0x0;
384848b8605Smrg
385848b8605Smrg   mtx_lock(&OneTimeLock);
386848b8605Smrg
387848b8605Smrg   /* truly one-time init */
388848b8605Smrg   if (!api_init_mask) {
389848b8605Smrg      GLuint i;
390848b8605Smrg
391848b8605Smrg      /* do some implementation tests */
392848b8605Smrg      assert( sizeof(GLbyte) == 1 );
393848b8605Smrg      assert( sizeof(GLubyte) == 1 );
394848b8605Smrg      assert( sizeof(GLshort) == 2 );
395848b8605Smrg      assert( sizeof(GLushort) == 2 );
396848b8605Smrg      assert( sizeof(GLint) == 4 );
397848b8605Smrg      assert( sizeof(GLuint) == 4 );
398848b8605Smrg
399848b8605Smrg      _mesa_one_time_init_extension_overrides();
400848b8605Smrg
401848b8605Smrg      _mesa_get_cpu_features();
402848b8605Smrg
403848b8605Smrg      for (i = 0; i < 256; i++) {
404848b8605Smrg         _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
405848b8605Smrg      }
406848b8605Smrg
407848b8605Smrg#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
408848b8605Smrg      if (MESA_VERBOSE != 0) {
409848b8605Smrg	 _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
410848b8605Smrg		     PACKAGE_VERSION, __DATE__, __TIME__);
411848b8605Smrg      }
412848b8605Smrg#endif
413848b8605Smrg
414848b8605Smrg#ifdef DEBUG
415848b8605Smrg      _mesa_test_formats();
416848b8605Smrg#endif
417848b8605Smrg   }
418848b8605Smrg
419848b8605Smrg   /* per-API one-time init */
420848b8605Smrg   if (!(api_init_mask & (1 << ctx->API))) {
421848b8605Smrg      _mesa_init_get_hash(ctx);
422848b8605Smrg
423848b8605Smrg      _mesa_init_remap_table();
424848b8605Smrg   }
425848b8605Smrg
426848b8605Smrg   api_init_mask |= 1 << ctx->API;
427848b8605Smrg
428848b8605Smrg   mtx_unlock(&OneTimeLock);
429848b8605Smrg
430848b8605Smrg   /* Hopefully atexit() is widely available.  If not, we may need some
431848b8605Smrg    * #ifdef tests here.
432848b8605Smrg    */
433848b8605Smrg#if 0 /* using destructor instead */
434848b8605Smrg   atexit(_mesa_destroy_shader_compiler);
435848b8605Smrg#endif
436848b8605Smrg
437848b8605Smrg   dummy_enum_func();
438848b8605Smrg}
439848b8605Smrg
440848b8605Smrg
441848b8605Smrg/**
442848b8605Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
443848b8605Smrg */
444848b8605Smrgstatic void
445848b8605Smrg_mesa_init_current(struct gl_context *ctx)
446848b8605Smrg{
447848b8605Smrg   GLuint i;
448848b8605Smrg
449848b8605Smrg   /* Init all to (0,0,0,1) */
450848b8605Smrg   for (i = 0; i < Elements(ctx->Current.Attrib); i++) {
451848b8605Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
452848b8605Smrg   }
453848b8605Smrg
454848b8605Smrg   /* redo special cases: */
455848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
456848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
457848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
458848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
459848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
460848b8605Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
461848b8605Smrg}
462848b8605Smrg
463848b8605Smrg
464848b8605Smrg/**
465848b8605Smrg * Init vertex/fragment/geometry program limits.
466848b8605Smrg * Important: drivers should override these with actual limits.
467848b8605Smrg */
468848b8605Smrgstatic void
469848b8605Smrginit_program_limits(struct gl_constants *consts, gl_shader_stage stage,
470848b8605Smrg                    struct gl_program_constants *prog)
471848b8605Smrg{
472848b8605Smrg   prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
473848b8605Smrg   prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
474848b8605Smrg   prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
475848b8605Smrg   prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
476848b8605Smrg   prog->MaxTemps = MAX_PROGRAM_TEMPS;
477848b8605Smrg   prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
478848b8605Smrg   prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
479848b8605Smrg   prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS;
480848b8605Smrg
481848b8605Smrg   switch (stage) {
482848b8605Smrg   case MESA_SHADER_VERTEX:
483848b8605Smrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
484848b8605Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
485848b8605Smrg      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
486848b8605Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
487848b8605Smrg      prog->MaxInputComponents = 0; /* value not used */
488848b8605Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
489848b8605Smrg      break;
490848b8605Smrg   case MESA_SHADER_FRAGMENT:
491848b8605Smrg      prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
492848b8605Smrg      prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
493848b8605Smrg      prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
494848b8605Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
495848b8605Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
496848b8605Smrg      prog->MaxOutputComponents = 0; /* value not used */
497848b8605Smrg      break;
498848b8605Smrg   case MESA_SHADER_GEOMETRY:
499848b8605Smrg      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
500848b8605Smrg      prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
501848b8605Smrg      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
502848b8605Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
503848b8605Smrg      prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
504848b8605Smrg      prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
505848b8605Smrg      break;
506848b8605Smrg   case MESA_SHADER_COMPUTE:
507848b8605Smrg      prog->MaxParameters = 0; /* not meaningful for compute shaders */
508848b8605Smrg      prog->MaxAttribs = 0; /* not meaningful for compute shaders */
509848b8605Smrg      prog->MaxAddressRegs = 0; /* not meaningful for compute shaders */
510848b8605Smrg      prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
511848b8605Smrg      prog->MaxInputComponents = 0; /* not meaningful for compute shaders */
512848b8605Smrg      prog->MaxOutputComponents = 0; /* not meaningful for compute shaders */
513848b8605Smrg      break;
514848b8605Smrg   default:
515848b8605Smrg      assert(0 && "Bad shader stage in init_program_limits()");
516848b8605Smrg   }
517848b8605Smrg
518848b8605Smrg   /* Set the native limits to zero.  This implies that there is no native
519848b8605Smrg    * support for shaders.  Let the drivers fill in the actual values.
520848b8605Smrg    */
521848b8605Smrg   prog->MaxNativeInstructions = 0;
522848b8605Smrg   prog->MaxNativeAluInstructions = 0;
523848b8605Smrg   prog->MaxNativeTexInstructions = 0;
524848b8605Smrg   prog->MaxNativeTexIndirections = 0;
525848b8605Smrg   prog->MaxNativeAttribs = 0;
526848b8605Smrg   prog->MaxNativeTemps = 0;
527848b8605Smrg   prog->MaxNativeAddressRegs = 0;
528848b8605Smrg   prog->MaxNativeParameters = 0;
529848b8605Smrg
530848b8605Smrg   /* Set GLSL datatype range/precision info assuming IEEE float values.
531848b8605Smrg    * Drivers should override these defaults as needed.
532848b8605Smrg    */
533848b8605Smrg   prog->MediumFloat.RangeMin = 127;
534848b8605Smrg   prog->MediumFloat.RangeMax = 127;
535848b8605Smrg   prog->MediumFloat.Precision = 23;
536848b8605Smrg   prog->LowFloat = prog->HighFloat = prog->MediumFloat;
537848b8605Smrg
538848b8605Smrg   /* Assume ints are stored as floats for now, since this is the least-common
539848b8605Smrg    * denominator.  The OpenGL ES spec implies (page 132) that the precision
540848b8605Smrg    * of integer types should be 0.  Practically speaking, IEEE
541848b8605Smrg    * single-precision floating point values can only store integers in the
542848b8605Smrg    * range [-0x01000000, 0x01000000] without loss of precision.
543848b8605Smrg    */
544848b8605Smrg   prog->MediumInt.RangeMin = 24;
545848b8605Smrg   prog->MediumInt.RangeMax = 24;
546848b8605Smrg   prog->MediumInt.Precision = 0;
547848b8605Smrg   prog->LowInt = prog->HighInt = prog->MediumInt;
548848b8605Smrg
549848b8605Smrg   prog->MaxUniformBlocks = 12;
550848b8605Smrg   prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents +
551848b8605Smrg                                         consts->MaxUniformBlockSize / 4 *
552848b8605Smrg                                         prog->MaxUniformBlocks);
553848b8605Smrg
554848b8605Smrg   prog->MaxAtomicBuffers = 0;
555848b8605Smrg   prog->MaxAtomicCounters = 0;
556848b8605Smrg}
557848b8605Smrg
558848b8605Smrg
559848b8605Smrg/**
560848b8605Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
561848b8605Smrg * Use defaults from config.h.  The device drivers will often override
562848b8605Smrg * some of these values (such as number of texture units).
563848b8605Smrg */
564848b8605Smrgvoid
565848b8605Smrg_mesa_init_constants(struct gl_constants *consts, gl_api api)
566848b8605Smrg{
567848b8605Smrg   int i;
568848b8605Smrg   assert(consts);
569848b8605Smrg
570848b8605Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
571848b8605Smrg   consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES;
572848b8605Smrg   consts->MaxTextureLevels = MAX_TEXTURE_LEVELS;
573848b8605Smrg   consts->Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
574848b8605Smrg   consts->MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
575848b8605Smrg   consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
576848b8605Smrg   consts->MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
577848b8605Smrg   consts->MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
578848b8605Smrg   consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
579848b8605Smrg   consts->MaxTextureUnits = MIN2(consts->MaxTextureCoordUnits,
580848b8605Smrg                                     consts->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
581848b8605Smrg   consts->MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
582848b8605Smrg   consts->MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
583848b8605Smrg   consts->MaxTextureBufferSize = 65536;
584848b8605Smrg   consts->TextureBufferOffsetAlignment = 1;
585848b8605Smrg   consts->MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
586848b8605Smrg   consts->SubPixelBits = SUB_PIXEL_BITS;
587848b8605Smrg   consts->MinPointSize = MIN_POINT_SIZE;
588848b8605Smrg   consts->MaxPointSize = MAX_POINT_SIZE;
589848b8605Smrg   consts->MinPointSizeAA = MIN_POINT_SIZE;
590848b8605Smrg   consts->MaxPointSizeAA = MAX_POINT_SIZE;
591848b8605Smrg   consts->PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
592848b8605Smrg   consts->MinLineWidth = MIN_LINE_WIDTH;
593848b8605Smrg   consts->MaxLineWidth = MAX_LINE_WIDTH;
594848b8605Smrg   consts->MinLineWidthAA = MIN_LINE_WIDTH;
595848b8605Smrg   consts->MaxLineWidthAA = MAX_LINE_WIDTH;
596848b8605Smrg   consts->LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
597848b8605Smrg   consts->MaxClipPlanes = 6;
598848b8605Smrg   consts->MaxLights = MAX_LIGHTS;
599848b8605Smrg   consts->MaxShininess = 128.0;
600848b8605Smrg   consts->MaxSpotExponent = 128.0;
601848b8605Smrg   consts->MaxViewportWidth = MAX_VIEWPORT_WIDTH;
602848b8605Smrg   consts->MaxViewportHeight = MAX_VIEWPORT_HEIGHT;
603848b8605Smrg   consts->MinMapBufferAlignment = 64;
604848b8605Smrg
605848b8605Smrg   /* Driver must override these values if ARB_viewport_array is supported. */
606848b8605Smrg   consts->MaxViewports = 1;
607848b8605Smrg   consts->ViewportSubpixelBits = 0;
608848b8605Smrg   consts->ViewportBounds.Min = 0;
609848b8605Smrg   consts->ViewportBounds.Max = 0;
610848b8605Smrg
611848b8605Smrg   /** GL_ARB_uniform_buffer_object */
612848b8605Smrg   consts->MaxCombinedUniformBlocks = 36;
613848b8605Smrg   consts->MaxUniformBufferBindings = 36;
614848b8605Smrg   consts->MaxUniformBlockSize = 16384;
615848b8605Smrg   consts->UniformBufferOffsetAlignment = 1;
616848b8605Smrg
617848b8605Smrg   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
618848b8605Smrg   consts->MaxUserAssignableUniformLocations =
619848b8605Smrg      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
620848b8605Smrg
621848b8605Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++)
622848b8605Smrg      init_program_limits(consts, i, &consts->Program[i]);
623848b8605Smrg
624848b8605Smrg   consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES;
625848b8605Smrg   consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
626848b8605Smrg
627848b8605Smrg   /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that
628848b8605Smrg    * gl_VertexID is implemented using a native hardware register with OpenGL
629848b8605Smrg    * semantics.
630848b8605Smrg    */
631848b8605Smrg   consts->VertexID_is_zero_based = false;
632848b8605Smrg
633848b8605Smrg   /* CheckArrayBounds is overriden by drivers/x11 for X server */
634848b8605Smrg   consts->CheckArrayBounds = GL_FALSE;
635848b8605Smrg
636848b8605Smrg   /* GL_ARB_draw_buffers */
637848b8605Smrg   consts->MaxDrawBuffers = MAX_DRAW_BUFFERS;
638848b8605Smrg
639848b8605Smrg   consts->MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
640848b8605Smrg   consts->MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE;
641848b8605Smrg
642848b8605Smrg   consts->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
643848b8605Smrg   consts->MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
644848b8605Smrg   consts->MaxVarying = 16; /* old limit not to break tnl and swrast */
645848b8605Smrg   consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
646848b8605Smrg   consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
647848b8605Smrg   consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
648848b8605Smrg
649848b8605Smrg   /* Shading language version */
650848b8605Smrg   if (api == API_OPENGL_COMPAT || api == API_OPENGL_CORE) {
651848b8605Smrg      consts->GLSLVersion = 120;
652848b8605Smrg      _mesa_override_glsl_version(consts);
653848b8605Smrg   }
654848b8605Smrg   else if (api == API_OPENGLES2) {
655848b8605Smrg      consts->GLSLVersion = 100;
656848b8605Smrg   }
657848b8605Smrg   else if (api == API_OPENGLES) {
658848b8605Smrg      consts->GLSLVersion = 0; /* GLSL not supported */
659848b8605Smrg   }
660848b8605Smrg
661848b8605Smrg   /* GL_ARB_framebuffer_object */
662848b8605Smrg   consts->MaxSamples = 0;
663848b8605Smrg
664848b8605Smrg   /* GLSL default if NativeIntegers == FALSE */
665848b8605Smrg   consts->UniformBooleanTrue = FLT_AS_UINT(1.0f);
666848b8605Smrg
667848b8605Smrg   /* GL_ARB_sync */
668848b8605Smrg   consts->MaxServerWaitTimeout = 0x1fff7fffffffULL;
669848b8605Smrg
670848b8605Smrg   /* GL_EXT_provoking_vertex */
671848b8605Smrg   consts->QuadsFollowProvokingVertexConvention = GL_TRUE;
672848b8605Smrg
673848b8605Smrg   /* GL_EXT_transform_feedback */
674848b8605Smrg   consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS;
675848b8605Smrg   consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
676848b8605Smrg   consts->MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
677848b8605Smrg   consts->MaxVertexStreams = 1;
678848b8605Smrg
679848b8605Smrg   /* GL 3.2  */
680848b8605Smrg   consts->ProfileMask = api == API_OPENGL_CORE
681848b8605Smrg                          ? GL_CONTEXT_CORE_PROFILE_BIT
682848b8605Smrg                          : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
683848b8605Smrg
684848b8605Smrg   /** GL_EXT_gpu_shader4 */
685848b8605Smrg   consts->MinProgramTexelOffset = -8;
686848b8605Smrg   consts->MaxProgramTexelOffset = 7;
687848b8605Smrg
688848b8605Smrg   /* GL_ARB_texture_gather */
689848b8605Smrg   consts->MinProgramTextureGatherOffset = -8;
690848b8605Smrg   consts->MaxProgramTextureGatherOffset = 7;
691848b8605Smrg
692848b8605Smrg   /* GL_ARB_robustness */
693848b8605Smrg   consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB;
694848b8605Smrg
695848b8605Smrg   /* PrimitiveRestart */
696848b8605Smrg   consts->PrimitiveRestartInSoftware = GL_FALSE;
697848b8605Smrg
698848b8605Smrg   /* ES 3.0 or ARB_ES3_compatibility */
699848b8605Smrg   consts->MaxElementIndex = 0xffffffffu;
700848b8605Smrg
701848b8605Smrg   /* GL_ARB_texture_multisample */
702848b8605Smrg   consts->MaxColorTextureSamples = 1;
703848b8605Smrg   consts->MaxDepthTextureSamples = 1;
704848b8605Smrg   consts->MaxIntegerSamples = 1;
705848b8605Smrg
706848b8605Smrg   /* GL_ARB_shader_atomic_counters */
707848b8605Smrg   consts->MaxAtomicBufferBindings = MAX_COMBINED_ATOMIC_BUFFERS;
708848b8605Smrg   consts->MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
709848b8605Smrg   consts->MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
710848b8605Smrg   consts->MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
711848b8605Smrg
712848b8605Smrg   /* GL_ARB_vertex_attrib_binding */
713848b8605Smrg   consts->MaxVertexAttribRelativeOffset = 2047;
714848b8605Smrg   consts->MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
715848b8605Smrg
716848b8605Smrg   /* GL_ARB_compute_shader */
717848b8605Smrg   consts->MaxComputeWorkGroupCount[0] = 65535;
718848b8605Smrg   consts->MaxComputeWorkGroupCount[1] = 65535;
719848b8605Smrg   consts->MaxComputeWorkGroupCount[2] = 65535;
720848b8605Smrg   consts->MaxComputeWorkGroupSize[0] = 1024;
721848b8605Smrg   consts->MaxComputeWorkGroupSize[1] = 1024;
722848b8605Smrg   consts->MaxComputeWorkGroupSize[2] = 64;
723848b8605Smrg   consts->MaxComputeWorkGroupInvocations = 1024;
724848b8605Smrg
725848b8605Smrg   /** GL_ARB_gpu_shader5 */
726848b8605Smrg   consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET;
727848b8605Smrg   consts->MaxFragmentInterpolationOffset = MAX_FRAGMENT_INTERPOLATION_OFFSET;
728848b8605Smrg}
729848b8605Smrg
730848b8605Smrg
731848b8605Smrg/**
732848b8605Smrg * Do some sanity checks on the limits/constants for the given context.
733848b8605Smrg * Only called the first time a context is bound.
734848b8605Smrg */
735848b8605Smrgstatic void
736848b8605Smrgcheck_context_limits(struct gl_context *ctx)
737848b8605Smrg{
738848b8605Smrg   /* check that we don't exceed the size of various bitfields */
739848b8605Smrg   assert(VARYING_SLOT_MAX <=
740848b8605Smrg	  (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
741848b8605Smrg   assert(VARYING_SLOT_MAX <=
742848b8605Smrg	  (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
743848b8605Smrg
744848b8605Smrg   /* shader-related checks */
745848b8605Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
746848b8605Smrg   assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
747848b8605Smrg
748848b8605Smrg   /* Texture unit checks */
749848b8605Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0);
750848b8605Smrg   assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
751848b8605Smrg   assert(ctx->Const.MaxTextureCoordUnits > 0);
752848b8605Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
753848b8605Smrg   assert(ctx->Const.MaxTextureUnits > 0);
754848b8605Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
755848b8605Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
756848b8605Smrg   assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
757848b8605Smrg                                             ctx->Const.MaxTextureCoordUnits));
758848b8605Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
759848b8605Smrg   assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
760848b8605Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
761848b8605Smrg   /* number of coord units cannot be greater than number of image units */
762848b8605Smrg   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
763848b8605Smrg
764848b8605Smrg
765848b8605Smrg   /* Texture size checks */
766848b8605Smrg   assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
767848b8605Smrg   assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
768848b8605Smrg   assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
769848b8605Smrg   assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
770848b8605Smrg
771848b8605Smrg   /* Texture level checks */
772848b8605Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
773848b8605Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
774848b8605Smrg
775848b8605Smrg   /* Max texture size should be <= max viewport size (render to texture) */
776848b8605Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
777848b8605Smrg          <= ctx->Const.MaxViewportWidth);
778848b8605Smrg   assert((1U << (ctx->Const.MaxTextureLevels - 1))
779848b8605Smrg          <= ctx->Const.MaxViewportHeight);
780848b8605Smrg
781848b8605Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
782848b8605Smrg
783848b8605Smrg   /* if this fails, add more enum values to gl_buffer_index */
784848b8605Smrg   assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
785848b8605Smrg
786848b8605Smrg   /* XXX probably add more tests */
787848b8605Smrg}
788848b8605Smrg
789848b8605Smrg
790848b8605Smrg/**
791848b8605Smrg * Initialize the attribute groups in a GL context.
792848b8605Smrg *
793848b8605Smrg * \param ctx GL context.
794848b8605Smrg *
795848b8605Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
796848b8605Smrg * functions for the more complex data structures.
797848b8605Smrg */
798848b8605Smrgstatic GLboolean
799848b8605Smrginit_attrib_groups(struct gl_context *ctx)
800848b8605Smrg{
801848b8605Smrg   assert(ctx);
802848b8605Smrg
803848b8605Smrg   /* Constants */
804848b8605Smrg   _mesa_init_constants(&ctx->Const, ctx->API);
805848b8605Smrg
806848b8605Smrg   /* Extensions */
807848b8605Smrg   _mesa_init_extensions(&ctx->Extensions);
808848b8605Smrg
809848b8605Smrg   /* Attribute Groups */
810848b8605Smrg   _mesa_init_accum( ctx );
811848b8605Smrg   _mesa_init_attrib( ctx );
812848b8605Smrg   _mesa_init_buffer_objects( ctx );
813848b8605Smrg   _mesa_init_color( ctx );
814848b8605Smrg   _mesa_init_current( ctx );
815848b8605Smrg   _mesa_init_depth( ctx );
816848b8605Smrg   _mesa_init_debug( ctx );
817848b8605Smrg   _mesa_init_display_list( ctx );
818848b8605Smrg   _mesa_init_errors( ctx );
819848b8605Smrg   _mesa_init_eval( ctx );
820848b8605Smrg   _mesa_init_fbobjects( ctx );
821848b8605Smrg   _mesa_init_feedback( ctx );
822848b8605Smrg   _mesa_init_fog( ctx );
823848b8605Smrg   _mesa_init_hint( ctx );
824848b8605Smrg   _mesa_init_line( ctx );
825848b8605Smrg   _mesa_init_lighting( ctx );
826848b8605Smrg   _mesa_init_matrix( ctx );
827848b8605Smrg   _mesa_init_multisample( ctx );
828848b8605Smrg   _mesa_init_performance_monitors( ctx );
829848b8605Smrg   _mesa_init_pipeline( ctx );
830848b8605Smrg   _mesa_init_pixel( ctx );
831848b8605Smrg   _mesa_init_pixelstore( ctx );
832848b8605Smrg   _mesa_init_point( ctx );
833848b8605Smrg   _mesa_init_polygon( ctx );
834848b8605Smrg   _mesa_init_program( ctx );
835848b8605Smrg   _mesa_init_queryobj( ctx );
836848b8605Smrg   _mesa_init_sync( ctx );
837848b8605Smrg   _mesa_init_rastpos( ctx );
838848b8605Smrg   _mesa_init_scissor( ctx );
839848b8605Smrg   _mesa_init_shader_state( ctx );
840848b8605Smrg   _mesa_init_stencil( ctx );
841848b8605Smrg   _mesa_init_transform( ctx );
842848b8605Smrg   _mesa_init_transform_feedback( ctx );
843848b8605Smrg   _mesa_init_varray( ctx );
844848b8605Smrg   _mesa_init_viewport( ctx );
845848b8605Smrg
846848b8605Smrg   if (!_mesa_init_texture( ctx ))
847848b8605Smrg      return GL_FALSE;
848848b8605Smrg
849848b8605Smrg   _mesa_init_texture_s3tc( ctx );
850848b8605Smrg
851848b8605Smrg   /* Miscellaneous */
852848b8605Smrg   ctx->NewState = _NEW_ALL;
853848b8605Smrg   ctx->NewDriverState = ~0;
854848b8605Smrg   ctx->ErrorValue = GL_NO_ERROR;
855848b8605Smrg   ctx->ShareGroupReset = false;
856848b8605Smrg   ctx->varying_vp_inputs = VERT_BIT_ALL;
857848b8605Smrg
858848b8605Smrg   return GL_TRUE;
859848b8605Smrg}
860848b8605Smrg
861848b8605Smrg
862848b8605Smrg/**
863848b8605Smrg * Update default objects in a GL context with respect to shared state.
864848b8605Smrg *
865848b8605Smrg * \param ctx GL context.
866848b8605Smrg *
867848b8605Smrg * Removes references to old default objects, (texture objects, program
868848b8605Smrg * objects, etc.) and changes to reference those from the current shared
869848b8605Smrg * state.
870848b8605Smrg */
871848b8605Smrgstatic GLboolean
872848b8605Smrgupdate_default_objects(struct gl_context *ctx)
873848b8605Smrg{
874848b8605Smrg   assert(ctx);
875848b8605Smrg
876848b8605Smrg   _mesa_update_default_objects_program(ctx);
877848b8605Smrg   _mesa_update_default_objects_texture(ctx);
878848b8605Smrg   _mesa_update_default_objects_buffer_objects(ctx);
879848b8605Smrg
880848b8605Smrg   return GL_TRUE;
881848b8605Smrg}
882848b8605Smrg
883848b8605Smrg
884848b8605Smrg/**
885848b8605Smrg * This is the default function we plug into all dispatch table slots
886848b8605Smrg * This helps prevents a segfault when someone calls a GL function without
887848b8605Smrg * first checking if the extension's supported.
888848b8605Smrg */
889848b8605Smrgint
890848b8605Smrg_mesa_generic_nop(void)
891848b8605Smrg{
892848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
893848b8605Smrg   _mesa_error(ctx, GL_INVALID_OPERATION,
894848b8605Smrg               "unsupported function called "
895848b8605Smrg               "(unsupported extension or deprecated function?)");
896848b8605Smrg   return 0;
897848b8605Smrg}
898848b8605Smrg
899848b8605Smrg
900848b8605Smrg/**
901848b8605Smrg * Special no-op glFlush, see below.
902848b8605Smrg */
903848b8605Smrg#if defined(_WIN32)
904848b8605Smrgstatic void GLAPIENTRY
905848b8605Smrgnop_glFlush(void)
906848b8605Smrg{
907848b8605Smrg   /* don't record an error like we do in _mesa_generic_nop() */
908848b8605Smrg}
909848b8605Smrg#endif
910848b8605Smrg
911848b8605Smrg
912848b8605Smrg/**
913848b8605Smrg * Allocate and initialize a new dispatch table.  All the dispatch
914848b8605Smrg * function pointers will point at the _mesa_generic_nop() function
915848b8605Smrg * which raises GL_INVALID_OPERATION.
916848b8605Smrg */
917848b8605Smrgstruct _glapi_table *
918848b8605Smrg_mesa_alloc_dispatch_table()
919848b8605Smrg{
920848b8605Smrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
921848b8605Smrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
922848b8605Smrg    * Mesa we do this to accomodate different versions of libGL and various
923848b8605Smrg    * DRI drivers.
924848b8605Smrg    */
925848b8605Smrg   GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
926848b8605Smrg   struct _glapi_table *table;
927848b8605Smrg
928848b8605Smrg   table = malloc(numEntries * sizeof(_glapi_proc));
929848b8605Smrg   if (table) {
930848b8605Smrg      _glapi_proc *entry = (_glapi_proc *) table;
931848b8605Smrg      GLint i;
932848b8605Smrg      for (i = 0; i < numEntries; i++) {
933848b8605Smrg         entry[i] = (_glapi_proc) _mesa_generic_nop;
934848b8605Smrg      }
935848b8605Smrg
936848b8605Smrg#if defined(_WIN32)
937848b8605Smrg      /* This is a special case for Windows in the event that
938848b8605Smrg       * wglGetProcAddress is called between glBegin/End().
939848b8605Smrg       *
940848b8605Smrg       * The MS opengl32.dll library apparently calls glFlush from
941848b8605Smrg       * wglGetProcAddress().  If we're inside glBegin/End(), glFlush
942848b8605Smrg       * will dispatch to _mesa_generic_nop() and we'll generate a
943848b8605Smrg       * GL_INVALID_OPERATION error.
944848b8605Smrg       *
945848b8605Smrg       * The specific case which hits this is piglit's primitive-restart
946848b8605Smrg       * test which calls glPrimitiveRestartNV() inside glBegin/End.  The
947848b8605Smrg       * first time we call glPrimitiveRestartNV() Piglit's API dispatch
948848b8605Smrg       * code will try to resolve the function by calling wglGetProcAddress.
949848b8605Smrg       * This raises GL_INVALID_OPERATION and an assert(glGetError()==0)
950848b8605Smrg       * will fail causing the test to fail.  By suppressing the error, the
951848b8605Smrg       * assertion passes and the test continues.
952848b8605Smrg       */
953848b8605Smrg      SET_Flush(table, nop_glFlush);
954848b8605Smrg#endif
955848b8605Smrg   }
956848b8605Smrg   return table;
957848b8605Smrg}
958848b8605Smrg
959848b8605Smrg/**
960848b8605Smrg * Creates a minimal dispatch table for use within glBegin()/glEnd().
961848b8605Smrg *
962848b8605Smrg * This ensures that we generate GL_INVALID_OPERATION errors from most
963848b8605Smrg * functions, since the set of functions that are valid within Begin/End is
964848b8605Smrg * very small.
965848b8605Smrg *
966848b8605Smrg * From the GL 1.0 specification section 2.6.3, "GL Commands within
967848b8605Smrg * Begin/End"
968848b8605Smrg *
969848b8605Smrg *     "The only GL commands that are allowed within any Begin/End pairs are
970848b8605Smrg *      the commands for specifying vertex coordinates, vertex color, normal
971848b8605Smrg *      coordinates, and texture coordinates (Vertex, Color, Index, Normal,
972848b8605Smrg *      TexCoord), EvalCoord and EvalPoint commands (see section 5.1),
973848b8605Smrg *      commands for specifying lighting material parameters (Material
974848b8605Smrg *      commands see section 2.12.2), display list invocation commands
975848b8605Smrg *      (CallList and CallLists see section 5.4), and the EdgeFlag
976848b8605Smrg *      command. Executing Begin after Begin has already been executed but
977848b8605Smrg *      before an End is issued generates the INVALID OPERATION error, as does
978848b8605Smrg *      executing End without a previous corresponding Begin. Executing any
979848b8605Smrg *      other GL command within Begin/End results in the error INVALID
980848b8605Smrg *      OPERATION."
981848b8605Smrg *
982848b8605Smrg * The table entries for specifying vertex attributes are set up by
983848b8605Smrg * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists
984848b8605Smrg * are set by install_vtxfmt() as well.
985848b8605Smrg */
986848b8605Smrgstatic struct _glapi_table *
987848b8605Smrgcreate_beginend_table(const struct gl_context *ctx)
988848b8605Smrg{
989848b8605Smrg   struct _glapi_table *table;
990848b8605Smrg
991848b8605Smrg   table = _mesa_alloc_dispatch_table();
992848b8605Smrg   if (!table)
993848b8605Smrg      return NULL;
994848b8605Smrg
995848b8605Smrg   /* Fill in functions which return a value, since they should return some
996848b8605Smrg    * specific value even if they emit a GL_INVALID_OPERATION error from them
997848b8605Smrg    * being called within glBegin()/glEnd().
998848b8605Smrg    */
999848b8605Smrg#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec))
1000848b8605Smrg
1001848b8605Smrg   COPY_DISPATCH(GenLists);
1002848b8605Smrg   COPY_DISPATCH(IsProgram);
1003848b8605Smrg   COPY_DISPATCH(IsVertexArray);
1004848b8605Smrg   COPY_DISPATCH(IsBuffer);
1005848b8605Smrg   COPY_DISPATCH(IsEnabled);
1006848b8605Smrg   COPY_DISPATCH(IsEnabledi);
1007848b8605Smrg   COPY_DISPATCH(IsRenderbuffer);
1008848b8605Smrg   COPY_DISPATCH(IsFramebuffer);
1009848b8605Smrg   COPY_DISPATCH(CheckFramebufferStatus);
1010848b8605Smrg   COPY_DISPATCH(RenderMode);
1011848b8605Smrg   COPY_DISPATCH(GetString);
1012848b8605Smrg   COPY_DISPATCH(GetStringi);
1013848b8605Smrg   COPY_DISPATCH(GetPointerv);
1014848b8605Smrg   COPY_DISPATCH(IsQuery);
1015848b8605Smrg   COPY_DISPATCH(IsSampler);
1016848b8605Smrg   COPY_DISPATCH(IsSync);
1017848b8605Smrg   COPY_DISPATCH(IsTexture);
1018848b8605Smrg   COPY_DISPATCH(IsTransformFeedback);
1019848b8605Smrg   COPY_DISPATCH(DeleteQueries);
1020848b8605Smrg   COPY_DISPATCH(AreTexturesResident);
1021848b8605Smrg   COPY_DISPATCH(FenceSync);
1022848b8605Smrg   COPY_DISPATCH(ClientWaitSync);
1023848b8605Smrg   COPY_DISPATCH(MapBuffer);
1024848b8605Smrg   COPY_DISPATCH(UnmapBuffer);
1025848b8605Smrg   COPY_DISPATCH(MapBufferRange);
1026848b8605Smrg   COPY_DISPATCH(ObjectPurgeableAPPLE);
1027848b8605Smrg   COPY_DISPATCH(ObjectUnpurgeableAPPLE);
1028848b8605Smrg
1029848b8605Smrg   _mesa_loopback_init_api_table(ctx, table);
1030848b8605Smrg
1031848b8605Smrg   return table;
1032848b8605Smrg}
1033848b8605Smrg
1034848b8605Smrgvoid
1035848b8605Smrg_mesa_initialize_dispatch_tables(struct gl_context *ctx)
1036848b8605Smrg{
1037848b8605Smrg   /* Do the code-generated setup of the exec table in api_exec.c. */
1038848b8605Smrg   _mesa_initialize_exec_table(ctx);
1039848b8605Smrg
1040848b8605Smrg   if (ctx->Save)
1041848b8605Smrg      _mesa_initialize_save_table(ctx);
1042848b8605Smrg}
1043848b8605Smrg
1044848b8605Smrg/**
1045848b8605Smrg * Initialize a struct gl_context struct (rendering context).
1046848b8605Smrg *
1047848b8605Smrg * This includes allocating all the other structs and arrays which hang off of
1048848b8605Smrg * the context by pointers.
1049848b8605Smrg * Note that the driver needs to pass in its dd_function_table here since
1050848b8605Smrg * we need to at least call driverFunctions->NewTextureObject to create the
1051848b8605Smrg * default texture objects.
1052848b8605Smrg *
1053848b8605Smrg * Called by _mesa_create_context().
1054848b8605Smrg *
1055848b8605Smrg * Performs the imports and exports callback tables initialization, and
1056848b8605Smrg * miscellaneous one-time initializations. If no shared context is supplied one
1057848b8605Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
1058848b8605Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
1059848b8605Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
1060848b8605Smrg * for debug flags.
1061848b8605Smrg *
1062848b8605Smrg * \param ctx the context to initialize
1063848b8605Smrg * \param api the GL API type to create the context for
1064848b8605Smrg * \param visual describes the visual attributes for this context or NULL to
1065848b8605Smrg *               create a configless context
1066848b8605Smrg * \param share_list points to context to share textures, display lists,
1067848b8605Smrg *        etc with, or NULL
1068848b8605Smrg * \param driverFunctions table of device driver functions for this context
1069848b8605Smrg *        to use
1070848b8605Smrg */
1071848b8605SmrgGLboolean
1072848b8605Smrg_mesa_initialize_context(struct gl_context *ctx,
1073848b8605Smrg                         gl_api api,
1074848b8605Smrg                         const struct gl_config *visual,
1075848b8605Smrg                         struct gl_context *share_list,
1076848b8605Smrg                         const struct dd_function_table *driverFunctions)
1077848b8605Smrg{
1078848b8605Smrg   struct gl_shared_state *shared;
1079848b8605Smrg   int i;
1080848b8605Smrg
1081848b8605Smrg   assert(driverFunctions->NewTextureObject);
1082848b8605Smrg   assert(driverFunctions->FreeTextureImageBuffer);
1083848b8605Smrg
1084848b8605Smrg   ctx->API = api;
1085848b8605Smrg   ctx->DrawBuffer = NULL;
1086848b8605Smrg   ctx->ReadBuffer = NULL;
1087848b8605Smrg   ctx->WinSysDrawBuffer = NULL;
1088848b8605Smrg   ctx->WinSysReadBuffer = NULL;
1089848b8605Smrg
1090848b8605Smrg   if (visual) {
1091848b8605Smrg      ctx->Visual = *visual;
1092848b8605Smrg      ctx->HasConfig = GL_TRUE;
1093848b8605Smrg   }
1094848b8605Smrg   else {
1095848b8605Smrg      memset(&ctx->Visual, 0, sizeof ctx->Visual);
1096848b8605Smrg      ctx->HasConfig = GL_FALSE;
1097848b8605Smrg   }
1098848b8605Smrg
1099848b8605Smrg   if (_mesa_is_desktop_gl(ctx)) {
1100848b8605Smrg      _mesa_override_gl_version(ctx);
1101848b8605Smrg   }
1102848b8605Smrg
1103848b8605Smrg   /* misc one-time initializations */
1104848b8605Smrg   one_time_init(ctx);
1105848b8605Smrg
1106848b8605Smrg   /* Plug in driver functions and context pointer here.
1107848b8605Smrg    * This is important because when we call alloc_shared_state() below
1108848b8605Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
1109848b8605Smrg    * textures.
1110848b8605Smrg    */
1111848b8605Smrg   ctx->Driver = *driverFunctions;
1112848b8605Smrg
1113848b8605Smrg   if (share_list) {
1114848b8605Smrg      /* share state with another context */
1115848b8605Smrg      shared = share_list->Shared;
1116848b8605Smrg   }
1117848b8605Smrg   else {
1118848b8605Smrg      /* allocate new, unshared state */
1119848b8605Smrg      shared = _mesa_alloc_shared_state(ctx);
1120848b8605Smrg      if (!shared)
1121848b8605Smrg         return GL_FALSE;
1122848b8605Smrg   }
1123848b8605Smrg
1124848b8605Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
1125848b8605Smrg
1126848b8605Smrg   if (!init_attrib_groups( ctx ))
1127848b8605Smrg      goto fail;
1128848b8605Smrg
1129848b8605Smrg   /* setup the API dispatch tables with all nop functions */
1130848b8605Smrg   ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table();
1131848b8605Smrg   if (!ctx->OutsideBeginEnd)
1132848b8605Smrg      goto fail;
1133848b8605Smrg   ctx->Exec = ctx->OutsideBeginEnd;
1134848b8605Smrg   ctx->CurrentDispatch = ctx->OutsideBeginEnd;
1135848b8605Smrg
1136848b8605Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
1137848b8605Smrg      = (_mesa_getenv("MESA_TEX_PROG") != NULL);
1138848b8605Smrg
1139848b8605Smrg   ctx->VertexProgram._MaintainTnlProgram
1140848b8605Smrg      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
1141848b8605Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
1142848b8605Smrg      /* this is required... */
1143848b8605Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
1144848b8605Smrg   }
1145848b8605Smrg
1146848b8605Smrg   /* Mesa core handles all the formats that mesa core knows about.
1147848b8605Smrg    * Drivers will want to override this list with just the formats
1148848b8605Smrg    * they can handle, and confirm that appropriate fallbacks exist in
1149848b8605Smrg    * _mesa_choose_tex_format().
1150848b8605Smrg    */
1151848b8605Smrg   memset(&ctx->TextureFormatSupported, GL_TRUE,
1152848b8605Smrg	  sizeof(ctx->TextureFormatSupported));
1153848b8605Smrg
1154848b8605Smrg   switch (ctx->API) {
1155848b8605Smrg   case API_OPENGL_COMPAT:
1156848b8605Smrg      ctx->BeginEnd = create_beginend_table(ctx);
1157848b8605Smrg      ctx->Save = _mesa_alloc_dispatch_table();
1158848b8605Smrg      if (!ctx->BeginEnd || !ctx->Save)
1159848b8605Smrg         goto fail;
1160848b8605Smrg
1161848b8605Smrg      /* fall-through */
1162848b8605Smrg   case API_OPENGL_CORE:
1163848b8605Smrg      break;
1164848b8605Smrg   case API_OPENGLES:
1165848b8605Smrg      /**
1166848b8605Smrg       * GL_OES_texture_cube_map says
1167848b8605Smrg       * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
1168848b8605Smrg       */
1169848b8605Smrg      for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1170848b8605Smrg	 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
1171848b8605Smrg	 texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
1172848b8605Smrg	 texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
1173848b8605Smrg	 texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
1174848b8605Smrg	 texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
1175848b8605Smrg	 texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
1176848b8605Smrg	 texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
1177848b8605Smrg      }
1178848b8605Smrg      break;
1179848b8605Smrg   case API_OPENGLES2:
1180848b8605Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
1181848b8605Smrg      ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
1182848b8605Smrg      break;
1183848b8605Smrg   }
1184848b8605Smrg
1185848b8605Smrg   ctx->FirstTimeCurrent = GL_TRUE;
1186848b8605Smrg
1187848b8605Smrg   return GL_TRUE;
1188848b8605Smrg
1189848b8605Smrgfail:
1190848b8605Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
1191848b8605Smrg   free(ctx->BeginEnd);
1192848b8605Smrg   free(ctx->OutsideBeginEnd);
1193848b8605Smrg   free(ctx->Save);
1194848b8605Smrg   return GL_FALSE;
1195848b8605Smrg}
1196848b8605Smrg
1197848b8605Smrg
1198848b8605Smrg/**
1199848b8605Smrg * Allocate and initialize a struct gl_context structure.
1200848b8605Smrg * Note that the driver needs to pass in its dd_function_table here since
1201848b8605Smrg * we need to at least call driverFunctions->NewTextureObject to initialize
1202848b8605Smrg * the rendering context.
1203848b8605Smrg *
1204848b8605Smrg * \param api the GL API type to create the context for
1205848b8605Smrg * \param visual a struct gl_config pointer (we copy the struct contents) or
1206848b8605Smrg *               NULL to create a configless context
1207848b8605Smrg * \param share_list another context to share display lists with or NULL
1208848b8605Smrg * \param driverFunctions points to the dd_function_table into which the
1209848b8605Smrg *        driver has plugged in all its special functions.
1210848b8605Smrg *
1211848b8605Smrg * \return pointer to a new __struct gl_contextRec or NULL if error.
1212848b8605Smrg */
1213848b8605Smrgstruct gl_context *
1214848b8605Smrg_mesa_create_context(gl_api api,
1215848b8605Smrg                     const struct gl_config *visual,
1216848b8605Smrg                     struct gl_context *share_list,
1217848b8605Smrg                     const struct dd_function_table *driverFunctions)
1218848b8605Smrg{
1219848b8605Smrg   struct gl_context *ctx;
1220848b8605Smrg
1221848b8605Smrg   ctx = calloc(1, sizeof(struct gl_context));
1222848b8605Smrg   if (!ctx)
1223848b8605Smrg      return NULL;
1224848b8605Smrg
1225848b8605Smrg   if (_mesa_initialize_context(ctx, api, visual, share_list,
1226848b8605Smrg                                driverFunctions)) {
1227848b8605Smrg      return ctx;
1228848b8605Smrg   }
1229848b8605Smrg   else {
1230848b8605Smrg      free(ctx);
1231848b8605Smrg      return NULL;
1232848b8605Smrg   }
1233848b8605Smrg}
1234848b8605Smrg
1235848b8605Smrg
1236848b8605Smrg/**
1237848b8605Smrg * Free the data associated with the given context.
1238848b8605Smrg *
1239848b8605Smrg * But doesn't free the struct gl_context struct itself.
1240848b8605Smrg *
1241848b8605Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
1242848b8605Smrg */
1243848b8605Smrgvoid
1244848b8605Smrg_mesa_free_context_data( struct gl_context *ctx )
1245848b8605Smrg{
1246848b8605Smrg   if (!_mesa_get_current_context()){
1247848b8605Smrg      /* No current context, but we may need one in order to delete
1248848b8605Smrg       * texture objs, etc.  So temporarily bind the context now.
1249848b8605Smrg       */
1250848b8605Smrg      _mesa_make_current(ctx, NULL, NULL);
1251848b8605Smrg   }
1252848b8605Smrg
1253848b8605Smrg   /* unreference WinSysDraw/Read buffers */
1254848b8605Smrg   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
1255848b8605Smrg   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
1256848b8605Smrg   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
1257848b8605Smrg   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
1258848b8605Smrg
1259848b8605Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
1260848b8605Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
1261848b8605Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1262848b8605Smrg
1263848b8605Smrg   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
1264848b8605Smrg   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
1265848b8605Smrg
1266848b8605Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
1267848b8605Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
1268848b8605Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
1269848b8605Smrg
1270848b8605Smrg   _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
1271848b8605Smrg   _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
1272848b8605Smrg
1273848b8605Smrg   _mesa_free_attrib_data(ctx);
1274848b8605Smrg   _mesa_free_buffer_objects(ctx);
1275848b8605Smrg   _mesa_free_lighting_data( ctx );
1276848b8605Smrg   _mesa_free_eval_data( ctx );
1277848b8605Smrg   _mesa_free_texture_data( ctx );
1278848b8605Smrg   _mesa_free_matrix_data( ctx );
1279848b8605Smrg   _mesa_free_viewport_data( ctx );
1280848b8605Smrg   _mesa_free_pipeline_data(ctx);
1281848b8605Smrg   _mesa_free_program_data(ctx);
1282848b8605Smrg   _mesa_free_shader_state(ctx);
1283848b8605Smrg   _mesa_free_queryobj_data(ctx);
1284848b8605Smrg   _mesa_free_sync_data(ctx);
1285848b8605Smrg   _mesa_free_varray_data(ctx);
1286848b8605Smrg   _mesa_free_transform_feedback(ctx);
1287848b8605Smrg   _mesa_free_performance_monitors(ctx);
1288848b8605Smrg
1289848b8605Smrg   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
1290848b8605Smrg   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
1291848b8605Smrg   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
1292848b8605Smrg   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
1293848b8605Smrg
1294848b8605Smrg   /* free dispatch tables */
1295848b8605Smrg   free(ctx->BeginEnd);
1296848b8605Smrg   free(ctx->OutsideBeginEnd);
1297848b8605Smrg   free(ctx->Save);
1298848b8605Smrg
1299848b8605Smrg   /* Shared context state (display lists, textures, etc) */
1300848b8605Smrg   _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
1301848b8605Smrg
1302848b8605Smrg   /* needs to be after freeing shared state */
1303848b8605Smrg   _mesa_free_display_list_data(ctx);
1304848b8605Smrg
1305848b8605Smrg   _mesa_free_errors_data(ctx);
1306848b8605Smrg
1307848b8605Smrg   free((void *)ctx->Extensions.String);
1308848b8605Smrg
1309848b8605Smrg   free(ctx->VersionString);
1310848b8605Smrg
1311848b8605Smrg   /* unbind the context if it's currently bound */
1312848b8605Smrg   if (ctx == _mesa_get_current_context()) {
1313848b8605Smrg      _mesa_make_current(NULL, NULL, NULL);
1314848b8605Smrg   }
1315848b8605Smrg}
1316848b8605Smrg
1317848b8605Smrg
1318848b8605Smrg/**
1319848b8605Smrg * Destroy a struct gl_context structure.
1320848b8605Smrg *
1321848b8605Smrg * \param ctx GL context.
1322848b8605Smrg *
1323848b8605Smrg * Calls _mesa_free_context_data() and frees the gl_context object itself.
1324848b8605Smrg */
1325848b8605Smrgvoid
1326848b8605Smrg_mesa_destroy_context( struct gl_context *ctx )
1327848b8605Smrg{
1328848b8605Smrg   if (ctx) {
1329848b8605Smrg      _mesa_free_context_data(ctx);
1330848b8605Smrg      free( (void *) ctx );
1331848b8605Smrg   }
1332848b8605Smrg}
1333848b8605Smrg
1334848b8605Smrg
1335848b8605Smrg/**
1336848b8605Smrg * Copy attribute groups from one context to another.
1337848b8605Smrg *
1338848b8605Smrg * \param src source context
1339848b8605Smrg * \param dst destination context
1340848b8605Smrg * \param mask bitwise OR of GL_*_BIT flags
1341848b8605Smrg *
1342848b8605Smrg * According to the bits specified in \p mask, copies the corresponding
1343848b8605Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
1344848b8605Smrg * memcpy is not enough due to the existence of internal pointers in their data
1345848b8605Smrg * structures.
1346848b8605Smrg */
1347848b8605Smrgvoid
1348848b8605Smrg_mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
1349848b8605Smrg                    GLuint mask )
1350848b8605Smrg{
1351848b8605Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
1352848b8605Smrg      /* OK to memcpy */
1353848b8605Smrg      dst->Accum = src->Accum;
1354848b8605Smrg   }
1355848b8605Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
1356848b8605Smrg      /* OK to memcpy */
1357848b8605Smrg      dst->Color = src->Color;
1358848b8605Smrg   }
1359848b8605Smrg   if (mask & GL_CURRENT_BIT) {
1360848b8605Smrg      /* OK to memcpy */
1361848b8605Smrg      dst->Current = src->Current;
1362848b8605Smrg   }
1363848b8605Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
1364848b8605Smrg      /* OK to memcpy */
1365848b8605Smrg      dst->Depth = src->Depth;
1366848b8605Smrg   }
1367848b8605Smrg   if (mask & GL_ENABLE_BIT) {
1368848b8605Smrg      /* no op */
1369848b8605Smrg   }
1370848b8605Smrg   if (mask & GL_EVAL_BIT) {
1371848b8605Smrg      /* OK to memcpy */
1372848b8605Smrg      dst->Eval = src->Eval;
1373848b8605Smrg   }
1374848b8605Smrg   if (mask & GL_FOG_BIT) {
1375848b8605Smrg      /* OK to memcpy */
1376848b8605Smrg      dst->Fog = src->Fog;
1377848b8605Smrg   }
1378848b8605Smrg   if (mask & GL_HINT_BIT) {
1379848b8605Smrg      /* OK to memcpy */
1380848b8605Smrg      dst->Hint = src->Hint;
1381848b8605Smrg   }
1382848b8605Smrg   if (mask & GL_LIGHTING_BIT) {
1383848b8605Smrg      GLuint i;
1384848b8605Smrg      /* begin with memcpy */
1385848b8605Smrg      dst->Light = src->Light;
1386848b8605Smrg      /* fixup linked lists to prevent pointer insanity */
1387848b8605Smrg      make_empty_list( &(dst->Light.EnabledList) );
1388848b8605Smrg      for (i = 0; i < MAX_LIGHTS; i++) {
1389848b8605Smrg         if (dst->Light.Light[i].Enabled) {
1390848b8605Smrg            insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
1391848b8605Smrg         }
1392848b8605Smrg      }
1393848b8605Smrg   }
1394848b8605Smrg   if (mask & GL_LINE_BIT) {
1395848b8605Smrg      /* OK to memcpy */
1396848b8605Smrg      dst->Line = src->Line;
1397848b8605Smrg   }
1398848b8605Smrg   if (mask & GL_LIST_BIT) {
1399848b8605Smrg      /* OK to memcpy */
1400848b8605Smrg      dst->List = src->List;
1401848b8605Smrg   }
1402848b8605Smrg   if (mask & GL_PIXEL_MODE_BIT) {
1403848b8605Smrg      /* OK to memcpy */
1404848b8605Smrg      dst->Pixel = src->Pixel;
1405848b8605Smrg   }
1406848b8605Smrg   if (mask & GL_POINT_BIT) {
1407848b8605Smrg      /* OK to memcpy */
1408848b8605Smrg      dst->Point = src->Point;
1409848b8605Smrg   }
1410848b8605Smrg   if (mask & GL_POLYGON_BIT) {
1411848b8605Smrg      /* OK to memcpy */
1412848b8605Smrg      dst->Polygon = src->Polygon;
1413848b8605Smrg   }
1414848b8605Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
1415848b8605Smrg      /* Use loop instead of memcpy due to problem with Portland Group's
1416848b8605Smrg       * C compiler.  Reported by John Stone.
1417848b8605Smrg       */
1418848b8605Smrg      GLuint i;
1419848b8605Smrg      for (i = 0; i < 32; i++) {
1420848b8605Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
1421848b8605Smrg      }
1422848b8605Smrg   }
1423848b8605Smrg   if (mask & GL_SCISSOR_BIT) {
1424848b8605Smrg      /* OK to memcpy */
1425848b8605Smrg      dst->Scissor = src->Scissor;
1426848b8605Smrg   }
1427848b8605Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
1428848b8605Smrg      /* OK to memcpy */
1429848b8605Smrg      dst->Stencil = src->Stencil;
1430848b8605Smrg   }
1431848b8605Smrg   if (mask & GL_TEXTURE_BIT) {
1432848b8605Smrg      /* Cannot memcpy because of pointers */
1433848b8605Smrg      _mesa_copy_texture_state(src, dst);
1434848b8605Smrg   }
1435848b8605Smrg   if (mask & GL_TRANSFORM_BIT) {
1436848b8605Smrg      /* OK to memcpy */
1437848b8605Smrg      dst->Transform = src->Transform;
1438848b8605Smrg   }
1439848b8605Smrg   if (mask & GL_VIEWPORT_BIT) {
1440848b8605Smrg      /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1441848b8605Smrg      unsigned i;
1442848b8605Smrg      for (i = 0; i < src->Const.MaxViewports; i++) {
1443848b8605Smrg         dst->ViewportArray[i].X = src->ViewportArray[i].X;
1444848b8605Smrg         dst->ViewportArray[i].Y = src->ViewportArray[i].Y;
1445848b8605Smrg         dst->ViewportArray[i].Width = src->ViewportArray[i].Width;
1446848b8605Smrg         dst->ViewportArray[i].Height = src->ViewportArray[i].Height;
1447848b8605Smrg         dst->ViewportArray[i].Near = src->ViewportArray[i].Near;
1448848b8605Smrg         dst->ViewportArray[i].Far = src->ViewportArray[i].Far;
1449848b8605Smrg         _math_matrix_copy(&dst->ViewportArray[i]._WindowMap,
1450848b8605Smrg                           &src->ViewportArray[i]._WindowMap);
1451848b8605Smrg      }
1452848b8605Smrg   }
1453848b8605Smrg
1454848b8605Smrg   /* XXX FIXME:  Call callbacks?
1455848b8605Smrg    */
1456848b8605Smrg   dst->NewState = _NEW_ALL;
1457848b8605Smrg   dst->NewDriverState = ~0;
1458848b8605Smrg}
1459848b8605Smrg
1460848b8605Smrg
1461848b8605Smrg/**
1462848b8605Smrg * Check if the given context can render into the given framebuffer
1463848b8605Smrg * by checking visual attributes.
1464848b8605Smrg *
1465848b8605Smrg * Most of these tests could go away because Mesa is now pretty flexible
1466848b8605Smrg * in terms of mixing rendering contexts with framebuffers.  As long
1467848b8605Smrg * as RGB vs. CI mode agree, we're probably good.
1468848b8605Smrg *
1469848b8605Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
1470848b8605Smrg */
1471848b8605Smrgstatic GLboolean
1472848b8605Smrgcheck_compatible(const struct gl_context *ctx,
1473848b8605Smrg                 const struct gl_framebuffer *buffer)
1474848b8605Smrg{
1475848b8605Smrg   const struct gl_config *ctxvis = &ctx->Visual;
1476848b8605Smrg   const struct gl_config *bufvis = &buffer->Visual;
1477848b8605Smrg
1478848b8605Smrg   if (buffer == _mesa_get_incomplete_framebuffer())
1479848b8605Smrg      return GL_TRUE;
1480848b8605Smrg
1481848b8605Smrg#if 0
1482848b8605Smrg   /* disabling this fixes the fgl_glxgears pbuffer demo */
1483848b8605Smrg   if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
1484848b8605Smrg      return GL_FALSE;
1485848b8605Smrg#endif
1486848b8605Smrg   if (ctxvis->stereoMode && !bufvis->stereoMode)
1487848b8605Smrg      return GL_FALSE;
1488848b8605Smrg   if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
1489848b8605Smrg      return GL_FALSE;
1490848b8605Smrg   if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
1491848b8605Smrg      return GL_FALSE;
1492848b8605Smrg   if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
1493848b8605Smrg      return GL_FALSE;
1494848b8605Smrg   if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
1495848b8605Smrg      return GL_FALSE;
1496848b8605Smrg   if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
1497848b8605Smrg      return GL_FALSE;
1498848b8605Smrg   if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
1499848b8605Smrg      return GL_FALSE;
1500848b8605Smrg#if 0
1501848b8605Smrg   /* disabled (see bug 11161) */
1502848b8605Smrg   if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
1503848b8605Smrg      return GL_FALSE;
1504848b8605Smrg#endif
1505848b8605Smrg   if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
1506848b8605Smrg      return GL_FALSE;
1507848b8605Smrg
1508848b8605Smrg   return GL_TRUE;
1509848b8605Smrg}
1510848b8605Smrg
1511848b8605Smrg
1512848b8605Smrg/**
1513848b8605Smrg * Check if the viewport/scissor size has not yet been initialized.
1514848b8605Smrg * Initialize the size if the given width and height are non-zero.
1515848b8605Smrg */
1516848b8605Smrgvoid
1517848b8605Smrg_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
1518848b8605Smrg{
1519848b8605Smrg   if (!ctx->ViewportInitialized && width > 0 && height > 0) {
1520848b8605Smrg      unsigned i;
1521848b8605Smrg
1522848b8605Smrg      /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
1523848b8605Smrg       * potential infinite recursion.
1524848b8605Smrg       */
1525848b8605Smrg      ctx->ViewportInitialized = GL_TRUE;
1526848b8605Smrg
1527848b8605Smrg      /* Note: ctx->Const.MaxViewports may not have been set by the driver
1528848b8605Smrg       * yet, so just initialize all of them.
1529848b8605Smrg       */
1530848b8605Smrg      for (i = 0; i < MAX_VIEWPORTS; i++) {
1531848b8605Smrg         _mesa_set_viewport(ctx, i, 0, 0, width, height);
1532848b8605Smrg         _mesa_set_scissor(ctx, i, 0, 0, width, height);
1533848b8605Smrg      }
1534848b8605Smrg   }
1535848b8605Smrg}
1536848b8605Smrg
1537848b8605Smrgstatic void
1538848b8605Smrghandle_first_current(struct gl_context *ctx)
1539848b8605Smrg{
1540848b8605Smrg   GLenum buffer;
1541848b8605Smrg   GLint bufferIndex;
1542848b8605Smrg
1543848b8605Smrg   assert(ctx->Version > 0);
1544848b8605Smrg
1545848b8605Smrg   ctx->Extensions.String = _mesa_make_extension_string(ctx);
1546848b8605Smrg
1547848b8605Smrg   check_context_limits(ctx);
1548848b8605Smrg
1549848b8605Smrg   /* According to GL_MESA_configless_context the default value of
1550848b8605Smrg    * glDrawBuffers depends on the config of the first surface it is bound to.
1551848b8605Smrg    * For GLES it is always GL_BACK which has a magic interpretation */
1552848b8605Smrg   if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) {
1553848b8605Smrg      if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) {
1554848b8605Smrg         if (ctx->DrawBuffer->Visual.doubleBufferMode)
1555848b8605Smrg            buffer = GL_BACK;
1556848b8605Smrg         else
1557848b8605Smrg            buffer = GL_FRONT;
1558848b8605Smrg
1559848b8605Smrg         _mesa_drawbuffers(ctx, 1, &buffer, NULL /* destMask */);
1560848b8605Smrg      }
1561848b8605Smrg
1562848b8605Smrg      if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) {
1563848b8605Smrg         if (ctx->ReadBuffer->Visual.doubleBufferMode) {
1564848b8605Smrg            buffer = GL_BACK;
1565848b8605Smrg            bufferIndex = BUFFER_BACK_LEFT;
1566848b8605Smrg         }
1567848b8605Smrg         else {
1568848b8605Smrg            buffer = GL_FRONT;
1569848b8605Smrg            bufferIndex = BUFFER_FRONT_LEFT;
1570848b8605Smrg         }
1571848b8605Smrg
1572848b8605Smrg         _mesa_readbuffer(ctx, buffer, bufferIndex);
1573848b8605Smrg      }
1574848b8605Smrg   }
1575848b8605Smrg
1576848b8605Smrg   /* We can use this to help debug user's problems.  Tell them to set
1577848b8605Smrg    * the MESA_INFO env variable before running their app.  Then the
1578848b8605Smrg    * first time each context is made current we'll print some useful
1579848b8605Smrg    * information.
1580848b8605Smrg    */
1581848b8605Smrg   if (_mesa_getenv("MESA_INFO")) {
1582848b8605Smrg      _mesa_print_info(ctx);
1583848b8605Smrg   }
1584848b8605Smrg}
1585848b8605Smrg
1586848b8605Smrg/**
1587848b8605Smrg * Bind the given context to the given drawBuffer and readBuffer and
1588848b8605Smrg * make it the current context for the calling thread.
1589848b8605Smrg * We'll render into the drawBuffer and read pixels from the
1590848b8605Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
1591848b8605Smrg *
1592848b8605Smrg * We check that the context's and framebuffer's visuals are compatible
1593848b8605Smrg * and return immediately if they're not.
1594848b8605Smrg *
1595848b8605Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
1596848b8605Smrg *                context.
1597848b8605Smrg * \param drawBuffer  the drawing framebuffer
1598848b8605Smrg * \param readBuffer  the reading framebuffer
1599848b8605Smrg */
1600848b8605SmrgGLboolean
1601848b8605Smrg_mesa_make_current( struct gl_context *newCtx,
1602848b8605Smrg                    struct gl_framebuffer *drawBuffer,
1603848b8605Smrg                    struct gl_framebuffer *readBuffer )
1604848b8605Smrg{
1605848b8605Smrg   GET_CURRENT_CONTEXT(curCtx);
1606848b8605Smrg
1607848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
1608848b8605Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
1609848b8605Smrg
1610848b8605Smrg   /* Check that the context's and framebuffer's visuals are compatible.
1611848b8605Smrg    */
1612848b8605Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
1613848b8605Smrg      if (!check_compatible(newCtx, drawBuffer)) {
1614848b8605Smrg         _mesa_warning(newCtx,
1615848b8605Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
1616848b8605Smrg         return GL_FALSE;
1617848b8605Smrg      }
1618848b8605Smrg   }
1619848b8605Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
1620848b8605Smrg      if (!check_compatible(newCtx, readBuffer)) {
1621848b8605Smrg         _mesa_warning(newCtx,
1622848b8605Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
1623848b8605Smrg         return GL_FALSE;
1624848b8605Smrg      }
1625848b8605Smrg   }
1626848b8605Smrg
1627848b8605Smrg   if (curCtx &&
1628848b8605Smrg      (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
1629848b8605Smrg       /* make sure this context is valid for flushing */
1630848b8605Smrg      curCtx != newCtx)
1631848b8605Smrg      _mesa_flush(curCtx);
1632848b8605Smrg
1633848b8605Smrg   /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
1634848b8605Smrg   _glapi_set_context((void *) newCtx);
1635848b8605Smrg   ASSERT(_mesa_get_current_context() == newCtx);
1636848b8605Smrg
1637848b8605Smrg   if (!newCtx) {
1638848b8605Smrg      _glapi_set_dispatch(NULL);  /* none current */
1639848b8605Smrg   }
1640848b8605Smrg   else {
1641848b8605Smrg      _glapi_set_dispatch(newCtx->CurrentDispatch);
1642848b8605Smrg
1643848b8605Smrg      if (drawBuffer && readBuffer) {
1644848b8605Smrg         ASSERT(_mesa_is_winsys_fbo(drawBuffer));
1645848b8605Smrg         ASSERT(_mesa_is_winsys_fbo(readBuffer));
1646848b8605Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
1647848b8605Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
1648848b8605Smrg
1649848b8605Smrg         /*
1650848b8605Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
1651848b8605Smrg          * or not bound to a user-created FBO.
1652848b8605Smrg          */
1653848b8605Smrg         if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) {
1654848b8605Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
1655848b8605Smrg            /* Update the FBO's list of drawbuffers/renderbuffers.
1656848b8605Smrg             * For winsys FBOs this comes from the GL state (which may have
1657848b8605Smrg             * changed since the last time this FBO was bound).
1658848b8605Smrg             */
1659848b8605Smrg            _mesa_update_draw_buffers(newCtx);
1660848b8605Smrg         }
1661848b8605Smrg         if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) {
1662848b8605Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
1663848b8605Smrg         }
1664848b8605Smrg
1665848b8605Smrg         /* XXX only set this flag if we're really changing the draw/read
1666848b8605Smrg          * framebuffer bindings.
1667848b8605Smrg          */
1668848b8605Smrg	 newCtx->NewState |= _NEW_BUFFERS;
1669848b8605Smrg
1670848b8605Smrg         if (drawBuffer) {
1671848b8605Smrg            _mesa_check_init_viewport(newCtx,
1672848b8605Smrg                                      drawBuffer->Width, drawBuffer->Height);
1673848b8605Smrg         }
1674848b8605Smrg      }
1675848b8605Smrg
1676848b8605Smrg      if (newCtx->FirstTimeCurrent) {
1677848b8605Smrg         handle_first_current(newCtx);
1678848b8605Smrg	 newCtx->FirstTimeCurrent = GL_FALSE;
1679848b8605Smrg      }
1680848b8605Smrg   }
1681848b8605Smrg
1682848b8605Smrg   return GL_TRUE;
1683848b8605Smrg}
1684848b8605Smrg
1685848b8605Smrg
1686848b8605Smrg/**
1687848b8605Smrg * Make context 'ctx' share the display lists, textures and programs
1688848b8605Smrg * that are associated with 'ctxToShare'.
1689848b8605Smrg * Any display lists, textures or programs associated with 'ctx' will
1690848b8605Smrg * be deleted if nobody else is sharing them.
1691848b8605Smrg */
1692848b8605SmrgGLboolean
1693848b8605Smrg_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
1694848b8605Smrg{
1695848b8605Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
1696848b8605Smrg      struct gl_shared_state *oldShared = NULL;
1697848b8605Smrg
1698848b8605Smrg      /* save ref to old state to prevent it from being deleted immediately */
1699848b8605Smrg      _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
1700848b8605Smrg
1701848b8605Smrg      /* update ctx's Shared pointer */
1702848b8605Smrg      _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
1703848b8605Smrg
1704848b8605Smrg      update_default_objects(ctx);
1705848b8605Smrg
1706848b8605Smrg      /* release the old shared state */
1707848b8605Smrg      _mesa_reference_shared_state(ctx, &oldShared, NULL);
1708848b8605Smrg
1709848b8605Smrg      return GL_TRUE;
1710848b8605Smrg   }
1711848b8605Smrg   else {
1712848b8605Smrg      return GL_FALSE;
1713848b8605Smrg   }
1714848b8605Smrg}
1715848b8605Smrg
1716848b8605Smrg
1717848b8605Smrg
1718848b8605Smrg/**
1719848b8605Smrg * \return pointer to the current GL context for this thread.
1720848b8605Smrg *
1721848b8605Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
1722848b8605Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
1723848b8605Smrg * context.h.
1724848b8605Smrg */
1725848b8605Smrgstruct gl_context *
1726848b8605Smrg_mesa_get_current_context( void )
1727848b8605Smrg{
1728848b8605Smrg   return (struct gl_context *) _glapi_get_context();
1729848b8605Smrg}
1730848b8605Smrg
1731848b8605Smrg
1732848b8605Smrg/**
1733848b8605Smrg * Get context's current API dispatch table.
1734848b8605Smrg *
1735848b8605Smrg * It'll either be the immediate-mode execute dispatcher or the display list
1736848b8605Smrg * compile dispatcher.
1737848b8605Smrg *
1738848b8605Smrg * \param ctx GL context.
1739848b8605Smrg *
1740848b8605Smrg * \return pointer to dispatch_table.
1741848b8605Smrg *
1742848b8605Smrg * Simply returns __struct gl_contextRec::CurrentDispatch.
1743848b8605Smrg */
1744848b8605Smrgstruct _glapi_table *
1745848b8605Smrg_mesa_get_dispatch(struct gl_context *ctx)
1746848b8605Smrg{
1747848b8605Smrg   return ctx->CurrentDispatch;
1748848b8605Smrg}
1749848b8605Smrg
1750848b8605Smrg/*@}*/
1751848b8605Smrg
1752848b8605Smrg
1753848b8605Smrg/**********************************************************************/
1754848b8605Smrg/** \name Miscellaneous functions                                     */
1755848b8605Smrg/**********************************************************************/
1756848b8605Smrg/*@{*/
1757848b8605Smrg
1758848b8605Smrg/**
1759848b8605Smrg * Record an error.
1760848b8605Smrg *
1761848b8605Smrg * \param ctx GL context.
1762848b8605Smrg * \param error error code.
1763848b8605Smrg *
1764848b8605Smrg * Records the given error code and call the driver's dd_function_table::Error
1765848b8605Smrg * function if defined.
1766848b8605Smrg *
1767848b8605Smrg * \sa
1768848b8605Smrg * This is called via _mesa_error().
1769848b8605Smrg */
1770848b8605Smrgvoid
1771848b8605Smrg_mesa_record_error(struct gl_context *ctx, GLenum error)
1772848b8605Smrg{
1773848b8605Smrg   if (!ctx)
1774848b8605Smrg      return;
1775848b8605Smrg
1776848b8605Smrg   if (ctx->ErrorValue == GL_NO_ERROR) {
1777848b8605Smrg      ctx->ErrorValue = error;
1778848b8605Smrg   }
1779848b8605Smrg}
1780848b8605Smrg
1781848b8605Smrg
1782848b8605Smrg/**
1783848b8605Smrg * Flush commands and wait for completion.
1784848b8605Smrg */
1785848b8605Smrgvoid
1786848b8605Smrg_mesa_finish(struct gl_context *ctx)
1787848b8605Smrg{
1788848b8605Smrg   FLUSH_VERTICES( ctx, 0 );
1789848b8605Smrg   FLUSH_CURRENT( ctx, 0 );
1790848b8605Smrg   if (ctx->Driver.Finish) {
1791848b8605Smrg      ctx->Driver.Finish(ctx);
1792848b8605Smrg   }
1793848b8605Smrg}
1794848b8605Smrg
1795848b8605Smrg
1796848b8605Smrg/**
1797848b8605Smrg * Flush commands.
1798848b8605Smrg */
1799848b8605Smrgvoid
1800848b8605Smrg_mesa_flush(struct gl_context *ctx)
1801848b8605Smrg{
1802848b8605Smrg   FLUSH_VERTICES( ctx, 0 );
1803848b8605Smrg   FLUSH_CURRENT( ctx, 0 );
1804848b8605Smrg   if (ctx->Driver.Flush) {
1805848b8605Smrg      ctx->Driver.Flush(ctx);
1806848b8605Smrg   }
1807848b8605Smrg}
1808848b8605Smrg
1809848b8605Smrg
1810848b8605Smrg
1811848b8605Smrg/**
1812848b8605Smrg * Execute glFinish().
1813848b8605Smrg *
1814848b8605Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1815848b8605Smrg * dd_function_table::Finish driver callback, if not NULL.
1816848b8605Smrg */
1817848b8605Smrgvoid GLAPIENTRY
1818848b8605Smrg_mesa_Finish(void)
1819848b8605Smrg{
1820848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1821848b8605Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1822848b8605Smrg   _mesa_finish(ctx);
1823848b8605Smrg}
1824848b8605Smrg
1825848b8605Smrg
1826848b8605Smrg/**
1827848b8605Smrg * Execute glFlush().
1828848b8605Smrg *
1829848b8605Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1830848b8605Smrg * dd_function_table::Flush driver callback, if not NULL.
1831848b8605Smrg */
1832848b8605Smrgvoid GLAPIENTRY
1833848b8605Smrg_mesa_Flush(void)
1834848b8605Smrg{
1835848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1836848b8605Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1837848b8605Smrg   _mesa_flush(ctx);
1838848b8605Smrg}
1839848b8605Smrg
1840848b8605Smrg
1841848b8605Smrg/*
1842848b8605Smrg * ARB_blend_func_extended - ERRORS section
1843848b8605Smrg * "The error INVALID_OPERATION is generated by Begin or any procedure that
1844848b8605Smrg *  implicitly calls Begin if any draw buffer has a blend function requiring the
1845848b8605Smrg *  second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or
1846848b8605Smrg *  ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than
1847848b8605Smrg *  the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements."
1848848b8605Smrg */
1849848b8605Smrgstatic GLboolean
1850848b8605Smrg_mesa_check_blend_func_error(struct gl_context *ctx)
1851848b8605Smrg{
1852848b8605Smrg   GLuint i;
1853848b8605Smrg   for (i = ctx->Const.MaxDualSourceDrawBuffers;
1854848b8605Smrg	i < ctx->DrawBuffer->_NumColorDrawBuffers;
1855848b8605Smrg	i++) {
1856848b8605Smrg      if (ctx->Color.Blend[i]._UsesDualSrc) {
1857848b8605Smrg	 _mesa_error(ctx, GL_INVALID_OPERATION,
1858848b8605Smrg		     "dual source blend on illegal attachment");
1859848b8605Smrg	 return GL_FALSE;
1860848b8605Smrg      }
1861848b8605Smrg   }
1862848b8605Smrg   return GL_TRUE;
1863848b8605Smrg}
1864848b8605Smrg
1865848b8605Smrgstatic bool
1866848b8605Smrgshader_linked_or_absent(struct gl_context *ctx,
1867848b8605Smrg                        const struct gl_shader_program *shProg,
1868848b8605Smrg                        bool *shader_present, const char *where)
1869848b8605Smrg{
1870848b8605Smrg   if (shProg) {
1871848b8605Smrg      *shader_present = true;
1872848b8605Smrg
1873848b8605Smrg      if (!shProg->LinkStatus) {
1874848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader not linked)", where);
1875848b8605Smrg         return false;
1876848b8605Smrg      }
1877848b8605Smrg#if 0 /* not normally enabled */
1878848b8605Smrg      {
1879848b8605Smrg         char errMsg[100];
1880848b8605Smrg         if (!_mesa_validate_shader_program(ctx, shProg, errMsg)) {
1881848b8605Smrg            _mesa_warning(ctx, "Shader program %u is invalid: %s",
1882848b8605Smrg                          shProg->Name, errMsg);
1883848b8605Smrg         }
1884848b8605Smrg      }
1885848b8605Smrg#endif
1886848b8605Smrg   }
1887848b8605Smrg
1888848b8605Smrg   return true;
1889848b8605Smrg}
1890848b8605Smrg
1891848b8605Smrg/**
1892848b8605Smrg * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
1893848b8605Smrg * is called to see if it's valid to render.  This involves checking that
1894848b8605Smrg * the current shader is valid and the framebuffer is complete.
1895848b8605Smrg * It also check the current pipeline object is valid if any.
1896848b8605Smrg * If an error is detected it'll be recorded here.
1897848b8605Smrg * \return GL_TRUE if OK to render, GL_FALSE if not
1898848b8605Smrg */
1899848b8605SmrgGLboolean
1900848b8605Smrg_mesa_valid_to_render(struct gl_context *ctx, const char *where)
1901848b8605Smrg{
1902848b8605Smrg   bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false };
1903848b8605Smrg   unsigned i;
1904848b8605Smrg
1905848b8605Smrg   /* This depends on having up to date derived state (shaders) */
1906848b8605Smrg   if (ctx->NewState)
1907848b8605Smrg      _mesa_update_state(ctx);
1908848b8605Smrg
1909848b8605Smrg   for (i = 0; i < MESA_SHADER_COMPUTE; i++) {
1910848b8605Smrg      if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i],
1911848b8605Smrg                                   &from_glsl_shader[i], where))
1912848b8605Smrg         return GL_FALSE;
1913848b8605Smrg   }
1914848b8605Smrg
1915848b8605Smrg   /* Any shader stages that are not supplied by the GLSL shader and have
1916848b8605Smrg    * assembly shaders enabled must now be validated.
1917848b8605Smrg    */
1918848b8605Smrg   if (!from_glsl_shader[MESA_SHADER_VERTEX]
1919848b8605Smrg       && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
1920848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
1921848b8605Smrg		  "%s(vertex program not valid)", where);
1922848b8605Smrg      return GL_FALSE;
1923848b8605Smrg   }
1924848b8605Smrg
1925848b8605Smrg   /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
1926848b8605Smrg    * FINISHME: geometry program should validated here.
1927848b8605Smrg    */
1928848b8605Smrg   (void) from_glsl_shader[MESA_SHADER_GEOMETRY];
1929848b8605Smrg
1930848b8605Smrg   if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) {
1931848b8605Smrg      if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
1932848b8605Smrg	 _mesa_error(ctx, GL_INVALID_OPERATION,
1933848b8605Smrg		     "%s(fragment program not valid)", where);
1934848b8605Smrg	 return GL_FALSE;
1935848b8605Smrg      }
1936848b8605Smrg
1937848b8605Smrg      /* If drawing to integer-valued color buffers, there must be an
1938848b8605Smrg       * active fragment shader (GL_EXT_texture_integer).
1939848b8605Smrg       */
1940848b8605Smrg      if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
1941848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
1942848b8605Smrg                     "%s(integer format but no fragment shader)", where);
1943848b8605Smrg         return GL_FALSE;
1944848b8605Smrg      }
1945848b8605Smrg   }
1946848b8605Smrg
1947848b8605Smrg   /* A pipeline object is bound */
1948848b8605Smrg   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
1949848b8605Smrg      /* Error message will be printed inside _mesa_validate_program_pipeline.
1950848b8605Smrg       */
1951848b8605Smrg      if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) {
1952848b8605Smrg         return GL_FALSE;
1953848b8605Smrg      }
1954848b8605Smrg   }
1955848b8605Smrg
1956848b8605Smrg   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1957848b8605Smrg      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1958848b8605Smrg                  "%s(incomplete framebuffer)", where);
1959848b8605Smrg      return GL_FALSE;
1960848b8605Smrg   }
1961848b8605Smrg
1962848b8605Smrg   if (_mesa_check_blend_func_error(ctx) == GL_FALSE) {
1963848b8605Smrg      return GL_FALSE;
1964848b8605Smrg   }
1965848b8605Smrg
1966848b8605Smrg#ifdef DEBUG
1967848b8605Smrg   if (ctx->_Shader->Flags & GLSL_LOG) {
1968848b8605Smrg      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
1969848b8605Smrg      gl_shader_stage i;
1970848b8605Smrg
1971848b8605Smrg      for (i = 0; i < MESA_SHADER_STAGES; i++) {
1972848b8605Smrg	 if (shProg[i] == NULL || shProg[i]->_Used
1973848b8605Smrg	     || shProg[i]->_LinkedShaders[i] == NULL)
1974848b8605Smrg	    continue;
1975848b8605Smrg
1976848b8605Smrg	 /* This is the first time this shader is being used.
1977848b8605Smrg	  * Append shader's constants/uniforms to log file.
1978848b8605Smrg	  *
1979848b8605Smrg	  * Only log data for the program target that matches the shader
1980848b8605Smrg	  * target.  It's possible to have a program bound to the vertex
1981848b8605Smrg	  * shader target that also supplied a fragment shader.  If that
1982848b8605Smrg	  * program isn't also bound to the fragment shader target we don't
1983848b8605Smrg	  * want to log its fragment data.
1984848b8605Smrg	  */
1985848b8605Smrg	 _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
1986848b8605Smrg      }
1987848b8605Smrg
1988848b8605Smrg      for (i = 0; i < MESA_SHADER_STAGES; i++) {
1989848b8605Smrg	 if (shProg[i] != NULL)
1990848b8605Smrg	    shProg[i]->_Used = GL_TRUE;
1991848b8605Smrg      }
1992848b8605Smrg   }
1993848b8605Smrg#endif
1994848b8605Smrg
1995848b8605Smrg   return GL_TRUE;
1996848b8605Smrg}
1997848b8605Smrg
1998848b8605Smrg
1999848b8605Smrg/*@}*/
2000