get.c revision 3a1ba094f45b3df9b5b4449fcac926b844aca7a4
1/*
2 * Copyright (C) 2010  Brian Paul   All Rights Reserved.
3 * Copyright (C) 2010  Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Kristian Høgsberg <krh@bitplanet.net>
23 */
24
25#include "glheader.h"
26#include "context.h"
27#include "enable.h"
28#include "enums.h"
29#include "extensions.h"
30#include "get.h"
31#include "macros.h"
32#include "mfeatures.h"
33#include "mtypes.h"
34#include "state.h"
35#include "texcompress.h"
36#include "framebuffer.h"
37
38/* This is a table driven implemetation of the glGet*v() functions.
39 * The basic idea is that most getters just look up an int somewhere
40 * in struct gl_context and then convert it to a bool or float according to
41 * which of glGetIntegerv() glGetBooleanv() etc is being called.
42 * Instead of generating code to do this, we can just record the enum
43 * value and the offset into struct gl_context in an array of structs.  Then
44 * in glGet*(), we lookup the struct for the enum in question, and use
45 * the offset to get the int we need.
46 *
47 * Sometimes we need to look up a float, a boolean, a bit in a
48 * bitfield, a matrix or other types instead, so we need to track the
49 * type of the value in struct gl_context.  And sometimes the value isn't in
50 * struct gl_context but in the drawbuffer, the array object, current texture
51 * unit, or maybe it's a computed value.  So we need to also track
52 * where or how to find the value.  Finally, we sometimes need to
53 * check that one of a number of extensions are enabled, the GL
54 * version or flush or call _mesa_update_state().  This is done by
55 * attaching optional extra information to the value description
56 * struct, it's sort of like an array of opcodes that describe extra
57 * checks or actions.
58 *
59 * Putting all this together we end up with struct value_desc below,
60 * and with a couple of macros to help, the table of struct value_desc
61 * is about as concise as the specification in the old python script.
62 */
63
64#undef CONST
65
66#define FLOAT_TO_BOOLEAN(X)   ( (X) ? GL_TRUE : GL_FALSE )
67#define FLOAT_TO_FIXED(F)     ( ((F) * 65536.0f > INT_MAX) ? INT_MAX : \
68                                ((F) * 65536.0f < INT_MIN) ? INT_MIN : \
69                                (GLint) ((F) * 65536.0f) )
70
71#define INT_TO_BOOLEAN(I)     ( (I) ? GL_TRUE : GL_FALSE )
72#define INT_TO_FIXED(I)       ( ((I) > SHRT_MAX) ? INT_MAX : \
73                                ((I) < SHRT_MIN) ? INT_MIN : \
74                                (GLint) ((I) * 65536) )
75
76#define INT64_TO_BOOLEAN(I)   ( (I) ? GL_TRUE : GL_FALSE )
77#define INT64_TO_INT(I)       ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
78
79#define BOOLEAN_TO_INT(B)     ( (GLint) (B) )
80#define BOOLEAN_TO_INT64(B)   ( (GLint64) (B) )
81#define BOOLEAN_TO_FLOAT(B)   ( (B) ? 1.0F : 0.0F )
82#define BOOLEAN_TO_FIXED(B)   ( (GLint) ((B) ? 1 : 0) << 16 )
83
84#define ENUM_TO_INT64(E)      ( (GLint64) (E) )
85#define ENUM_TO_FIXED(E)      (E)
86
87enum value_type {
88   TYPE_INVALID,
89   TYPE_API_MASK,
90   TYPE_INT,
91   TYPE_INT_2,
92   TYPE_INT_3,
93   TYPE_INT_4,
94   TYPE_INT_N,
95   TYPE_INT64,
96   TYPE_ENUM,
97   TYPE_ENUM_2,
98   TYPE_BOOLEAN,
99   TYPE_BIT_0,
100   TYPE_BIT_1,
101   TYPE_BIT_2,
102   TYPE_BIT_3,
103   TYPE_BIT_4,
104   TYPE_BIT_5,
105   TYPE_BIT_6,
106   TYPE_BIT_7,
107   TYPE_FLOAT,
108   TYPE_FLOAT_2,
109   TYPE_FLOAT_3,
110   TYPE_FLOAT_4,
111   TYPE_FLOATN,
112   TYPE_FLOATN_2,
113   TYPE_FLOATN_3,
114   TYPE_FLOATN_4,
115   TYPE_DOUBLEN,
116   TYPE_MATRIX,
117   TYPE_MATRIX_T,
118   TYPE_CONST
119};
120
121enum value_location {
122   LOC_BUFFER,
123   LOC_CONTEXT,
124   LOC_ARRAY,
125   LOC_TEXUNIT,
126   LOC_CUSTOM
127};
128
129enum value_extra {
130   EXTRA_END = 0x8000,
131   EXTRA_VERSION_30,
132   EXTRA_VERSION_31,
133   EXTRA_VERSION_32,
134   EXTRA_VERSION_ES2,
135   EXTRA_NEW_BUFFERS,
136   EXTRA_NEW_FRAG_CLAMP,
137   EXTRA_VALID_DRAW_BUFFER,
138   EXTRA_VALID_TEXTURE_UNIT,
139   EXTRA_VALID_CLIP_DISTANCE,
140   EXTRA_FLUSH_CURRENT,
141};
142
143#define NO_EXTRA NULL
144#define NO_OFFSET 0
145
146struct value_desc {
147   GLenum pname;
148   GLubyte location;  /**< enum value_location */
149   GLubyte type;      /**< enum value_type */
150   int offset;
151   const int *extra;
152};
153
154union value {
155   GLfloat value_float;
156   GLfloat value_float_4[4];
157   GLmatrix *value_matrix;
158   GLint value_int;
159   GLint value_int_4[4];
160   GLint64 value_int64;
161   GLenum value_enum;
162
163   /* Sigh, see GL_COMPRESSED_TEXTURE_FORMATS_ARB handling */
164   struct {
165      GLint n, ints[100];
166   } value_int_n;
167   GLboolean value_bool;
168};
169
170#define BUFFER_FIELD(field, type) \
171   LOC_BUFFER, type, offsetof(struct gl_framebuffer, field)
172#define CONTEXT_FIELD(field, type) \
173   LOC_CONTEXT, type, offsetof(struct gl_context, field)
174#define ARRAY_FIELD(field, type) \
175   LOC_ARRAY, type, offsetof(struct gl_array_object, field)
176#define CONST(value) \
177   LOC_CONTEXT, TYPE_CONST, value
178
179#define BUFFER_INT(field) BUFFER_FIELD(field, TYPE_INT)
180#define BUFFER_ENUM(field) BUFFER_FIELD(field, TYPE_ENUM)
181#define BUFFER_BOOL(field) BUFFER_FIELD(field, TYPE_BOOLEAN)
182
183#define CONTEXT_INT(field) CONTEXT_FIELD(field, TYPE_INT)
184#define CONTEXT_INT2(field) CONTEXT_FIELD(field, TYPE_INT_2)
185#define CONTEXT_INT64(field) CONTEXT_FIELD(field, TYPE_INT64)
186#define CONTEXT_ENUM(field) CONTEXT_FIELD(field, TYPE_ENUM)
187#define CONTEXT_ENUM2(field) CONTEXT_FIELD(field, TYPE_ENUM_2)
188#define CONTEXT_BOOL(field) CONTEXT_FIELD(field, TYPE_BOOLEAN)
189#define CONTEXT_BIT0(field) CONTEXT_FIELD(field, TYPE_BIT_0)
190#define CONTEXT_BIT1(field) CONTEXT_FIELD(field, TYPE_BIT_1)
191#define CONTEXT_BIT2(field) CONTEXT_FIELD(field, TYPE_BIT_2)
192#define CONTEXT_BIT3(field) CONTEXT_FIELD(field, TYPE_BIT_3)
193#define CONTEXT_BIT4(field) CONTEXT_FIELD(field, TYPE_BIT_4)
194#define CONTEXT_BIT5(field) CONTEXT_FIELD(field, TYPE_BIT_5)
195#define CONTEXT_BIT6(field) CONTEXT_FIELD(field, TYPE_BIT_6)
196#define CONTEXT_BIT7(field) CONTEXT_FIELD(field, TYPE_BIT_7)
197#define CONTEXT_FLOAT(field) CONTEXT_FIELD(field, TYPE_FLOAT)
198#define CONTEXT_FLOAT2(field) CONTEXT_FIELD(field, TYPE_FLOAT_2)
199#define CONTEXT_FLOAT3(field) CONTEXT_FIELD(field, TYPE_FLOAT_3)
200#define CONTEXT_FLOAT4(field) CONTEXT_FIELD(field, TYPE_FLOAT_4)
201#define CONTEXT_MATRIX(field) CONTEXT_FIELD(field, TYPE_MATRIX)
202#define CONTEXT_MATRIX_T(field) CONTEXT_FIELD(field, TYPE_MATRIX_T)
203
204#define ARRAY_INT(field) ARRAY_FIELD(field, TYPE_INT)
205#define ARRAY_ENUM(field) ARRAY_FIELD(field, TYPE_ENUM)
206#define ARRAY_BOOL(field) ARRAY_FIELD(field, TYPE_BOOLEAN)
207
208#define EXT(f)					\
209   offsetof(struct gl_extensions, f)
210
211#define EXTRA_EXT(e)				\
212   static const int extra_##e[] = {		\
213      EXT(e), EXTRA_END				\
214   }
215
216#define EXTRA_EXT2(e1, e2)			\
217   static const int extra_##e1##_##e2[] = {	\
218      EXT(e1), EXT(e2), EXTRA_END		\
219   }
220
221/* The 'extra' mechanism is a way to specify extra checks (such as
222 * extensions or specific gl versions) or actions (flush current, new
223 * buffers) that we need to do before looking up an enum.  We need to
224 * declare them all up front so we can refer to them in the value_desc
225 * structs below. */
226
227static const int extra_new_buffers[] = {
228   EXTRA_NEW_BUFFERS,
229   EXTRA_END
230};
231
232static const int extra_new_frag_clamp[] = {
233   EXTRA_NEW_FRAG_CLAMP,
234   EXTRA_END
235};
236
237static const int extra_valid_draw_buffer[] = {
238   EXTRA_VALID_DRAW_BUFFER,
239   EXTRA_END
240};
241
242static const int extra_valid_texture_unit[] = {
243   EXTRA_VALID_TEXTURE_UNIT,
244   EXTRA_END
245};
246
247static const int extra_valid_clip_distance[] = {
248   EXTRA_VALID_CLIP_DISTANCE,
249   EXTRA_END
250};
251
252static const int extra_flush_current_valid_texture_unit[] = {
253   EXTRA_FLUSH_CURRENT,
254   EXTRA_VALID_TEXTURE_UNIT,
255   EXTRA_END
256};
257
258static const int extra_flush_current[] = {
259   EXTRA_FLUSH_CURRENT,
260   EXTRA_END
261};
262
263static const int extra_EXT_secondary_color_flush_current[] = {
264   EXT(EXT_secondary_color),
265   EXTRA_FLUSH_CURRENT,
266   EXTRA_END
267};
268
269static const int extra_EXT_fog_coord_flush_current[] = {
270   EXT(EXT_fog_coord),
271   EXTRA_FLUSH_CURRENT,
272   EXTRA_END
273};
274
275static const int extra_EXT_texture_integer[] = {
276   EXT(EXT_texture_integer),
277   EXTRA_END
278};
279
280static const int extra_EXT_gpu_shader4[] = {
281   EXT(EXT_gpu_shader4),
282   EXTRA_END
283};
284
285static const int extra_ARB_sampler_objects[] = {
286   EXT(ARB_sampler_objects),
287   EXTRA_END
288};
289
290
291EXTRA_EXT(ARB_ES2_compatibility);
292EXTRA_EXT(ARB_texture_cube_map);
293EXTRA_EXT(MESA_texture_array);
294EXTRA_EXT2(EXT_secondary_color, ARB_vertex_program);
295EXTRA_EXT(EXT_secondary_color);
296EXTRA_EXT(EXT_fog_coord);
297EXTRA_EXT(EXT_texture_filter_anisotropic);
298EXTRA_EXT(IBM_rasterpos_clip);
299EXTRA_EXT(NV_point_sprite);
300EXTRA_EXT(NV_vertex_program);
301EXTRA_EXT(NV_fragment_program);
302EXTRA_EXT(NV_texture_rectangle);
303EXTRA_EXT(EXT_stencil_two_side);
304EXTRA_EXT(NV_light_max_exponent);
305EXTRA_EXT(EXT_depth_bounds_test);
306EXTRA_EXT(ARB_depth_clamp);
307EXTRA_EXT(ATI_fragment_shader);
308EXTRA_EXT(EXT_framebuffer_blit);
309EXTRA_EXT(ARB_shader_objects);
310EXTRA_EXT(EXT_provoking_vertex);
311EXTRA_EXT(ARB_fragment_shader);
312EXTRA_EXT(ARB_fragment_program);
313EXTRA_EXT2(ARB_framebuffer_object, EXT_framebuffer_multisample);
314EXTRA_EXT(EXT_framebuffer_object);
315EXTRA_EXT(APPLE_vertex_array_object);
316EXTRA_EXT(ARB_seamless_cube_map);
317EXTRA_EXT(EXT_compiled_vertex_array);
318EXTRA_EXT(ARB_sync);
319EXTRA_EXT(ARB_vertex_shader);
320EXTRA_EXT(EXT_transform_feedback);
321EXTRA_EXT(ARB_transform_feedback2);
322EXTRA_EXT(EXT_pixel_buffer_object);
323EXTRA_EXT(ARB_vertex_program);
324EXTRA_EXT2(NV_point_sprite, ARB_point_sprite);
325EXTRA_EXT2(ARB_fragment_program, NV_fragment_program);
326EXTRA_EXT2(ARB_vertex_program, NV_vertex_program);
327EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
328EXTRA_EXT(ARB_geometry_shader4);
329EXTRA_EXT(ARB_color_buffer_float);
330EXTRA_EXT(ARB_copy_buffer);
331EXTRA_EXT(EXT_framebuffer_sRGB);
332EXTRA_EXT(ARB_texture_buffer_object);
333
334static const int
335extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
336   EXT(ARB_vertex_program),
337   EXT(ARB_fragment_program),
338   EXT(NV_vertex_program),
339   EXTRA_END
340};
341
342static const int
343extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
344   EXT(NV_vertex_program),
345   EXT(ARB_vertex_program),
346   EXT(ARB_fragment_program),
347   EXT(NV_vertex_program),
348   EXTRA_END
349};
350
351static const int
352extra_NV_primitive_restart[] = {
353   EXT(NV_primitive_restart),
354   EXTRA_END
355};
356
357static const int extra_version_30[] = { EXTRA_VERSION_30, EXTRA_END };
358static const int extra_version_31[] = { EXTRA_VERSION_31, EXTRA_END };
359static const int extra_version_32[] = { EXTRA_VERSION_32, EXTRA_END };
360
361static const int
362extra_ARB_vertex_program_version_es2[] = {
363   EXT(ARB_vertex_program),
364   EXTRA_VERSION_ES2,
365   EXTRA_END
366};
367
368#define API_OPENGL_BIT (1 << API_OPENGL)
369#define API_OPENGLES_BIT (1 << API_OPENGLES)
370#define API_OPENGLES2_BIT (1 << API_OPENGLES2)
371
372/* This is the big table describing all the enums we accept in
373 * glGet*v().  The table is partitioned into six parts: enums
374 * understood by all GL APIs (OpenGL, GLES and GLES2), enums shared
375 * between OpenGL and GLES, enums exclusive to GLES, etc for the
376 * remaining combinations.  When we add the enums to the hash table in
377 * _mesa_init_get_hash(), we only add the enums for the API we're
378 * instantiating and the different sections are guarded by #if
379 * FEATURE_GL etc to make sure we only compile in the enums we may
380 * need. */
381
382static const struct value_desc values[] = {
383   /* Enums shared between OpenGL, GLES1 and GLES2 */
384   { 0, 0, TYPE_API_MASK,
385     API_OPENGL_BIT | API_OPENGLES_BIT | API_OPENGLES2_BIT, NO_EXTRA},
386   { GL_ALPHA_BITS, BUFFER_INT(Visual.alphaBits), extra_new_buffers },
387   { GL_BLEND, CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA },
388   { GL_BLEND_SRC, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
389   { GL_BLUE_BITS, BUFFER_INT(Visual.blueBits), extra_new_buffers },
390   { GL_COLOR_CLEAR_VALUE, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
391   { GL_COLOR_WRITEMASK, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
392   { GL_CULL_FACE, CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA },
393   { GL_CULL_FACE_MODE, CONTEXT_ENUM(Polygon.CullFaceMode), NO_EXTRA },
394   { GL_DEPTH_BITS, BUFFER_INT(Visual.depthBits), NO_EXTRA },
395   { GL_DEPTH_CLEAR_VALUE, CONTEXT_FIELD(Depth.Clear, TYPE_DOUBLEN), NO_EXTRA },
396   { GL_DEPTH_FUNC, CONTEXT_ENUM(Depth.Func), NO_EXTRA },
397   { GL_DEPTH_RANGE, CONTEXT_FIELD(Viewport.Near, TYPE_FLOATN_2), NO_EXTRA },
398   { GL_DEPTH_TEST, CONTEXT_BOOL(Depth.Test), NO_EXTRA },
399   { GL_DEPTH_WRITEMASK, CONTEXT_BOOL(Depth.Mask), NO_EXTRA },
400   { GL_DITHER, CONTEXT_BOOL(Color.DitherFlag), NO_EXTRA },
401   { GL_FRONT_FACE, CONTEXT_ENUM(Polygon.FrontFace), NO_EXTRA },
402   { GL_GREEN_BITS, BUFFER_INT(Visual.greenBits), extra_new_buffers },
403   { GL_LINE_WIDTH, CONTEXT_FLOAT(Line.Width), NO_EXTRA },
404   { GL_ALIASED_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidth), NO_EXTRA },
405   { GL_MAX_ELEMENTS_VERTICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA },
406   { GL_MAX_ELEMENTS_INDICES, CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA },
407   { GL_MAX_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT,
408     offsetof(struct gl_context, Const.MaxTextureLevels), NO_EXTRA },
409   { GL_MAX_VIEWPORT_DIMS, CONTEXT_INT2(Const.MaxViewportWidth), NO_EXTRA },
410   { GL_PACK_ALIGNMENT, CONTEXT_INT(Pack.Alignment), NO_EXTRA },
411   { GL_ALIASED_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSize), NO_EXTRA },
412   { GL_POLYGON_OFFSET_FACTOR, CONTEXT_FLOAT(Polygon.OffsetFactor ), NO_EXTRA },
413   { GL_POLYGON_OFFSET_UNITS, CONTEXT_FLOAT(Polygon.OffsetUnits ), NO_EXTRA },
414   { GL_POLYGON_OFFSET_FILL, CONTEXT_BOOL(Polygon.OffsetFill), NO_EXTRA },
415   { GL_RED_BITS, BUFFER_INT(Visual.redBits), extra_new_buffers },
416   { GL_SCISSOR_BOX, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
417   { GL_SCISSOR_TEST, CONTEXT_BOOL(Scissor.Enabled), NO_EXTRA },
418   { GL_STENCIL_BITS, BUFFER_INT(Visual.stencilBits), NO_EXTRA },
419   { GL_STENCIL_CLEAR_VALUE, CONTEXT_INT(Stencil.Clear), NO_EXTRA },
420   { GL_STENCIL_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
421   { GL_STENCIL_FUNC, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
422   { GL_STENCIL_PASS_DEPTH_FAIL, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
423   { GL_STENCIL_PASS_DEPTH_PASS, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
424   { GL_STENCIL_REF, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
425   { GL_STENCIL_TEST, CONTEXT_BOOL(Stencil.Enabled), NO_EXTRA },
426   { GL_STENCIL_VALUE_MASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
427   { GL_STENCIL_WRITEMASK, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
428   { GL_SUBPIXEL_BITS, CONTEXT_INT(Const.SubPixelBits), NO_EXTRA },
429   { GL_TEXTURE_BINDING_2D, LOC_CUSTOM, TYPE_INT, TEXTURE_2D_INDEX, NO_EXTRA },
430   { GL_UNPACK_ALIGNMENT, CONTEXT_INT(Unpack.Alignment), NO_EXTRA },
431   { GL_VIEWPORT, LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA },
432
433   /* GL_ARB_multitexture */
434   { GL_ACTIVE_TEXTURE, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
435
436   /* Note that all the OES_* extensions require that the Mesa "struct
437    * gl_extensions" include a member with the name of the extension.
438    * That structure does not yet include OES extensions (and we're
439    * not sure whether it will).  If it does, all the OES_*
440    * extensions below should mark the dependency. */
441
442   /* GL_ARB_texture_cube_map */
443   { GL_TEXTURE_BINDING_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_INT,
444     TEXTURE_CUBE_INDEX, extra_ARB_texture_cube_map },
445   { GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, LOC_CUSTOM, TYPE_INT,
446     offsetof(struct gl_context, Const.MaxCubeTextureLevels),
447     extra_ARB_texture_cube_map }, /* XXX: OES_texture_cube_map */
448
449   /* XXX: OES_blend_subtract */
450   { GL_BLEND_SRC_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].SrcRGB), NO_EXTRA },
451   { GL_BLEND_DST_RGB_EXT, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
452   { GL_BLEND_SRC_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].SrcA), NO_EXTRA },
453   { GL_BLEND_DST_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].DstA), NO_EXTRA },
454
455   /* GL_BLEND_EQUATION_RGB, which is what we're really after, is
456    * defined identically to GL_BLEND_EQUATION. */
457   { GL_BLEND_EQUATION, CONTEXT_ENUM(Color.Blend[0].EquationRGB), NO_EXTRA },
458   { GL_BLEND_EQUATION_ALPHA_EXT, CONTEXT_ENUM(Color.Blend[0].EquationA), NO_EXTRA },
459
460   /* GL_ARB_texture_compression */
461   { GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
462   { GL_COMPRESSED_TEXTURE_FORMATS_ARB, LOC_CUSTOM, TYPE_INT_N, 0, NO_EXTRA },
463
464   /* GL_ARB_multisample */
465   { GL_SAMPLE_ALPHA_TO_COVERAGE_ARB,
466     CONTEXT_BOOL(Multisample.SampleAlphaToCoverage), NO_EXTRA },
467   { GL_SAMPLE_COVERAGE_ARB, CONTEXT_BOOL(Multisample.SampleCoverage), NO_EXTRA },
468   { GL_SAMPLE_COVERAGE_VALUE_ARB,
469     CONTEXT_FLOAT(Multisample.SampleCoverageValue), NO_EXTRA },
470   { GL_SAMPLE_COVERAGE_INVERT_ARB,
471     CONTEXT_BOOL(Multisample.SampleCoverageInvert), NO_EXTRA },
472   { GL_SAMPLE_BUFFERS_ARB, BUFFER_INT(Visual.sampleBuffers), NO_EXTRA },
473   { GL_SAMPLES_ARB, BUFFER_INT(Visual.samples), NO_EXTRA },
474
475   /* GL_SGIS_generate_mipmap */
476   { GL_GENERATE_MIPMAP_HINT_SGIS, CONTEXT_ENUM(Hint.GenerateMipmap), NO_EXTRA },
477
478   /* GL_ARB_vertex_buffer_object */
479   { GL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
480
481   /* GL_ARB_vertex_buffer_object */
482   /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported */
483   { GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
484
485   /* GL_ARB_color_buffer_float */
486   { GL_CLAMP_VERTEX_COLOR, CONTEXT_ENUM(Light.ClampVertexColor), extra_ARB_color_buffer_float },
487   { GL_CLAMP_FRAGMENT_COLOR, CONTEXT_ENUM(Color.ClampFragmentColor), extra_ARB_color_buffer_float },
488   { GL_CLAMP_READ_COLOR, CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float },
489
490   /* GL_ARB_copy_buffer */
491   { GL_COPY_READ_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
492   { GL_COPY_WRITE_BUFFER, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_copy_buffer },
493
494   /* GL_OES_read_format */
495   { GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, LOC_CUSTOM, TYPE_INT, 0,
496     extra_new_buffers },
497   { GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, LOC_CUSTOM, TYPE_INT, 0,
498     extra_new_buffers },
499
500   /* GL_EXT_framebuffer_object */
501   { GL_FRAMEBUFFER_BINDING_EXT, BUFFER_INT(Name),
502     extra_EXT_framebuffer_object },
503   { GL_RENDERBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
504     extra_EXT_framebuffer_object },
505   { GL_MAX_RENDERBUFFER_SIZE_EXT, CONTEXT_INT(Const.MaxRenderbufferSize),
506     extra_EXT_framebuffer_object },
507
508   /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's
509    * GLSL: */
510   { GL_MAX_CLIP_PLANES, CONTEXT_INT(Const.MaxClipPlanes), NO_EXTRA },
511
512#if FEATURE_GL || FEATURE_ES1
513   /* Enums in OpenGL and GLES1 */
514   { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES_BIT, NO_EXTRA },
515   { GL_LIGHT0, CONTEXT_BOOL(Light.Light[0].Enabled), NO_EXTRA },
516   { GL_LIGHT1, CONTEXT_BOOL(Light.Light[1].Enabled), NO_EXTRA },
517   { GL_LIGHT2, CONTEXT_BOOL(Light.Light[2].Enabled), NO_EXTRA },
518   { GL_LIGHT3, CONTEXT_BOOL(Light.Light[3].Enabled), NO_EXTRA },
519   { GL_LIGHT4, CONTEXT_BOOL(Light.Light[4].Enabled), NO_EXTRA },
520   { GL_LIGHT5, CONTEXT_BOOL(Light.Light[5].Enabled), NO_EXTRA },
521   { GL_LIGHT6, CONTEXT_BOOL(Light.Light[6].Enabled), NO_EXTRA },
522   { GL_LIGHT7, CONTEXT_BOOL(Light.Light[7].Enabled), NO_EXTRA },
523   { GL_LIGHTING, CONTEXT_BOOL(Light.Enabled), NO_EXTRA },
524   { GL_LIGHT_MODEL_AMBIENT,
525     CONTEXT_FIELD(Light.Model.Ambient[0], TYPE_FLOATN_4), NO_EXTRA },
526   { GL_LIGHT_MODEL_TWO_SIDE, CONTEXT_BOOL(Light.Model.TwoSide), NO_EXTRA },
527   { GL_ALPHA_TEST, CONTEXT_BOOL(Color.AlphaEnabled), NO_EXTRA },
528   { GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
529   { GL_ALPHA_TEST_REF, LOC_CUSTOM, TYPE_FLOATN, 0, extra_new_frag_clamp },
530   { GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
531   { GL_CLIP_DISTANCE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
532   { GL_CLIP_DISTANCE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
533   { GL_CLIP_DISTANCE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
534   { GL_CLIP_DISTANCE3, CONTEXT_BIT3(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
535   { GL_CLIP_DISTANCE4, CONTEXT_BIT4(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
536   { GL_CLIP_DISTANCE5, CONTEXT_BIT5(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
537   { GL_CLIP_DISTANCE6, CONTEXT_BIT6(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
538   { GL_CLIP_DISTANCE7, CONTEXT_BIT7(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
539   { GL_COLOR_MATERIAL, CONTEXT_BOOL(Light.ColorMaterialEnabled), NO_EXTRA },
540   { GL_CURRENT_COLOR,
541     CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR0][0], TYPE_FLOATN_4),
542     extra_flush_current },
543   { GL_CURRENT_NORMAL,
544     CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_NORMAL][0], TYPE_FLOATN_3),
545     extra_flush_current },
546   { GL_CURRENT_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0,
547     extra_flush_current_valid_texture_unit },
548   { GL_DISTANCE_ATTENUATION_EXT, CONTEXT_FLOAT3(Point.Params[0]), NO_EXTRA },
549   { GL_FOG, CONTEXT_BOOL(Fog.Enabled), NO_EXTRA },
550   { GL_FOG_COLOR, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
551   { GL_FOG_DENSITY, CONTEXT_FLOAT(Fog.Density), NO_EXTRA },
552   { GL_FOG_END, CONTEXT_FLOAT(Fog.End), NO_EXTRA },
553   { GL_FOG_HINT, CONTEXT_ENUM(Hint.Fog), NO_EXTRA },
554   { GL_FOG_MODE, CONTEXT_ENUM(Fog.Mode), NO_EXTRA },
555   { GL_FOG_START, CONTEXT_FLOAT(Fog.Start), NO_EXTRA },
556   { GL_LINE_SMOOTH, CONTEXT_BOOL(Line.SmoothFlag), NO_EXTRA },
557   { GL_LINE_SMOOTH_HINT, CONTEXT_ENUM(Hint.LineSmooth), NO_EXTRA },
558   { GL_LINE_WIDTH_RANGE, CONTEXT_FLOAT2(Const.MinLineWidthAA), NO_EXTRA },
559   { GL_COLOR_LOGIC_OP, CONTEXT_BOOL(Color.ColorLogicOpEnabled), NO_EXTRA },
560   { GL_LOGIC_OP_MODE, CONTEXT_ENUM(Color.LogicOp), NO_EXTRA },
561   { GL_MATRIX_MODE, CONTEXT_ENUM(Transform.MatrixMode), NO_EXTRA },
562   { GL_MAX_MODELVIEW_STACK_DEPTH, CONST(MAX_MODELVIEW_STACK_DEPTH), NO_EXTRA },
563   { GL_MAX_PROJECTION_STACK_DEPTH, CONST(MAX_PROJECTION_STACK_DEPTH), NO_EXTRA },
564   { GL_MAX_TEXTURE_STACK_DEPTH, CONST(MAX_TEXTURE_STACK_DEPTH), NO_EXTRA },
565   { GL_MODELVIEW_MATRIX, CONTEXT_MATRIX(ModelviewMatrixStack.Top), NO_EXTRA },
566   { GL_MODELVIEW_STACK_DEPTH, LOC_CUSTOM, TYPE_INT,
567     offsetof(struct gl_context, ModelviewMatrixStack.Depth), NO_EXTRA },
568   { GL_NORMALIZE, CONTEXT_BOOL(Transform.Normalize), NO_EXTRA },
569   { GL_PACK_SKIP_IMAGES_EXT, CONTEXT_INT(Pack.SkipImages), NO_EXTRA },
570   { GL_PERSPECTIVE_CORRECTION_HINT, CONTEXT_ENUM(Hint.PerspectiveCorrection), NO_EXTRA },
571   { GL_POINT_SIZE, CONTEXT_FLOAT(Point.Size), NO_EXTRA },
572   { GL_POINT_SIZE_RANGE, CONTEXT_FLOAT2(Const.MinPointSizeAA), NO_EXTRA },
573   { GL_POINT_SMOOTH, CONTEXT_BOOL(Point.SmoothFlag), NO_EXTRA },
574   { GL_POINT_SMOOTH_HINT, CONTEXT_ENUM(Hint.PointSmooth), NO_EXTRA },
575   { GL_POINT_SIZE_MIN_EXT, CONTEXT_FLOAT(Point.MinSize), NO_EXTRA },
576   { GL_POINT_SIZE_MAX_EXT, CONTEXT_FLOAT(Point.MaxSize), NO_EXTRA },
577   { GL_POINT_FADE_THRESHOLD_SIZE_EXT, CONTEXT_FLOAT(Point.Threshold), NO_EXTRA },
578   { GL_PROJECTION_MATRIX, CONTEXT_MATRIX(ProjectionMatrixStack.Top), NO_EXTRA },
579   { GL_PROJECTION_STACK_DEPTH, LOC_CUSTOM, TYPE_INT,
580     offsetof(struct gl_context, ProjectionMatrixStack.Depth), NO_EXTRA },
581   { GL_RESCALE_NORMAL, CONTEXT_BOOL(Transform.RescaleNormals), NO_EXTRA },
582   { GL_SHADE_MODEL, CONTEXT_ENUM(Light.ShadeModel), NO_EXTRA },
583   { GL_TEXTURE_2D, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
584   { GL_TEXTURE_MATRIX, LOC_CUSTOM, TYPE_MATRIX, 0, extra_valid_texture_unit },
585   { GL_TEXTURE_STACK_DEPTH, LOC_CUSTOM, TYPE_INT, 0,
586     extra_valid_texture_unit  },
587
588   { GL_VERTEX_ARRAY, ARRAY_BOOL(Vertex.Enabled), NO_EXTRA },
589   { GL_VERTEX_ARRAY_SIZE, ARRAY_INT(Vertex.Size), NO_EXTRA },
590   { GL_VERTEX_ARRAY_TYPE, ARRAY_ENUM(Vertex.Type), NO_EXTRA },
591   { GL_VERTEX_ARRAY_STRIDE, ARRAY_INT(Vertex.Stride), NO_EXTRA },
592   { GL_NORMAL_ARRAY, ARRAY_BOOL(Normal.Enabled), NO_EXTRA },
593   { GL_NORMAL_ARRAY_TYPE, ARRAY_ENUM(Normal.Type), NO_EXTRA },
594   { GL_NORMAL_ARRAY_STRIDE, ARRAY_INT(Normal.Stride), NO_EXTRA },
595   { GL_COLOR_ARRAY, ARRAY_BOOL(Color.Enabled), NO_EXTRA },
596   { GL_COLOR_ARRAY_SIZE, ARRAY_INT(Color.Size), NO_EXTRA },
597   { GL_COLOR_ARRAY_TYPE, ARRAY_ENUM(Color.Type), NO_EXTRA },
598   { GL_COLOR_ARRAY_STRIDE, ARRAY_INT(Color.Stride), NO_EXTRA },
599   { GL_TEXTURE_COORD_ARRAY,
600     LOC_CUSTOM, TYPE_BOOLEAN, offsetof(struct gl_client_array, Enabled), NO_EXTRA },
601   { GL_TEXTURE_COORD_ARRAY_SIZE,
602     LOC_CUSTOM, TYPE_INT, offsetof(struct gl_client_array, Size), NO_EXTRA },
603   { GL_TEXTURE_COORD_ARRAY_TYPE,
604     LOC_CUSTOM, TYPE_ENUM, offsetof(struct gl_client_array, Type), NO_EXTRA },
605   { GL_TEXTURE_COORD_ARRAY_STRIDE,
606     LOC_CUSTOM, TYPE_INT, offsetof(struct gl_client_array, Stride), NO_EXTRA },
607
608   /* GL_ARB_ES2_compatibility */
609   { GL_SHADER_COMPILER, CONST(1), extra_ARB_ES2_compatibility },
610   { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying),
611     extra_ARB_ES2_compatibility },
612   { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0,
613     extra_ARB_ES2_compatibility },
614   { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0,
615     extra_ARB_ES2_compatibility },
616
617   /* GL_ARB_multitexture */
618   { GL_MAX_TEXTURE_UNITS, CONTEXT_INT(Const.MaxTextureUnits), NO_EXTRA },
619   { GL_CLIENT_ACTIVE_TEXTURE, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
620
621   /* GL_ARB_texture_cube_map */
622   { GL_TEXTURE_CUBE_MAP_ARB, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
623   /* S, T, and R are always set at the same time */
624   { GL_TEXTURE_GEN_STR_OES, LOC_TEXUNIT, TYPE_BIT_0,
625     offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
626
627   /* GL_ARB_multisample */
628   { GL_MULTISAMPLE_ARB, CONTEXT_BOOL(Multisample.Enabled), NO_EXTRA },
629   { GL_SAMPLE_ALPHA_TO_ONE_ARB, CONTEXT_BOOL(Multisample.SampleAlphaToOne), NO_EXTRA },
630
631   /* GL_ARB_vertex_buffer_object */
632   { GL_VERTEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
633     offsetof(struct gl_array_object, Vertex.BufferObj), NO_EXTRA },
634   { GL_NORMAL_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
635     offsetof(struct gl_array_object, Normal.BufferObj), NO_EXTRA },
636   { GL_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
637     offsetof(struct gl_array_object, Color.BufferObj), NO_EXTRA },
638   { GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA },
639
640   /* GL_OES_point_sprite */
641   { GL_POINT_SPRITE_NV,
642     CONTEXT_BOOL(Point.PointSprite),
643     extra_NV_point_sprite_ARB_point_sprite },
644
645   /* GL_ARB_fragment_shader */
646   { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB,
647     CONTEXT_INT(Const.FragmentProgram.MaxUniformComponents),
648     extra_ARB_fragment_shader },
649
650   /* GL_ARB_vertex_shader */
651   { GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB,
652     CONTEXT_INT(Const.VertexProgram.MaxUniformComponents),
653     extra_ARB_vertex_shader },
654   { GL_MAX_VARYING_FLOATS_ARB, LOC_CUSTOM, TYPE_INT, 0,
655     extra_ARB_vertex_shader },
656
657   /* GL_EXT_texture_lod_bias */
658   { GL_MAX_TEXTURE_LOD_BIAS_EXT, CONTEXT_FLOAT(Const.MaxTextureLodBias),
659     NO_EXTRA },
660
661   /* GL_EXT_texture_filter_anisotropic */
662   { GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
663     CONTEXT_FLOAT(Const.MaxTextureMaxAnisotropy),
664     extra_EXT_texture_filter_anisotropic },
665#endif /* FEATURE_GL || FEATURE_ES1 */
666
667#if FEATURE_ES1
668   { 0, 0, TYPE_API_MASK, API_OPENGLES_BIT },
669   /* XXX: OES_matrix_get */
670   { GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES },
671   { GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES },
672   { GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES },
673
674   /* OES_point_size_array */
675   { GL_POINT_SIZE_ARRAY_OES, ARRAY_FIELD(PointSize.Enabled, TYPE_BOOLEAN) },
676   { GL_POINT_SIZE_ARRAY_TYPE_OES, ARRAY_FIELD(PointSize.Type, TYPE_ENUM) },
677   { GL_POINT_SIZE_ARRAY_STRIDE_OES, ARRAY_FIELD(PointSize.Stride, TYPE_INT) },
678   { GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, LOC_CUSTOM, TYPE_INT, 0 },
679#endif /* FEATURE_ES1 */
680
681#if FEATURE_GL || FEATURE_ES2
682   { 0, 0, TYPE_API_MASK, API_OPENGL_BIT | API_OPENGLES2_BIT, NO_EXTRA },
683   /* This entry isn't spec'ed for GLES 2, but is needed for Mesa's GLSL: */
684   { GL_MAX_LIGHTS, CONTEXT_INT(Const.MaxLights), NO_EXTRA },
685   { GL_MAX_TEXTURE_COORDS_ARB, /* == GL_MAX_TEXTURE_COORDS_NV */
686     CONTEXT_INT(Const.MaxTextureCoordUnits),
687     extra_ARB_fragment_program_NV_fragment_program },
688
689   /* GL_ARB_draw_buffers */
690   { GL_MAX_DRAW_BUFFERS_ARB, CONTEXT_INT(Const.MaxDrawBuffers), NO_EXTRA },
691
692   { GL_BLEND_COLOR_EXT, LOC_CUSTOM, TYPE_FLOATN_4, 0, extra_new_frag_clamp },
693   /* GL_ARB_fragment_program */
694   { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, /* == GL_MAX_TEXTURE_IMAGE_UNITS_NV */
695     CONTEXT_INT(Const.MaxTextureImageUnits),
696     extra_ARB_fragment_program_NV_fragment_program },
697   { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB,
698     CONTEXT_INT(Const.MaxVertexTextureImageUnits), extra_ARB_vertex_shader },
699   { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB,
700     CONTEXT_INT(Const.MaxCombinedTextureImageUnits),
701     extra_ARB_vertex_shader },
702
703   /* GL_ARB_shader_objects
704    * Actually, this token isn't part of GL_ARB_shader_objects, but is
705    * close enough for now. */
706   { GL_CURRENT_PROGRAM, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_objects },
707
708   /* OpenGL 2.0 */
709   { GL_STENCIL_BACK_FUNC, CONTEXT_ENUM(Stencil.Function[1]), NO_EXTRA },
710   { GL_STENCIL_BACK_VALUE_MASK, CONTEXT_INT(Stencil.ValueMask[1]), NO_EXTRA },
711   { GL_STENCIL_BACK_WRITEMASK, CONTEXT_INT(Stencil.WriteMask[1]), NO_EXTRA },
712   { GL_STENCIL_BACK_REF, CONTEXT_INT(Stencil.Ref[1]), NO_EXTRA },
713   { GL_STENCIL_BACK_FAIL, CONTEXT_ENUM(Stencil.FailFunc[1]), NO_EXTRA },
714   { GL_STENCIL_BACK_PASS_DEPTH_FAIL, CONTEXT_ENUM(Stencil.ZFailFunc[1]), NO_EXTRA },
715   { GL_STENCIL_BACK_PASS_DEPTH_PASS, CONTEXT_ENUM(Stencil.ZPassFunc[1]), NO_EXTRA },
716
717   { GL_MAX_VERTEX_ATTRIBS_ARB,
718     CONTEXT_INT(Const.VertexProgram.MaxAttribs),
719     extra_ARB_vertex_program_version_es2 },
720
721   /* OES_texture_3D */
722   { GL_TEXTURE_BINDING_3D, LOC_CUSTOM, TYPE_INT, TEXTURE_3D_INDEX, NO_EXTRA },
723   { GL_MAX_3D_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT,
724     offsetof(struct gl_context, Const.Max3DTextureLevels), NO_EXTRA },
725
726   /* GL_ARB_fragment_program/OES_standard_derivatives */
727   { GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB,
728     CONTEXT_ENUM(Hint.FragmentShaderDerivative), extra_ARB_fragment_shader },
729#endif /* FEATURE_GL || FEATURE_ES2 */
730
731#if FEATURE_ES2
732   /* Enums unique to OpenGL ES 2.0 */
733   { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA },
734   { GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
735   { GL_MAX_VARYING_VECTORS, CONTEXT_INT(Const.MaxVarying), NO_EXTRA },
736   { GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
737   { GL_SHADER_COMPILER, CONST(1), NO_EXTRA },
738   /* OES_get_program_binary */
739   { GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
740   { GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
741#endif /* FEATURE_ES2 */
742
743#if FEATURE_GL
744   /* Remaining enums are only in OpenGL */
745   { 0, 0, TYPE_API_MASK, API_OPENGL_BIT, NO_EXTRA },
746   { GL_ACCUM_RED_BITS, BUFFER_INT(Visual.accumRedBits), NO_EXTRA },
747   { GL_ACCUM_GREEN_BITS, BUFFER_INT(Visual.accumGreenBits), NO_EXTRA },
748   { GL_ACCUM_BLUE_BITS, BUFFER_INT(Visual.accumBlueBits), NO_EXTRA },
749   { GL_ACCUM_ALPHA_BITS, BUFFER_INT(Visual.accumAlphaBits), NO_EXTRA },
750   { GL_ACCUM_CLEAR_VALUE, CONTEXT_FIELD(Accum.ClearColor[0], TYPE_FLOATN_4), NO_EXTRA },
751   { GL_ALPHA_BIAS, CONTEXT_FLOAT(Pixel.AlphaBias), NO_EXTRA },
752   { GL_ALPHA_SCALE, CONTEXT_FLOAT(Pixel.AlphaScale), NO_EXTRA },
753   { GL_ATTRIB_STACK_DEPTH, CONTEXT_INT(AttribStackDepth), NO_EXTRA },
754   { GL_AUTO_NORMAL, CONTEXT_BOOL(Eval.AutoNormal), NO_EXTRA },
755   { GL_AUX_BUFFERS, BUFFER_INT(Visual.numAuxBuffers), NO_EXTRA },
756   { GL_BLUE_BIAS, CONTEXT_FLOAT(Pixel.BlueBias), NO_EXTRA },
757   { GL_BLUE_SCALE, CONTEXT_FLOAT(Pixel.BlueScale), NO_EXTRA },
758   { GL_CLIENT_ATTRIB_STACK_DEPTH, CONTEXT_INT(ClientAttribStackDepth), NO_EXTRA },
759   { GL_COLOR_MATERIAL_FACE, CONTEXT_ENUM(Light.ColorMaterialFace), NO_EXTRA },
760   { GL_COLOR_MATERIAL_PARAMETER, CONTEXT_ENUM(Light.ColorMaterialMode), NO_EXTRA },
761   { GL_CURRENT_INDEX,
762     CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]),
763     extra_flush_current },
764   { GL_CURRENT_RASTER_COLOR,
765     CONTEXT_FIELD(Current.RasterColor[0], TYPE_FLOATN_4), NO_EXTRA },
766   { GL_CURRENT_RASTER_DISTANCE, CONTEXT_FLOAT(Current.RasterDistance), NO_EXTRA },
767   { GL_CURRENT_RASTER_INDEX, CONST(1), NO_EXTRA },
768   { GL_CURRENT_RASTER_POSITION, CONTEXT_FLOAT4(Current.RasterPos[0]), NO_EXTRA },
769   { GL_CURRENT_RASTER_SECONDARY_COLOR,
770     CONTEXT_FIELD(Current.RasterSecondaryColor[0], TYPE_FLOATN_4), NO_EXTRA },
771   { GL_CURRENT_RASTER_TEXTURE_COORDS, LOC_CUSTOM, TYPE_FLOAT_4, 0,
772     extra_valid_texture_unit },
773   { GL_CURRENT_RASTER_POSITION_VALID, CONTEXT_BOOL(Current.RasterPosValid), NO_EXTRA },
774   { GL_DEPTH_BIAS, CONTEXT_FLOAT(Pixel.DepthBias), NO_EXTRA },
775   { GL_DEPTH_SCALE, CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA },
776   { GL_DOUBLEBUFFER, BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA },
777   { GL_DRAW_BUFFER, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
778   { GL_EDGE_FLAG, LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA },
779   { GL_FEEDBACK_BUFFER_SIZE, CONTEXT_INT(Feedback.BufferSize), NO_EXTRA },
780   { GL_FEEDBACK_BUFFER_TYPE, CONTEXT_ENUM(Feedback.Type), NO_EXTRA },
781   { GL_FOG_INDEX, CONTEXT_FLOAT(Fog.Index), NO_EXTRA },
782   { GL_GREEN_BIAS, CONTEXT_FLOAT(Pixel.GreenBias), NO_EXTRA },
783   { GL_GREEN_SCALE, CONTEXT_FLOAT(Pixel.GreenScale), NO_EXTRA },
784   { GL_INDEX_BITS, BUFFER_INT(Visual.indexBits), extra_new_buffers },
785   { GL_INDEX_CLEAR_VALUE, CONTEXT_INT(Color.ClearIndex), NO_EXTRA },
786   { GL_INDEX_MODE, CONST(0) , NO_EXTRA},
787   { GL_INDEX_OFFSET, CONTEXT_INT(Pixel.IndexOffset), NO_EXTRA },
788   { GL_INDEX_SHIFT, CONTEXT_INT(Pixel.IndexShift), NO_EXTRA },
789   { GL_INDEX_WRITEMASK, CONTEXT_INT(Color.IndexMask), NO_EXTRA },
790   { GL_LIGHT_MODEL_COLOR_CONTROL, CONTEXT_ENUM(Light.Model.ColorControl), NO_EXTRA },
791   { GL_LIGHT_MODEL_LOCAL_VIEWER, CONTEXT_BOOL(Light.Model.LocalViewer), NO_EXTRA },
792   { GL_LINE_STIPPLE, CONTEXT_BOOL(Line.StippleFlag), NO_EXTRA },
793   { GL_LINE_STIPPLE_PATTERN, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
794   { GL_LINE_STIPPLE_REPEAT, CONTEXT_INT(Line.StippleFactor), NO_EXTRA },
795   { GL_LINE_WIDTH_GRANULARITY, CONTEXT_FLOAT(Const.LineWidthGranularity), NO_EXTRA },
796   { GL_LIST_BASE, CONTEXT_INT(List.ListBase), NO_EXTRA },
797   { GL_LIST_INDEX, LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA },
798   { GL_LIST_MODE, LOC_CUSTOM, TYPE_ENUM, 0, NO_EXTRA },
799   { GL_INDEX_LOGIC_OP, CONTEXT_BOOL(Color.IndexLogicOpEnabled), NO_EXTRA },
800   { GL_MAP1_COLOR_4, CONTEXT_BOOL(Eval.Map1Color4), NO_EXTRA },
801   { GL_MAP1_GRID_DOMAIN, CONTEXT_FLOAT2(Eval.MapGrid1u1), NO_EXTRA },
802   { GL_MAP1_GRID_SEGMENTS, CONTEXT_INT(Eval.MapGrid1un), NO_EXTRA },
803   { GL_MAP1_INDEX, CONTEXT_BOOL(Eval.Map1Index), NO_EXTRA },
804   { GL_MAP1_NORMAL, CONTEXT_BOOL(Eval.Map1Normal), NO_EXTRA },
805   { GL_MAP1_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map1TextureCoord1), NO_EXTRA },
806   { GL_MAP1_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map1TextureCoord2), NO_EXTRA },
807   { GL_MAP1_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map1TextureCoord3), NO_EXTRA },
808   { GL_MAP1_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map1TextureCoord4), NO_EXTRA },
809   { GL_MAP1_VERTEX_3, CONTEXT_BOOL(Eval.Map1Vertex3), NO_EXTRA },
810   { GL_MAP1_VERTEX_4, CONTEXT_BOOL(Eval.Map1Vertex4), NO_EXTRA },
811   { GL_MAP2_COLOR_4, CONTEXT_BOOL(Eval.Map2Color4), NO_EXTRA },
812   { GL_MAP2_GRID_DOMAIN, LOC_CUSTOM, TYPE_FLOAT_4, 0, NO_EXTRA },
813   { GL_MAP2_GRID_SEGMENTS, CONTEXT_INT2(Eval.MapGrid2un), NO_EXTRA },
814   { GL_MAP2_INDEX, CONTEXT_BOOL(Eval.Map2Index), NO_EXTRA },
815   { GL_MAP2_NORMAL, CONTEXT_BOOL(Eval.Map2Normal), NO_EXTRA },
816   { GL_MAP2_TEXTURE_COORD_1, CONTEXT_BOOL(Eval.Map2TextureCoord1), NO_EXTRA },
817   { GL_MAP2_TEXTURE_COORD_2, CONTEXT_BOOL(Eval.Map2TextureCoord2), NO_EXTRA },
818   { GL_MAP2_TEXTURE_COORD_3, CONTEXT_BOOL(Eval.Map2TextureCoord3), NO_EXTRA },
819   { GL_MAP2_TEXTURE_COORD_4, CONTEXT_BOOL(Eval.Map2TextureCoord4), NO_EXTRA },
820   { GL_MAP2_VERTEX_3, CONTEXT_BOOL(Eval.Map2Vertex3), NO_EXTRA },
821   { GL_MAP2_VERTEX_4, CONTEXT_BOOL(Eval.Map2Vertex4), NO_EXTRA },
822   { GL_MAP_COLOR, CONTEXT_BOOL(Pixel.MapColorFlag), NO_EXTRA },
823   { GL_MAP_STENCIL, CONTEXT_BOOL(Pixel.MapStencilFlag), NO_EXTRA },
824   { GL_MAX_ATTRIB_STACK_DEPTH, CONST(MAX_ATTRIB_STACK_DEPTH), NO_EXTRA },
825   { GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, CONST(MAX_CLIENT_ATTRIB_STACK_DEPTH), NO_EXTRA },
826
827   { GL_MAX_EVAL_ORDER, CONST(MAX_EVAL_ORDER), NO_EXTRA },
828   { GL_MAX_LIST_NESTING, CONST(MAX_LIST_NESTING), NO_EXTRA },
829   { GL_MAX_NAME_STACK_DEPTH, CONST(MAX_NAME_STACK_DEPTH), NO_EXTRA },
830   { GL_MAX_PIXEL_MAP_TABLE, CONST(MAX_PIXEL_MAP_TABLE), NO_EXTRA },
831   { GL_NAME_STACK_DEPTH, CONTEXT_INT(Select.NameStackDepth), NO_EXTRA },
832   { GL_PACK_LSB_FIRST, CONTEXT_BOOL(Pack.LsbFirst), NO_EXTRA },
833   { GL_PACK_ROW_LENGTH, CONTEXT_INT(Pack.RowLength), NO_EXTRA },
834   { GL_PACK_SKIP_PIXELS, CONTEXT_INT(Pack.SkipPixels), NO_EXTRA },
835   { GL_PACK_SKIP_ROWS, CONTEXT_INT(Pack.SkipRows), NO_EXTRA },
836   { GL_PACK_SWAP_BYTES, CONTEXT_BOOL(Pack.SwapBytes), NO_EXTRA },
837   { GL_PACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Pack.ImageHeight), NO_EXTRA },
838   { GL_PACK_INVERT_MESA, CONTEXT_BOOL(Pack.Invert), NO_EXTRA },
839   { GL_PIXEL_MAP_A_TO_A_SIZE, CONTEXT_INT(PixelMaps.AtoA.Size), NO_EXTRA },
840   { GL_PIXEL_MAP_B_TO_B_SIZE, CONTEXT_INT(PixelMaps.BtoB.Size), NO_EXTRA },
841   { GL_PIXEL_MAP_G_TO_G_SIZE, CONTEXT_INT(PixelMaps.GtoG.Size), NO_EXTRA },
842   { GL_PIXEL_MAP_I_TO_A_SIZE, CONTEXT_INT(PixelMaps.ItoA.Size), NO_EXTRA },
843   { GL_PIXEL_MAP_I_TO_B_SIZE, CONTEXT_INT(PixelMaps.ItoB.Size), NO_EXTRA },
844   { GL_PIXEL_MAP_I_TO_G_SIZE, CONTEXT_INT(PixelMaps.ItoG.Size), NO_EXTRA },
845   { GL_PIXEL_MAP_I_TO_I_SIZE, CONTEXT_INT(PixelMaps.ItoI.Size), NO_EXTRA },
846   { GL_PIXEL_MAP_I_TO_R_SIZE, CONTEXT_INT(PixelMaps.ItoR.Size), NO_EXTRA },
847   { GL_PIXEL_MAP_R_TO_R_SIZE, CONTEXT_INT(PixelMaps.RtoR.Size), NO_EXTRA },
848   { GL_PIXEL_MAP_S_TO_S_SIZE, CONTEXT_INT(PixelMaps.StoS.Size), NO_EXTRA },
849   { GL_POINT_SIZE_GRANULARITY, CONTEXT_FLOAT(Const.PointSizeGranularity), NO_EXTRA },
850   { GL_POLYGON_MODE, CONTEXT_ENUM2(Polygon.FrontMode), NO_EXTRA },
851   { GL_POLYGON_OFFSET_BIAS_EXT, CONTEXT_FLOAT(Polygon.OffsetUnits), NO_EXTRA },
852   { GL_POLYGON_OFFSET_POINT, CONTEXT_BOOL(Polygon.OffsetPoint), NO_EXTRA },
853   { GL_POLYGON_OFFSET_LINE, CONTEXT_BOOL(Polygon.OffsetLine), NO_EXTRA },
854   { GL_POLYGON_SMOOTH, CONTEXT_BOOL(Polygon.SmoothFlag), NO_EXTRA },
855   { GL_POLYGON_SMOOTH_HINT, CONTEXT_ENUM(Hint.PolygonSmooth), NO_EXTRA },
856   { GL_POLYGON_STIPPLE, CONTEXT_BOOL(Polygon.StippleFlag), NO_EXTRA },
857   { GL_READ_BUFFER, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
858   { GL_RED_BIAS, CONTEXT_FLOAT(Pixel.RedBias), NO_EXTRA },
859   { GL_RED_SCALE, CONTEXT_FLOAT(Pixel.RedScale), NO_EXTRA },
860   { GL_RENDER_MODE, CONTEXT_ENUM(RenderMode), NO_EXTRA },
861   { GL_RGBA_MODE, CONST(1), NO_EXTRA },
862   { GL_SELECTION_BUFFER_SIZE, CONTEXT_INT(Select.BufferSize), NO_EXTRA },
863
864   { GL_STEREO, BUFFER_INT(Visual.stereoMode), NO_EXTRA },
865
866   { GL_TEXTURE_1D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
867   { GL_TEXTURE_3D, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
868   { GL_TEXTURE_1D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
869   { GL_TEXTURE_2D_ARRAY_EXT, LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA },
870
871   { GL_TEXTURE_BINDING_1D, LOC_CUSTOM, TYPE_INT, TEXTURE_1D_INDEX, NO_EXTRA },
872   { GL_TEXTURE_BINDING_1D_ARRAY, LOC_CUSTOM, TYPE_INT,
873     TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array },
874   { GL_TEXTURE_BINDING_2D_ARRAY, LOC_CUSTOM, TYPE_INT,
875     TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array },
876   { GL_MAX_ARRAY_TEXTURE_LAYERS_EXT,
877     CONTEXT_INT(Const.MaxArrayTextureLayers), extra_MESA_texture_array },
878
879   { GL_TEXTURE_GEN_S, LOC_TEXUNIT, TYPE_BIT_0,
880     offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
881   { GL_TEXTURE_GEN_T, LOC_TEXUNIT, TYPE_BIT_1,
882     offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
883   { GL_TEXTURE_GEN_R, LOC_TEXUNIT, TYPE_BIT_2,
884     offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
885   { GL_TEXTURE_GEN_Q, LOC_TEXUNIT, TYPE_BIT_3,
886     offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA },
887   { GL_UNPACK_LSB_FIRST, CONTEXT_BOOL(Unpack.LsbFirst), NO_EXTRA },
888   { GL_UNPACK_ROW_LENGTH, CONTEXT_INT(Unpack.RowLength), NO_EXTRA },
889   { GL_UNPACK_SKIP_PIXELS, CONTEXT_INT(Unpack.SkipPixels), NO_EXTRA },
890   { GL_UNPACK_SKIP_ROWS, CONTEXT_INT(Unpack.SkipRows), NO_EXTRA },
891   { GL_UNPACK_SWAP_BYTES, CONTEXT_BOOL(Unpack.SwapBytes), NO_EXTRA },
892   { GL_UNPACK_SKIP_IMAGES_EXT, CONTEXT_INT(Unpack.SkipImages), NO_EXTRA },
893   { GL_UNPACK_IMAGE_HEIGHT_EXT, CONTEXT_INT(Unpack.ImageHeight), NO_EXTRA },
894   { GL_ZOOM_X, CONTEXT_FLOAT(Pixel.ZoomX), NO_EXTRA },
895   { GL_ZOOM_Y, CONTEXT_FLOAT(Pixel.ZoomY), NO_EXTRA },
896
897   /* Vertex arrays */
898   { GL_VERTEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
899   { GL_NORMAL_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
900   { GL_COLOR_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
901   { GL_INDEX_ARRAY, ARRAY_BOOL(Index.Enabled), NO_EXTRA },
902   { GL_INDEX_ARRAY_TYPE, ARRAY_ENUM(Index.Type), NO_EXTRA },
903   { GL_INDEX_ARRAY_STRIDE, ARRAY_INT(Index.Stride), NO_EXTRA },
904   { GL_INDEX_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
905   { GL_TEXTURE_COORD_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
906   { GL_EDGE_FLAG_ARRAY, ARRAY_BOOL(EdgeFlag.Enabled), NO_EXTRA },
907   { GL_EDGE_FLAG_ARRAY_STRIDE, ARRAY_INT(EdgeFlag.Stride), NO_EXTRA },
908   { GL_EDGE_FLAG_ARRAY_COUNT_EXT, CONST(0), NO_EXTRA },
909
910   /* GL_ARB_texture_compression */
911   { GL_TEXTURE_COMPRESSION_HINT_ARB, CONTEXT_INT(Hint.TextureCompression), NO_EXTRA },
912
913   /* GL_EXT_compiled_vertex_array */
914   { GL_ARRAY_ELEMENT_LOCK_FIRST_EXT, CONTEXT_INT(Array.LockFirst),
915     extra_EXT_compiled_vertex_array },
916   { GL_ARRAY_ELEMENT_LOCK_COUNT_EXT, CONTEXT_INT(Array.LockCount),
917     extra_EXT_compiled_vertex_array },
918
919   /* GL_ARB_transpose_matrix */
920   { GL_TRANSPOSE_MODELVIEW_MATRIX_ARB,
921     CONTEXT_MATRIX_T(ModelviewMatrixStack), NO_EXTRA },
922   { GL_TRANSPOSE_PROJECTION_MATRIX_ARB,
923     CONTEXT_MATRIX_T(ProjectionMatrixStack.Top), NO_EXTRA },
924   { GL_TRANSPOSE_TEXTURE_MATRIX_ARB, CONTEXT_MATRIX_T(TextureMatrixStack), NO_EXTRA },
925
926   /* GL_EXT_secondary_color */
927   { GL_COLOR_SUM_EXT, CONTEXT_BOOL(Fog.ColorSumEnabled),
928     extra_EXT_secondary_color_ARB_vertex_program },
929   { GL_CURRENT_SECONDARY_COLOR_EXT,
930     CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR1][0], TYPE_FLOATN_4),
931     extra_EXT_secondary_color_flush_current },
932   { GL_SECONDARY_COLOR_ARRAY_EXT, ARRAY_BOOL(SecondaryColor.Enabled),
933     extra_EXT_secondary_color },
934   { GL_SECONDARY_COLOR_ARRAY_TYPE_EXT, ARRAY_ENUM(SecondaryColor.Type),
935     extra_EXT_secondary_color },
936   { GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT, ARRAY_INT(SecondaryColor.Stride),
937     extra_EXT_secondary_color },
938   { GL_SECONDARY_COLOR_ARRAY_SIZE_EXT, ARRAY_INT(SecondaryColor.Size),
939     extra_EXT_secondary_color },
940
941   /* GL_EXT_fog_coord */
942   { GL_CURRENT_FOG_COORDINATE_EXT,
943     CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]),
944     extra_EXT_fog_coord_flush_current },
945   { GL_FOG_COORDINATE_ARRAY_EXT, ARRAY_BOOL(FogCoord.Enabled),
946     extra_EXT_fog_coord },
947   { GL_FOG_COORDINATE_ARRAY_TYPE_EXT, ARRAY_ENUM(FogCoord.Type),
948     extra_EXT_fog_coord },
949   { GL_FOG_COORDINATE_ARRAY_STRIDE_EXT, ARRAY_INT(FogCoord.Stride),
950     extra_EXT_fog_coord },
951   { GL_FOG_COORDINATE_SOURCE_EXT, CONTEXT_ENUM(Fog.FogCoordinateSource),
952     extra_EXT_fog_coord },
953
954   /* GL_IBM_rasterpos_clip */
955   { GL_RASTER_POSITION_UNCLIPPED_IBM,
956     CONTEXT_BOOL(Transform.RasterPositionUnclipped),
957     extra_IBM_rasterpos_clip },
958
959   /* GL_NV_point_sprite */
960   { GL_POINT_SPRITE_R_MODE_NV,
961     CONTEXT_ENUM(Point.SpriteRMode), extra_NV_point_sprite },
962   { GL_POINT_SPRITE_COORD_ORIGIN, CONTEXT_ENUM(Point.SpriteOrigin),
963     extra_NV_point_sprite_ARB_point_sprite },
964
965   /* GL_NV_vertex_program */
966   { GL_VERTEX_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0,
967     extra_NV_vertex_program },
968   { GL_VERTEX_ATTRIB_ARRAY0_NV, ARRAY_BOOL(VertexAttrib[0].Enabled),
969     extra_NV_vertex_program },
970   { GL_VERTEX_ATTRIB_ARRAY1_NV, ARRAY_BOOL(VertexAttrib[1].Enabled),
971     extra_NV_vertex_program },
972   { GL_VERTEX_ATTRIB_ARRAY2_NV, ARRAY_BOOL(VertexAttrib[2].Enabled),
973     extra_NV_vertex_program },
974   { GL_VERTEX_ATTRIB_ARRAY3_NV, ARRAY_BOOL(VertexAttrib[3].Enabled),
975     extra_NV_vertex_program },
976   { GL_VERTEX_ATTRIB_ARRAY4_NV, ARRAY_BOOL(VertexAttrib[4].Enabled),
977     extra_NV_vertex_program },
978   { GL_VERTEX_ATTRIB_ARRAY5_NV, ARRAY_BOOL(VertexAttrib[5].Enabled),
979     extra_NV_vertex_program },
980   { GL_VERTEX_ATTRIB_ARRAY6_NV, ARRAY_BOOL(VertexAttrib[6].Enabled),
981     extra_NV_vertex_program },
982   { GL_VERTEX_ATTRIB_ARRAY7_NV, ARRAY_BOOL(VertexAttrib[7].Enabled),
983     extra_NV_vertex_program },
984   { GL_VERTEX_ATTRIB_ARRAY8_NV, ARRAY_BOOL(VertexAttrib[8].Enabled),
985     extra_NV_vertex_program },
986   { GL_VERTEX_ATTRIB_ARRAY9_NV, ARRAY_BOOL(VertexAttrib[9].Enabled),
987     extra_NV_vertex_program },
988   { GL_VERTEX_ATTRIB_ARRAY10_NV, ARRAY_BOOL(VertexAttrib[10].Enabled),
989     extra_NV_vertex_program },
990   { GL_VERTEX_ATTRIB_ARRAY11_NV, ARRAY_BOOL(VertexAttrib[11].Enabled),
991     extra_NV_vertex_program },
992   { GL_VERTEX_ATTRIB_ARRAY12_NV, ARRAY_BOOL(VertexAttrib[12].Enabled),
993     extra_NV_vertex_program },
994   { GL_VERTEX_ATTRIB_ARRAY13_NV, ARRAY_BOOL(VertexAttrib[13].Enabled),
995     extra_NV_vertex_program },
996   { GL_VERTEX_ATTRIB_ARRAY14_NV, ARRAY_BOOL(VertexAttrib[14].Enabled),
997     extra_NV_vertex_program },
998   { GL_VERTEX_ATTRIB_ARRAY15_NV, ARRAY_BOOL(VertexAttrib[15].Enabled),
999     extra_NV_vertex_program },
1000   { GL_MAP1_VERTEX_ATTRIB0_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[0]),
1001     extra_NV_vertex_program },
1002   { GL_MAP1_VERTEX_ATTRIB1_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[1]),
1003     extra_NV_vertex_program },
1004   { GL_MAP1_VERTEX_ATTRIB2_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[2]),
1005     extra_NV_vertex_program },
1006   { GL_MAP1_VERTEX_ATTRIB3_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[3]),
1007     extra_NV_vertex_program },
1008   { GL_MAP1_VERTEX_ATTRIB4_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[4]),
1009     extra_NV_vertex_program },
1010   { GL_MAP1_VERTEX_ATTRIB5_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[5]),
1011     extra_NV_vertex_program },
1012   { GL_MAP1_VERTEX_ATTRIB6_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[6]),
1013     extra_NV_vertex_program },
1014   { GL_MAP1_VERTEX_ATTRIB7_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[7]),
1015     extra_NV_vertex_program },
1016   { GL_MAP1_VERTEX_ATTRIB8_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[8]),
1017     extra_NV_vertex_program },
1018   { GL_MAP1_VERTEX_ATTRIB9_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[9]),
1019     extra_NV_vertex_program },
1020   { GL_MAP1_VERTEX_ATTRIB10_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[10]),
1021     extra_NV_vertex_program },
1022   { GL_MAP1_VERTEX_ATTRIB11_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[11]),
1023     extra_NV_vertex_program },
1024   { GL_MAP1_VERTEX_ATTRIB12_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[12]),
1025     extra_NV_vertex_program },
1026   { GL_MAP1_VERTEX_ATTRIB13_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[13]),
1027     extra_NV_vertex_program },
1028   { GL_MAP1_VERTEX_ATTRIB14_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[14]),
1029     extra_NV_vertex_program },
1030   { GL_MAP1_VERTEX_ATTRIB15_4_NV, CONTEXT_BOOL(Eval.Map1Attrib[15]),
1031     extra_NV_vertex_program },
1032
1033   /* GL_NV_fragment_program */
1034   { GL_FRAGMENT_PROGRAM_NV, CONTEXT_BOOL(FragmentProgram.Enabled),
1035     extra_NV_fragment_program },
1036   { GL_FRAGMENT_PROGRAM_BINDING_NV, LOC_CUSTOM, TYPE_INT, 0,
1037     extra_NV_fragment_program },
1038   { GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV,
1039     CONST(MAX_NV_FRAGMENT_PROGRAM_PARAMS),
1040     extra_NV_fragment_program },
1041
1042   /* GL_NV_texture_rectangle */
1043   { GL_TEXTURE_RECTANGLE_NV,
1044     LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_NV_texture_rectangle },
1045   { GL_TEXTURE_BINDING_RECTANGLE_NV,
1046     LOC_CUSTOM, TYPE_INT, TEXTURE_RECT_INDEX, extra_NV_texture_rectangle },
1047   { GL_MAX_RECTANGLE_TEXTURE_SIZE_NV,
1048     CONTEXT_INT(Const.MaxTextureRectSize), extra_NV_texture_rectangle },
1049
1050   /* GL_EXT_stencil_two_side */
1051   { GL_STENCIL_TEST_TWO_SIDE_EXT, CONTEXT_BOOL(Stencil.TestTwoSide),
1052	 extra_EXT_stencil_two_side },
1053   { GL_ACTIVE_STENCIL_FACE_EXT, LOC_CUSTOM, TYPE_ENUM, NO_OFFSET, NO_EXTRA },
1054
1055   /* GL_NV_light_max_exponent */
1056   { GL_MAX_SHININESS_NV, CONTEXT_FLOAT(Const.MaxShininess),
1057     extra_NV_light_max_exponent },
1058   { GL_MAX_SPOT_EXPONENT_NV, CONTEXT_FLOAT(Const.MaxSpotExponent),
1059     extra_NV_light_max_exponent },
1060
1061   /* GL_NV_primitive_restart */
1062   { GL_PRIMITIVE_RESTART_NV, CONTEXT_BOOL(Array.PrimitiveRestart),
1063     extra_NV_primitive_restart },
1064   { GL_PRIMITIVE_RESTART_INDEX_NV, CONTEXT_INT(Array.RestartIndex),
1065     extra_NV_primitive_restart },
1066
1067   /* GL_ARB_vertex_buffer_object */
1068   { GL_INDEX_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
1069     offsetof(struct gl_array_object, Index.BufferObj), NO_EXTRA },
1070   { GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
1071     offsetof(struct gl_array_object, EdgeFlag.BufferObj), NO_EXTRA },
1072   { GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
1073     offsetof(struct gl_array_object, SecondaryColor.BufferObj), NO_EXTRA },
1074   { GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
1075     offsetof(struct gl_array_object, FogCoord.BufferObj), NO_EXTRA },
1076
1077   /* GL_EXT_pixel_buffer_object */
1078   { GL_PIXEL_PACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
1079     extra_EXT_pixel_buffer_object },
1080   { GL_PIXEL_UNPACK_BUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
1081     extra_EXT_pixel_buffer_object },
1082
1083   /* GL_ARB_vertex_program */
1084   { GL_VERTEX_PROGRAM_ARB, /* == GL_VERTEX_PROGRAM_NV */
1085     CONTEXT_BOOL(VertexProgram.Enabled),
1086     extra_ARB_vertex_program_NV_vertex_program },
1087   { GL_VERTEX_PROGRAM_POINT_SIZE_ARB, /* == GL_VERTEX_PROGRAM_POINT_SIZE_NV*/
1088     CONTEXT_BOOL(VertexProgram.PointSizeEnabled),
1089     extra_ARB_vertex_program_NV_vertex_program },
1090   { GL_VERTEX_PROGRAM_TWO_SIDE_ARB, /* == GL_VERTEX_PROGRAM_TWO_SIDE_NV */
1091     CONTEXT_BOOL(VertexProgram.TwoSideEnabled),
1092     extra_ARB_vertex_program_NV_vertex_program },
1093   { GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB, /* == GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
1094     CONTEXT_INT(Const.MaxProgramMatrixStackDepth),
1095     extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
1096   { GL_MAX_PROGRAM_MATRICES_ARB, /* == GL_MAX_TRACK_MATRICES_NV */
1097     CONTEXT_INT(Const.MaxProgramMatrices),
1098     extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
1099   { GL_CURRENT_MATRIX_STACK_DEPTH_ARB, /* == GL_CURRENT_MATRIX_STACK_DEPTH_NV */
1100     LOC_CUSTOM, TYPE_INT, 0,
1101     extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
1102
1103   { GL_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */
1104     LOC_CUSTOM, TYPE_MATRIX, 0,
1105     extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
1106   { GL_TRANSPOSE_CURRENT_MATRIX_ARB, /* == GL_CURRENT_MATRIX_NV */
1107     LOC_CUSTOM, TYPE_MATRIX, 0,
1108     extra_ARB_vertex_program_ARB_fragment_program },
1109
1110   { GL_PROGRAM_ERROR_POSITION_ARB, /* == GL_PROGRAM_ERROR_POSITION_NV */
1111     CONTEXT_INT(Program.ErrorPos),
1112     extra_NV_vertex_program_ARB_vertex_program_ARB_fragment_program_NV_vertex_program },
1113
1114   /* GL_ARB_fragment_program */
1115   { GL_FRAGMENT_PROGRAM_ARB, CONTEXT_BOOL(FragmentProgram.Enabled),
1116     extra_ARB_fragment_program },
1117
1118   /* GL_EXT_depth_bounds_test */
1119   { GL_DEPTH_BOUNDS_TEST_EXT, CONTEXT_BOOL(Depth.BoundsTest),
1120     extra_EXT_depth_bounds_test },
1121   { GL_DEPTH_BOUNDS_EXT, CONTEXT_FLOAT2(Depth.BoundsMin),
1122     extra_EXT_depth_bounds_test },
1123
1124   /* GL_ARB_depth_clamp*/
1125   { GL_DEPTH_CLAMP, CONTEXT_BOOL(Transform.DepthClamp),
1126     extra_ARB_depth_clamp },
1127
1128   /* GL_ARB_draw_buffers */
1129   { GL_DRAW_BUFFER0_ARB, BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA },
1130   { GL_DRAW_BUFFER1_ARB, BUFFER_ENUM(ColorDrawBuffer[1]),
1131     extra_valid_draw_buffer },
1132   { GL_DRAW_BUFFER2_ARB, BUFFER_ENUM(ColorDrawBuffer[2]),
1133     extra_valid_draw_buffer },
1134   { GL_DRAW_BUFFER3_ARB, BUFFER_ENUM(ColorDrawBuffer[3]),
1135     extra_valid_draw_buffer },
1136   { GL_DRAW_BUFFER4_ARB, BUFFER_ENUM(ColorDrawBuffer[4]),
1137     extra_valid_draw_buffer },
1138   { GL_DRAW_BUFFER5_ARB, BUFFER_ENUM(ColorDrawBuffer[5]),
1139     extra_valid_draw_buffer },
1140   { GL_DRAW_BUFFER6_ARB, BUFFER_ENUM(ColorDrawBuffer[6]),
1141     extra_valid_draw_buffer },
1142   { GL_DRAW_BUFFER7_ARB, BUFFER_ENUM(ColorDrawBuffer[7]),
1143     extra_valid_draw_buffer },
1144
1145   /* GL_ATI_fragment_shader */
1146   { GL_NUM_FRAGMENT_REGISTERS_ATI, CONST(6), extra_ATI_fragment_shader },
1147   { GL_NUM_FRAGMENT_CONSTANTS_ATI, CONST(8), extra_ATI_fragment_shader },
1148   { GL_NUM_PASSES_ATI, CONST(2), extra_ATI_fragment_shader },
1149   { GL_NUM_INSTRUCTIONS_PER_PASS_ATI, CONST(8), extra_ATI_fragment_shader },
1150   { GL_NUM_INSTRUCTIONS_TOTAL_ATI, CONST(16), extra_ATI_fragment_shader },
1151   { GL_COLOR_ALPHA_PAIRING_ATI, CONST(GL_TRUE), extra_ATI_fragment_shader },
1152   { GL_NUM_LOOPBACK_COMPONENTS_ATI, CONST(3), extra_ATI_fragment_shader },
1153   { GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI,
1154     CONST(3), extra_ATI_fragment_shader },
1155
1156   /* GL_EXT_framebuffer_object */
1157   { GL_MAX_COLOR_ATTACHMENTS_EXT, CONTEXT_INT(Const.MaxColorAttachments),
1158     extra_EXT_framebuffer_object },
1159
1160   /* GL_EXT_framebuffer_blit
1161    * NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT */
1162   { GL_READ_FRAMEBUFFER_BINDING_EXT, LOC_CUSTOM, TYPE_INT, 0,
1163     extra_EXT_framebuffer_blit },
1164
1165   /* GL_EXT_provoking_vertex */
1166   { GL_PROVOKING_VERTEX_EXT,
1167     CONTEXT_ENUM(Light.ProvokingVertex), extra_EXT_provoking_vertex },
1168   { GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT,
1169     CONTEXT_BOOL(Const.QuadsFollowProvokingVertexConvention),
1170     extra_EXT_provoking_vertex },
1171
1172   /* GL_ARB_framebuffer_object */
1173   { GL_MAX_SAMPLES, CONTEXT_INT(Const.MaxSamples),
1174     extra_ARB_framebuffer_object_EXT_framebuffer_multisample },
1175
1176   /* GL_APPLE_vertex_array_object */
1177   { GL_VERTEX_ARRAY_BINDING_APPLE, ARRAY_INT(Name),
1178     extra_APPLE_vertex_array_object },
1179
1180   /* GL_ARB_seamless_cube_map */
1181   { GL_TEXTURE_CUBE_MAP_SEAMLESS,
1182     CONTEXT_BOOL(Texture.CubeMapSeamless), extra_ARB_seamless_cube_map },
1183
1184   /* GL_ARB_sync */
1185   { GL_MAX_SERVER_WAIT_TIMEOUT,
1186     CONTEXT_INT64(Const.MaxServerWaitTimeout), extra_ARB_sync },
1187
1188   /* GL_EXT_texture_integer */
1189   { GL_RGBA_INTEGER_MODE_EXT, BUFFER_BOOL(_IntegerColor),
1190     extra_EXT_texture_integer },
1191
1192   /* GL_EXT_transform_feedback */
1193   { GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, LOC_CUSTOM, TYPE_INT, 0,
1194     extra_EXT_transform_feedback },
1195   { GL_RASTERIZER_DISCARD, CONTEXT_BOOL(TransformFeedback.RasterDiscard),
1196     extra_EXT_transform_feedback },
1197   { GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
1198     CONTEXT_INT(Const.MaxTransformFeedbackInterleavedComponents),
1199     extra_EXT_transform_feedback },
1200   { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
1201     CONTEXT_INT(Const.MaxTransformFeedbackSeparateAttribs),
1202     extra_EXT_transform_feedback },
1203   { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
1204     CONTEXT_INT(Const.MaxTransformFeedbackSeparateComponents),
1205     extra_EXT_transform_feedback },
1206
1207   /* GL_ARB_transform_feedback2 */
1208   { GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, LOC_CUSTOM, TYPE_BOOLEAN, 0,
1209     extra_ARB_transform_feedback2 },
1210   { GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, LOC_CUSTOM, TYPE_BOOLEAN, 0,
1211     extra_ARB_transform_feedback2 },
1212   { GL_TRANSFORM_FEEDBACK_BINDING, LOC_CUSTOM, TYPE_INT, 0,
1213     extra_ARB_transform_feedback2 },
1214
1215   /* GL_ARB_geometry_shader4 */
1216   { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB,
1217     CONTEXT_INT(Const.MaxGeometryTextureImageUnits),
1218     extra_ARB_geometry_shader4 },
1219   { GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB,
1220     CONTEXT_INT(Const.MaxGeometryOutputVertices),
1221     extra_ARB_geometry_shader4 },
1222   { GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB,
1223     CONTEXT_INT(Const.MaxGeometryTotalOutputComponents),
1224     extra_ARB_geometry_shader4 },
1225   { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB,
1226     CONTEXT_INT(Const.GeometryProgram.MaxUniformComponents),
1227     extra_ARB_geometry_shader4 },
1228   { GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB,
1229     CONTEXT_INT(Const.MaxGeometryVaryingComponents),
1230     extra_ARB_geometry_shader4 },
1231   { GL_MAX_VERTEX_VARYING_COMPONENTS_ARB,
1232     CONTEXT_INT(Const.MaxVertexVaryingComponents),
1233     extra_ARB_geometry_shader4 },
1234
1235   /* GL_ARB_color_buffer_float */
1236   { GL_RGBA_FLOAT_MODE_ARB, BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), 0 },
1237
1238   /* GL_EXT_gpu_shader4 / GL 3.0 */
1239   { GL_MIN_PROGRAM_TEXEL_OFFSET,
1240     CONTEXT_INT(Const.MinProgramTexelOffset),
1241     extra_EXT_gpu_shader4 },
1242   { GL_MAX_PROGRAM_TEXEL_OFFSET,
1243     CONTEXT_INT(Const.MaxProgramTexelOffset),
1244     extra_EXT_gpu_shader4 },
1245
1246   /* GL_ARB_texture_buffer_object */
1247   { GL_MAX_TEXTURE_BUFFER_SIZE_ARB, CONTEXT_INT(Const.MaxTextureBufferSize),
1248     extra_ARB_texture_buffer_object },
1249   { GL_TEXTURE_BINDING_BUFFER_ARB, LOC_CUSTOM, TYPE_INT, 0,
1250     extra_ARB_texture_buffer_object },
1251   { GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB, LOC_CUSTOM, TYPE_INT,
1252     TEXTURE_BUFFER_INDEX, extra_ARB_texture_buffer_object },
1253   { GL_TEXTURE_BUFFER_FORMAT_ARB, LOC_CUSTOM, TYPE_INT, 0,
1254     extra_ARB_texture_buffer_object },
1255   { GL_TEXTURE_BUFFER_ARB, LOC_CUSTOM, TYPE_INT, 0,
1256     extra_ARB_texture_buffer_object },
1257
1258   /* GL_ARB_sampler_objects / GL 3.3 */
1259   { GL_SAMPLER_BINDING,
1260     LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, extra_ARB_sampler_objects },
1261
1262   /* GL 3.0 */
1263   { GL_NUM_EXTENSIONS, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 },
1264   { GL_MAJOR_VERSION, CONTEXT_INT(VersionMajor), extra_version_30 },
1265   { GL_MINOR_VERSION, CONTEXT_INT(VersionMinor), extra_version_30  },
1266   { GL_CONTEXT_FLAGS, CONTEXT_INT(Const.ContextFlags), extra_version_30  },
1267
1268   /* GL3.0 / GL_EXT_framebuffer_sRGB */
1269   { GL_FRAMEBUFFER_SRGB_EXT, CONTEXT_BOOL(Color.sRGBEnabled), extra_EXT_framebuffer_sRGB },
1270   { GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, BUFFER_INT(Visual.sRGBCapable), extra_EXT_framebuffer_sRGB },
1271
1272   /* GL 3.1 */
1273   /* NOTE: different enum values for GL_PRIMITIVE_RESTART_NV
1274    * vs. GL_PRIMITIVE_RESTART!
1275    */
1276   { GL_PRIMITIVE_RESTART, CONTEXT_BOOL(Array.PrimitiveRestart),
1277     extra_version_31 },
1278   { GL_PRIMITIVE_RESTART_INDEX, CONTEXT_INT(Array.RestartIndex),
1279     extra_version_31 },
1280
1281
1282   /* GL 3.2 */
1283   { GL_CONTEXT_PROFILE_MASK, CONTEXT_INT(Const.ProfileMask),
1284     extra_version_32 },
1285
1286   /* GL_ARB_robustness */
1287   { GL_RESET_NOTIFICATION_STRATEGY_ARB, CONTEXT_ENUM(Const.ResetStrategy), NO_EXTRA },
1288#endif /* FEATURE_GL */
1289};
1290
1291/* All we need now is a way to look up the value struct from the enum.
1292 * The code generated by gcc for the old generated big switch
1293 * statement is a big, balanced, open coded if/else tree, essentially
1294 * an unrolled binary search.  It would be natural to sort the new
1295 * enum table and use bsearch(), but we will use a read-only hash
1296 * table instead.  bsearch() has a nice guaranteed worst case
1297 * performance, but we're also guaranteed to hit that worst case
1298 * (log2(n) iterations) for about half the enums.  Instead, using an
1299 * open addressing hash table, we can find the enum on the first try
1300 * for 80% of the enums, 1 collision for 10% and never more than 5
1301 * collisions for any enum (typical numbers).  And the code is very
1302 * simple, even though it feels a little magic. */
1303
1304static unsigned short table[1024];
1305static const int prime_factor = 89, prime_step = 281;
1306
1307#ifdef GET_DEBUG
1308static void
1309print_table_stats(void)
1310{
1311   int i, j, collisions[11], count, hash, mask;
1312   const struct value_desc *d;
1313
1314   count = 0;
1315   mask = Elements(table) - 1;
1316   memset(collisions, 0, sizeof collisions);
1317
1318   for (i = 0; i < Elements(table); i++) {
1319      if (!table[i])
1320	 continue;
1321      count++;
1322      d = &values[table[i]];
1323      hash = (d->pname * prime_factor);
1324      j = 0;
1325      while (1) {
1326	 if (values[table[hash & mask]].pname == d->pname)
1327	    break;
1328	 hash += prime_step;
1329	 j++;
1330      }
1331
1332      if (j < 10)
1333	 collisions[j]++;
1334      else
1335	 collisions[10]++;
1336   }
1337
1338   printf("number of enums: %d (total %d)\n", count, Elements(values));
1339   for (i = 0; i < Elements(collisions) - 1; i++)
1340      if (collisions[i] > 0)
1341	 printf("  %d enums with %d %scollisions\n",
1342		collisions[i], i, i == 10 ? "or more " : "");
1343}
1344#endif
1345
1346/**
1347 * Initialize the enum hash for a given API
1348 *
1349 * This is called from one_time_init() to insert the enum values that
1350 * are valid for the API in question into the enum hash table.
1351 *
1352 * \param the current context, for determining the API in question
1353 */
1354void _mesa_init_get_hash(struct gl_context *ctx)
1355{
1356   int i, hash, index, mask;
1357   int api_mask = 0, api_bit;
1358
1359   mask = Elements(table) - 1;
1360   api_bit = 1 << ctx->API;
1361
1362   for (i = 0; i < Elements(values); i++) {
1363      if (values[i].type == TYPE_API_MASK) {
1364	 api_mask = values[i].offset;
1365	 continue;
1366      }
1367      if (!(api_mask & api_bit))
1368	 continue;
1369
1370      hash = (values[i].pname * prime_factor) & mask;
1371      while (1) {
1372	 index = hash & mask;
1373	 if (!table[index]) {
1374	    table[index] = i;
1375	    break;
1376	 }
1377	 hash += prime_step;
1378      }
1379   }
1380
1381#ifdef GET_DEBUG
1382   print_table_stats();
1383#endif
1384}
1385
1386/**
1387 * Handle irregular enums
1388 *
1389 * Some values don't conform to the "well-known type at context
1390 * pointer + offset" pattern, so we have this function to catch all
1391 * the corner cases.  Typically, it's a computed value or a one-off
1392 * pointer to a custom struct or something.
1393 *
1394 * In this case we can't return a pointer to the value, so we'll have
1395 * to use the temporary variable 'v' declared back in the calling
1396 * glGet*v() function to store the result.
1397 *
1398 * \param ctx the current context
1399 * \param d the struct value_desc that describes the enum
1400 * \param v pointer to the tmp declared in the calling glGet*v() function
1401 */
1402static void
1403find_custom_value(struct gl_context *ctx, const struct value_desc *d, union value *v)
1404{
1405   struct gl_buffer_object **buffer_obj;
1406   struct gl_client_array *array;
1407   GLuint unit, *p;
1408
1409   switch (d->pname) {
1410   case GL_TEXTURE_1D:
1411   case GL_TEXTURE_2D:
1412   case GL_TEXTURE_3D:
1413   case GL_TEXTURE_1D_ARRAY_EXT:
1414   case GL_TEXTURE_2D_ARRAY_EXT:
1415   case GL_TEXTURE_CUBE_MAP_ARB:
1416   case GL_TEXTURE_RECTANGLE_NV:
1417      v->value_bool = _mesa_IsEnabled(d->pname);
1418      break;
1419
1420   case GL_LINE_STIPPLE_PATTERN:
1421      /* This is the only GLushort, special case it here by promoting
1422       * to an int rather than introducing a new type. */
1423      v->value_int = ctx->Line.StipplePattern;
1424      break;
1425
1426   case GL_CURRENT_RASTER_TEXTURE_COORDS:
1427      unit = ctx->Texture.CurrentUnit;
1428      v->value_float_4[0] = ctx->Current.RasterTexCoords[unit][0];
1429      v->value_float_4[1] = ctx->Current.RasterTexCoords[unit][1];
1430      v->value_float_4[2] = ctx->Current.RasterTexCoords[unit][2];
1431      v->value_float_4[3] = ctx->Current.RasterTexCoords[unit][3];
1432      break;
1433
1434   case GL_CURRENT_TEXTURE_COORDS:
1435      unit = ctx->Texture.CurrentUnit;
1436      v->value_float_4[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0];
1437      v->value_float_4[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1];
1438      v->value_float_4[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2];
1439      v->value_float_4[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3];
1440      break;
1441
1442   case GL_COLOR_WRITEMASK:
1443      v->value_int_4[0] = ctx->Color.ColorMask[0][RCOMP] ? 1 : 0;
1444      v->value_int_4[1] = ctx->Color.ColorMask[0][GCOMP] ? 1 : 0;
1445      v->value_int_4[2] = ctx->Color.ColorMask[0][BCOMP] ? 1 : 0;
1446      v->value_int_4[3] = ctx->Color.ColorMask[0][ACOMP] ? 1 : 0;
1447      break;
1448
1449   case GL_EDGE_FLAG:
1450      v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0;
1451      break;
1452
1453   case GL_READ_BUFFER:
1454      v->value_enum = ctx->ReadBuffer->ColorReadBuffer;
1455      break;
1456
1457   case GL_MAP2_GRID_DOMAIN:
1458      v->value_float_4[0] = ctx->Eval.MapGrid2u1;
1459      v->value_float_4[1] = ctx->Eval.MapGrid2u2;
1460      v->value_float_4[2] = ctx->Eval.MapGrid2v1;
1461      v->value_float_4[3] = ctx->Eval.MapGrid2v2;
1462      break;
1463
1464   case GL_TEXTURE_STACK_DEPTH:
1465      unit = ctx->Texture.CurrentUnit;
1466      v->value_int = ctx->TextureMatrixStack[unit].Depth + 1;
1467      break;
1468   case GL_TEXTURE_MATRIX:
1469      unit = ctx->Texture.CurrentUnit;
1470      v->value_matrix = ctx->TextureMatrixStack[unit].Top;
1471      break;
1472
1473   case GL_TEXTURE_COORD_ARRAY:
1474   case GL_TEXTURE_COORD_ARRAY_SIZE:
1475   case GL_TEXTURE_COORD_ARRAY_TYPE:
1476   case GL_TEXTURE_COORD_ARRAY_STRIDE:
1477      array = &ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture];
1478      v->value_int = *(GLuint *) ((char *) array + d->offset);
1479      break;
1480
1481   case GL_ACTIVE_TEXTURE_ARB:
1482      v->value_int = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
1483      break;
1484   case GL_CLIENT_ACTIVE_TEXTURE_ARB:
1485      v->value_int = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
1486      break;
1487
1488   case GL_MODELVIEW_STACK_DEPTH:
1489   case GL_PROJECTION_STACK_DEPTH:
1490      v->value_int = *(GLint *) ((char *) ctx + d->offset) + 1;
1491      break;
1492
1493   case GL_MAX_TEXTURE_SIZE:
1494   case GL_MAX_3D_TEXTURE_SIZE:
1495   case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
1496      p = (GLuint *) ((char *) ctx + d->offset);
1497      v->value_int = 1 << (*p - 1);
1498      break;
1499
1500   case GL_SCISSOR_BOX:
1501      v->value_int_4[0] = ctx->Scissor.X;
1502      v->value_int_4[1] = ctx->Scissor.Y;
1503      v->value_int_4[2] = ctx->Scissor.Width;
1504      v->value_int_4[3] = ctx->Scissor.Height;
1505      break;
1506
1507   case GL_LIST_INDEX:
1508      v->value_int =
1509	 ctx->ListState.CurrentList ? ctx->ListState.CurrentList->Name : 0;
1510      break;
1511   case GL_LIST_MODE:
1512      if (!ctx->CompileFlag)
1513	 v->value_enum = 0;
1514      else if (ctx->ExecuteFlag)
1515	 v->value_enum = GL_COMPILE_AND_EXECUTE;
1516      else
1517	 v->value_enum = GL_COMPILE;
1518      break;
1519
1520   case GL_VIEWPORT:
1521      v->value_int_4[0] = ctx->Viewport.X;
1522      v->value_int_4[1] = ctx->Viewport.Y;
1523      v->value_int_4[2] = ctx->Viewport.Width;
1524      v->value_int_4[3] = ctx->Viewport.Height;
1525      break;
1526
1527   case GL_ACTIVE_STENCIL_FACE_EXT:
1528      v->value_enum = ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT;
1529      break;
1530
1531   case GL_STENCIL_FAIL:
1532      v->value_enum = ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace];
1533      break;
1534   case GL_STENCIL_FUNC:
1535      v->value_enum = ctx->Stencil.Function[ctx->Stencil.ActiveFace];
1536      break;
1537   case GL_STENCIL_PASS_DEPTH_FAIL:
1538      v->value_enum = ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace];
1539      break;
1540   case GL_STENCIL_PASS_DEPTH_PASS:
1541      v->value_enum = ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace];
1542      break;
1543   case GL_STENCIL_REF:
1544      v->value_int = ctx->Stencil.Ref[ctx->Stencil.ActiveFace];
1545      break;
1546   case GL_STENCIL_VALUE_MASK:
1547      v->value_int = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace];
1548      break;
1549   case GL_STENCIL_WRITEMASK:
1550      v->value_int = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace];
1551      break;
1552
1553   case GL_NUM_EXTENSIONS:
1554      v->value_int = _mesa_get_extension_count(ctx);
1555      break;
1556
1557   case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1558      v->value_int = _mesa_get_color_read_type(ctx);
1559      break;
1560   case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1561      v->value_int = _mesa_get_color_read_format(ctx);
1562      break;
1563
1564   case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
1565      v->value_int = ctx->CurrentStack->Depth + 1;
1566      break;
1567   case GL_CURRENT_MATRIX_ARB:
1568   case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
1569      v->value_matrix = ctx->CurrentStack->Top;
1570      break;
1571
1572   case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
1573      v->value_int = _mesa_get_compressed_formats(ctx, NULL);
1574      break;
1575   case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
1576      v->value_int_n.n =
1577	 _mesa_get_compressed_formats(ctx, v->value_int_n.ints);
1578      ASSERT(v->value_int_n.n <= 100);
1579      break;
1580
1581   case GL_MAX_VARYING_FLOATS_ARB:
1582      v->value_int = ctx->Const.MaxVarying * 4;
1583      break;
1584
1585   /* Various object names */
1586
1587   case GL_TEXTURE_BINDING_1D:
1588   case GL_TEXTURE_BINDING_2D:
1589   case GL_TEXTURE_BINDING_3D:
1590   case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
1591   case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
1592   case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
1593   case GL_TEXTURE_BINDING_RECTANGLE_NV:
1594      unit = ctx->Texture.CurrentUnit;
1595      v->value_int =
1596	 ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name;
1597      break;
1598
1599   /* GL_ARB_vertex_buffer_object */
1600   case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
1601   case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
1602   case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
1603   case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
1604   case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
1605   case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
1606   case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
1607      buffer_obj = (struct gl_buffer_object **)
1608	 ((char *) ctx->Array.ArrayObj + d->offset);
1609      v->value_int = (*buffer_obj)->Name;
1610      break;
1611   case GL_ARRAY_BUFFER_BINDING_ARB:
1612      v->value_int = ctx->Array.ArrayBufferObj->Name;
1613      break;
1614   case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
1615      v->value_int =
1616	 ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name;
1617      break;
1618   case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
1619      v->value_int = ctx->Array.ElementArrayBufferObj->Name;
1620      break;
1621
1622   /* ARB_copy_buffer */
1623   case GL_COPY_READ_BUFFER:
1624      v->value_int = ctx->CopyReadBuffer->Name;
1625      break;
1626   case GL_COPY_WRITE_BUFFER:
1627      v->value_int = ctx->CopyWriteBuffer->Name;
1628      break;
1629
1630   case GL_FRAGMENT_PROGRAM_BINDING_NV:
1631      v->value_int =
1632	 ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0;
1633      break;
1634   case GL_VERTEX_PROGRAM_BINDING_NV:
1635      v->value_int =
1636	 ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0;
1637      break;
1638   case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
1639      v->value_int = ctx->Pack.BufferObj->Name;
1640      break;
1641   case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
1642      v->value_int = ctx->Unpack.BufferObj->Name;
1643      break;
1644   case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1645      v->value_int = ctx->TransformFeedback.CurrentBuffer->Name;
1646      break;
1647   case GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED:
1648      v->value_int = ctx->TransformFeedback.CurrentObject->Paused;
1649      break;
1650   case GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE:
1651      v->value_int = ctx->TransformFeedback.CurrentObject->Active;
1652      break;
1653   case GL_TRANSFORM_FEEDBACK_BINDING:
1654      v->value_int = ctx->TransformFeedback.CurrentObject->Name;
1655      break;
1656   case GL_CURRENT_PROGRAM:
1657      v->value_int =
1658	 ctx->Shader.ActiveProgram ? ctx->Shader.ActiveProgram->Name : 0;
1659      break;
1660   case GL_READ_FRAMEBUFFER_BINDING_EXT:
1661      v->value_int = ctx->ReadBuffer->Name;
1662      break;
1663   case GL_RENDERBUFFER_BINDING_EXT:
1664      v->value_int =
1665	 ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
1666      break;
1667   case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1668      v->value_int = ctx->Array.ArrayObj->PointSize.BufferObj->Name;
1669      break;
1670
1671   case GL_FOG_COLOR:
1672      if(ctx->Color._ClampFragmentColor)
1673         COPY_4FV(v->value_float_4, ctx->Fog.Color);
1674      else
1675         COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped);
1676      break;
1677   case GL_COLOR_CLEAR_VALUE:
1678      if(ctx->Color._ClampFragmentColor) {
1679         v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F);
1680         v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F);
1681         v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F);
1682         v->value_float_4[3] = CLAMP(ctx->Color.ClearColor.f[3], 0.0F, 1.0F);
1683      } else
1684         COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f);
1685      break;
1686   case GL_BLEND_COLOR_EXT:
1687      if(ctx->Color._ClampFragmentColor)
1688         COPY_4FV(v->value_float_4, ctx->Color.BlendColor);
1689      else
1690         COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped);
1691      break;
1692   case GL_ALPHA_TEST_REF:
1693      if(ctx->Color._ClampFragmentColor)
1694         v->value_float = ctx->Color.AlphaRef;
1695      else
1696         v->value_float = ctx->Color.AlphaRefUnclamped;
1697      break;
1698   case GL_MAX_VERTEX_UNIFORM_VECTORS:
1699      v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4;
1700      break;
1701
1702   case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1703      v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
1704      break;
1705
1706   /* GL_ARB_texture_buffer_object */
1707   case GL_TEXTURE_BUFFER_ARB:
1708      v->value_int = ctx->Texture.BufferObject->Name;
1709      break;
1710   case GL_TEXTURE_BINDING_BUFFER_ARB:
1711      unit = ctx->Texture.CurrentUnit;
1712      v->value_int =
1713         ctx->Texture.Unit[unit].CurrentTex[TEXTURE_BUFFER_INDEX]->Name;
1714      break;
1715   case GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB:
1716      {
1717         struct gl_buffer_object *buf =
1718            ctx->Texture.Unit[ctx->Texture.CurrentUnit]
1719            .CurrentTex[TEXTURE_BUFFER_INDEX]->BufferObject;
1720         v->value_int = buf ? buf->Name : 0;
1721      }
1722      break;
1723   case GL_TEXTURE_BUFFER_FORMAT_ARB:
1724      v->value_int = ctx->Texture.Unit[ctx->Texture.CurrentUnit]
1725         .CurrentTex[TEXTURE_BUFFER_INDEX]->BufferObjectFormat;
1726      break;
1727
1728   /* GL_ARB_sampler_objects */
1729   case GL_SAMPLER_BINDING:
1730      {
1731         struct gl_sampler_object *samp =
1732            ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler;
1733         v->value_int = samp ? samp->Name : 0;
1734      }
1735      break;
1736   }
1737}
1738
1739/**
1740 * Check extra constraints on a struct value_desc descriptor
1741 *
1742 * If a struct value_desc has a non-NULL extra pointer, it means that
1743 * there are a number of extra constraints to check or actions to
1744 * perform.  The extras is just an integer array where each integer
1745 * encode different constraints or actions.
1746 *
1747 * \param ctx current context
1748 * \param func name of calling glGet*v() function for error reporting
1749 * \param d the struct value_desc that has the extra constraints
1750 *
1751 * \return GL_FALSE if one of the constraints was not satisfied,
1752 *     otherwise GL_TRUE.
1753 */
1754static GLboolean
1755check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d)
1756{
1757   const GLuint version = ctx->VersionMajor * 10 + ctx->VersionMinor;
1758   int total, enabled;
1759   const int *e;
1760
1761   total = 0;
1762   enabled = 0;
1763   for (e = d->extra; *e != EXTRA_END; e++)
1764      switch (*e) {
1765      case EXTRA_VERSION_30:
1766	 if (version >= 30) {
1767	    total++;
1768	    enabled++;
1769	 }
1770	 break;
1771      case EXTRA_VERSION_31:
1772	 if (version >= 31) {
1773	    total++;
1774	    enabled++;
1775	 }
1776	 break;
1777      case EXTRA_VERSION_32:
1778	 if (version >= 32) {
1779	    total++;
1780	    enabled++;
1781	 }
1782	 break;
1783      case EXTRA_NEW_FRAG_CLAMP:
1784         if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1785            _mesa_update_state(ctx);
1786         break;
1787      case EXTRA_VERSION_ES2:
1788	 if (ctx->API == API_OPENGLES2) {
1789	    total++;
1790	    enabled++;
1791	 }
1792	 break;
1793      case EXTRA_NEW_BUFFERS:
1794	 if (ctx->NewState & _NEW_BUFFERS)
1795	    _mesa_update_state(ctx);
1796	 break;
1797      case EXTRA_FLUSH_CURRENT:
1798	 FLUSH_CURRENT(ctx, 0);
1799	 break;
1800      case EXTRA_VALID_DRAW_BUFFER:
1801	 if (d->pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
1802	    _mesa_error(ctx, GL_INVALID_OPERATION, "%s(draw buffer %u)",
1803			func, d->pname - GL_DRAW_BUFFER0_ARB);
1804	    return GL_FALSE;
1805	 }
1806	 break;
1807      case EXTRA_VALID_TEXTURE_UNIT:
1808	 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
1809	    _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture %u)",
1810			func, ctx->Texture.CurrentUnit);
1811	    return GL_FALSE;
1812	 }
1813	 break;
1814      case EXTRA_VALID_CLIP_DISTANCE:
1815	 if (d->pname - GL_CLIP_DISTANCE0 >= ctx->Const.MaxClipPlanes) {
1816	    _mesa_error(ctx, GL_INVALID_ENUM, "%s(clip distance %u)",
1817			func, d->pname - GL_CLIP_DISTANCE0);
1818	    return GL_FALSE;
1819	 }
1820	 break;
1821      case EXTRA_END:
1822	 break;
1823      default: /* *e is a offset into the extension struct */
1824	 total++;
1825	 if (*(GLboolean *) ((char *) &ctx->Extensions + *e))
1826	    enabled++;
1827	 break;
1828      }
1829
1830   if (total > 0 && enabled == 0) {
1831      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
1832                  _mesa_lookup_enum_by_nr(d->pname));
1833      return GL_FALSE;
1834   }
1835
1836   return GL_TRUE;
1837}
1838
1839static const struct value_desc error_value =
1840   { 0, 0, TYPE_INVALID, NO_OFFSET, NO_EXTRA };
1841
1842/**
1843 * Find the struct value_desc corresponding to the enum 'pname'.
1844 *
1845 * We hash the enum value to get an index into the 'table' array,
1846 * which holds the index in the 'values' array of struct value_desc.
1847 * Once we've found the entry, we do the extra checks, if any, then
1848 * look up the value and return a pointer to it.
1849 *
1850 * If the value has to be computed (for example, it's the result of a
1851 * function call or we need to add 1 to it), we use the tmp 'v' to
1852 * store the result.
1853 *
1854 * \param func name of glGet*v() func for error reporting
1855 * \param pname the enum value we're looking up
1856 * \param p is were we return the pointer to the value
1857 * \param v a tmp union value variable in the calling glGet*v() function
1858 *
1859 * \return the struct value_desc corresponding to the enum or a struct
1860 *     value_desc of TYPE_INVALID if not found.  This lets the calling
1861 *     glGet*v() function jump right into a switch statement and
1862 *     handle errors there instead of having to check for NULL.
1863 */
1864static const struct value_desc *
1865find_value(const char *func, GLenum pname, void **p, union value *v)
1866{
1867   GET_CURRENT_CONTEXT(ctx);
1868   struct gl_texture_unit *unit;
1869   int mask, hash;
1870   const struct value_desc *d;
1871
1872   mask = Elements(table) - 1;
1873   hash = (pname * prime_factor);
1874   while (1) {
1875      d = &values[table[hash & mask]];
1876
1877      /* If the enum isn't valid, the hash walk ends with index 0,
1878       * which is the API mask entry at the beginning of values[]. */
1879      if (unlikely(d->type == TYPE_API_MASK)) {
1880	 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
1881                     _mesa_lookup_enum_by_nr(pname));
1882	 return &error_value;
1883      }
1884
1885      if (likely(d->pname == pname))
1886	 break;
1887
1888      hash += prime_step;
1889   }
1890
1891   if (unlikely(d->extra && !check_extra(ctx, func, d)))
1892      return &error_value;
1893
1894   switch (d->location) {
1895   case LOC_BUFFER:
1896      *p = ((char *) ctx->DrawBuffer + d->offset);
1897      return d;
1898   case LOC_CONTEXT:
1899      *p = ((char *) ctx + d->offset);
1900      return d;
1901   case LOC_ARRAY:
1902      *p = ((char *) ctx->Array.ArrayObj + d->offset);
1903      return d;
1904   case LOC_TEXUNIT:
1905      unit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1906      *p = ((char *) unit + d->offset);
1907      return d;
1908   case LOC_CUSTOM:
1909      find_custom_value(ctx, d, v);
1910      *p = v;
1911      return d;
1912   default:
1913      assert(0);
1914      break;
1915   }
1916
1917   /* silence warning */
1918   return &error_value;
1919}
1920
1921static const int transpose[] = {
1922   0, 4,  8, 12,
1923   1, 5,  9, 13,
1924   2, 6, 10, 14,
1925   3, 7, 11, 15
1926};
1927
1928void GLAPIENTRY
1929_mesa_GetBooleanv(GLenum pname, GLboolean *params)
1930{
1931   const struct value_desc *d;
1932   union value v;
1933   GLmatrix *m;
1934   int shift, i;
1935   void *p;
1936   GET_CURRENT_CONTEXT(ctx);
1937
1938   ASSERT_OUTSIDE_BEGIN_END(ctx);
1939
1940   d = find_value("glGetBooleanv", pname, &p, &v);
1941   switch (d->type) {
1942   case TYPE_INVALID:
1943      break;
1944   case TYPE_CONST:
1945      params[0] = INT_TO_BOOLEAN(d->offset);
1946      break;
1947
1948   case TYPE_FLOAT_4:
1949   case TYPE_FLOATN_4:
1950      params[3] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[3]);
1951   case TYPE_FLOAT_3:
1952   case TYPE_FLOATN_3:
1953      params[2] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[2]);
1954   case TYPE_FLOAT_2:
1955   case TYPE_FLOATN_2:
1956      params[1] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[1]);
1957   case TYPE_FLOAT:
1958   case TYPE_FLOATN:
1959      params[0] = FLOAT_TO_BOOLEAN(((GLfloat *) p)[0]);
1960      break;
1961
1962   case TYPE_DOUBLEN:
1963      params[0] = FLOAT_TO_BOOLEAN(((GLdouble *) p)[0]);
1964      break;
1965
1966   case TYPE_INT_4:
1967      params[3] = INT_TO_BOOLEAN(((GLint *) p)[3]);
1968   case TYPE_INT_3:
1969      params[2] = INT_TO_BOOLEAN(((GLint *) p)[2]);
1970   case TYPE_INT_2:
1971   case TYPE_ENUM_2:
1972      params[1] = INT_TO_BOOLEAN(((GLint *) p)[1]);
1973   case TYPE_INT:
1974   case TYPE_ENUM:
1975      params[0] = INT_TO_BOOLEAN(((GLint *) p)[0]);
1976      break;
1977
1978   case TYPE_INT_N:
1979      for (i = 0; i < v.value_int_n.n; i++)
1980	 params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]);
1981      break;
1982
1983   case TYPE_INT64:
1984      params[0] = INT64_TO_BOOLEAN(((GLint64 *) p)[0]);
1985      break;
1986
1987   case TYPE_BOOLEAN:
1988      params[0] = ((GLboolean*) p)[0];
1989      break;
1990
1991   case TYPE_MATRIX:
1992      m = *(GLmatrix **) p;
1993      for (i = 0; i < 16; i++)
1994	 params[i] = FLOAT_TO_BOOLEAN(m->m[i]);
1995      break;
1996
1997   case TYPE_MATRIX_T:
1998      m = *(GLmatrix **) p;
1999      for (i = 0; i < 16; i++)
2000	 params[i] = FLOAT_TO_BOOLEAN(m->m[transpose[i]]);
2001      break;
2002
2003   case TYPE_BIT_0:
2004   case TYPE_BIT_1:
2005   case TYPE_BIT_2:
2006   case TYPE_BIT_3:
2007   case TYPE_BIT_4:
2008   case TYPE_BIT_5:
2009   case TYPE_BIT_6:
2010   case TYPE_BIT_7:
2011      shift = d->type - TYPE_BIT_0;
2012      params[0] = (*(GLbitfield *) p >> shift) & 1;
2013      break;
2014   }
2015}
2016
2017void GLAPIENTRY
2018_mesa_GetFloatv(GLenum pname, GLfloat *params)
2019{
2020   const struct value_desc *d;
2021   union value v;
2022   GLmatrix *m;
2023   int shift, i;
2024   void *p;
2025   GET_CURRENT_CONTEXT(ctx);
2026
2027   ASSERT_OUTSIDE_BEGIN_END(ctx);
2028
2029   d = find_value("glGetFloatv", pname, &p, &v);
2030   switch (d->type) {
2031   case TYPE_INVALID:
2032      break;
2033   case TYPE_CONST:
2034      params[0] = (GLfloat) d->offset;
2035      break;
2036
2037   case TYPE_FLOAT_4:
2038   case TYPE_FLOATN_4:
2039      params[3] = ((GLfloat *) p)[3];
2040   case TYPE_FLOAT_3:
2041   case TYPE_FLOATN_3:
2042      params[2] = ((GLfloat *) p)[2];
2043   case TYPE_FLOAT_2:
2044   case TYPE_FLOATN_2:
2045      params[1] = ((GLfloat *) p)[1];
2046   case TYPE_FLOAT:
2047   case TYPE_FLOATN:
2048      params[0] = ((GLfloat *) p)[0];
2049      break;
2050
2051   case TYPE_DOUBLEN:
2052      params[0] = ((GLdouble *) p)[0];
2053      break;
2054
2055   case TYPE_INT_4:
2056      params[3] = (GLfloat) (((GLint *) p)[3]);
2057   case TYPE_INT_3:
2058      params[2] = (GLfloat) (((GLint *) p)[2]);
2059   case TYPE_INT_2:
2060   case TYPE_ENUM_2:
2061      params[1] = (GLfloat) (((GLint *) p)[1]);
2062   case TYPE_INT:
2063   case TYPE_ENUM:
2064      params[0] = (GLfloat) (((GLint *) p)[0]);
2065      break;
2066
2067   case TYPE_INT_N:
2068      for (i = 0; i < v.value_int_n.n; i++)
2069	 params[i] = INT_TO_FLOAT(v.value_int_n.ints[i]);
2070      break;
2071
2072   case TYPE_INT64:
2073      params[0] = ((GLint64 *) p)[0];
2074      break;
2075
2076   case TYPE_BOOLEAN:
2077      params[0] = BOOLEAN_TO_FLOAT(*(GLboolean*) p);
2078      break;
2079
2080   case TYPE_MATRIX:
2081      m = *(GLmatrix **) p;
2082      for (i = 0; i < 16; i++)
2083	 params[i] = m->m[i];
2084      break;
2085
2086   case TYPE_MATRIX_T:
2087      m = *(GLmatrix **) p;
2088      for (i = 0; i < 16; i++)
2089	 params[i] = m->m[transpose[i]];
2090      break;
2091
2092   case TYPE_BIT_0:
2093   case TYPE_BIT_1:
2094   case TYPE_BIT_2:
2095   case TYPE_BIT_3:
2096   case TYPE_BIT_4:
2097   case TYPE_BIT_5:
2098   case TYPE_BIT_6:
2099   case TYPE_BIT_7:
2100      shift = d->type - TYPE_BIT_0;
2101      params[0] = BOOLEAN_TO_FLOAT((*(GLbitfield *) p >> shift) & 1);
2102      break;
2103   }
2104}
2105
2106void GLAPIENTRY
2107_mesa_GetIntegerv(GLenum pname, GLint *params)
2108{
2109   const struct value_desc *d;
2110   union value v;
2111   GLmatrix *m;
2112   int shift, i;
2113   void *p;
2114   GET_CURRENT_CONTEXT(ctx);
2115
2116   ASSERT_OUTSIDE_BEGIN_END(ctx);
2117
2118   d = find_value("glGetIntegerv", pname, &p, &v);
2119   switch (d->type) {
2120   case TYPE_INVALID:
2121      break;
2122   case TYPE_CONST:
2123      params[0] = d->offset;
2124      break;
2125
2126   case TYPE_FLOAT_4:
2127      params[3] = IROUND(((GLfloat *) p)[3]);
2128   case TYPE_FLOAT_3:
2129      params[2] = IROUND(((GLfloat *) p)[2]);
2130   case TYPE_FLOAT_2:
2131      params[1] = IROUND(((GLfloat *) p)[1]);
2132   case TYPE_FLOAT:
2133      params[0] = IROUND(((GLfloat *) p)[0]);
2134      break;
2135
2136   case TYPE_FLOATN_4:
2137      params[3] = FLOAT_TO_INT(((GLfloat *) p)[3]);
2138   case TYPE_FLOATN_3:
2139      params[2] = FLOAT_TO_INT(((GLfloat *) p)[2]);
2140   case TYPE_FLOATN_2:
2141      params[1] = FLOAT_TO_INT(((GLfloat *) p)[1]);
2142   case TYPE_FLOATN:
2143      params[0] = FLOAT_TO_INT(((GLfloat *) p)[0]);
2144      break;
2145
2146   case TYPE_DOUBLEN:
2147      params[0] = FLOAT_TO_INT(((GLdouble *) p)[0]);
2148      break;
2149
2150   case TYPE_INT_4:
2151      params[3] = ((GLint *) p)[3];
2152   case TYPE_INT_3:
2153      params[2] = ((GLint *) p)[2];
2154   case TYPE_INT_2:
2155   case TYPE_ENUM_2:
2156      params[1] = ((GLint *) p)[1];
2157   case TYPE_INT:
2158   case TYPE_ENUM:
2159      params[0] = ((GLint *) p)[0];
2160      break;
2161
2162   case TYPE_INT_N:
2163      for (i = 0; i < v.value_int_n.n; i++)
2164	 params[i] = v.value_int_n.ints[i];
2165      break;
2166
2167   case TYPE_INT64:
2168      params[0] = INT64_TO_INT(((GLint64 *) p)[0]);
2169      break;
2170
2171   case TYPE_BOOLEAN:
2172      params[0] = BOOLEAN_TO_INT(*(GLboolean*) p);
2173      break;
2174
2175   case TYPE_MATRIX:
2176      m = *(GLmatrix **) p;
2177      for (i = 0; i < 16; i++)
2178	 params[i] = FLOAT_TO_INT(m->m[i]);
2179      break;
2180
2181   case TYPE_MATRIX_T:
2182      m = *(GLmatrix **) p;
2183      for (i = 0; i < 16; i++)
2184	 params[i] = FLOAT_TO_INT(m->m[transpose[i]]);
2185      break;
2186
2187   case TYPE_BIT_0:
2188   case TYPE_BIT_1:
2189   case TYPE_BIT_2:
2190   case TYPE_BIT_3:
2191   case TYPE_BIT_4:
2192   case TYPE_BIT_5:
2193   case TYPE_BIT_6:
2194   case TYPE_BIT_7:
2195      shift = d->type - TYPE_BIT_0;
2196      params[0] = (*(GLbitfield *) p >> shift) & 1;
2197      break;
2198   }
2199}
2200
2201#if FEATURE_ARB_sync
2202void GLAPIENTRY
2203_mesa_GetInteger64v(GLenum pname, GLint64 *params)
2204{
2205   const struct value_desc *d;
2206   union value v;
2207   GLmatrix *m;
2208   int shift, i;
2209   void *p;
2210   GET_CURRENT_CONTEXT(ctx);
2211
2212   ASSERT_OUTSIDE_BEGIN_END(ctx);
2213
2214   d = find_value("glGetInteger64v", pname, &p, &v);
2215   switch (d->type) {
2216   case TYPE_INVALID:
2217      break;
2218   case TYPE_CONST:
2219      params[0] = d->offset;
2220      break;
2221
2222   case TYPE_FLOAT_4:
2223      params[3] = IROUND64(((GLfloat *) p)[3]);
2224   case TYPE_FLOAT_3:
2225      params[2] = IROUND64(((GLfloat *) p)[2]);
2226   case TYPE_FLOAT_2:
2227      params[1] = IROUND64(((GLfloat *) p)[1]);
2228   case TYPE_FLOAT:
2229      params[0] = IROUND64(((GLfloat *) p)[0]);
2230      break;
2231
2232   case TYPE_FLOATN_4:
2233      params[3] = FLOAT_TO_INT64(((GLfloat *) p)[3]);
2234   case TYPE_FLOATN_3:
2235      params[2] = FLOAT_TO_INT64(((GLfloat *) p)[2]);
2236   case TYPE_FLOATN_2:
2237      params[1] = FLOAT_TO_INT64(((GLfloat *) p)[1]);
2238   case TYPE_FLOATN:
2239      params[0] = FLOAT_TO_INT64(((GLfloat *) p)[0]);
2240      break;
2241
2242   case TYPE_DOUBLEN:
2243      params[0] = FLOAT_TO_INT64(((GLdouble *) p)[0]);
2244      break;
2245
2246   case TYPE_INT_4:
2247      params[3] = ((GLint *) p)[3];
2248   case TYPE_INT_3:
2249      params[2] = ((GLint *) p)[2];
2250   case TYPE_INT_2:
2251   case TYPE_ENUM_2:
2252      params[1] = ((GLint *) p)[1];
2253   case TYPE_INT:
2254   case TYPE_ENUM:
2255      params[0] = ((GLint *) p)[0];
2256      break;
2257
2258   case TYPE_INT_N:
2259      for (i = 0; i < v.value_int_n.n; i++)
2260	 params[i] = INT_TO_BOOLEAN(v.value_int_n.ints[i]);
2261      break;
2262
2263   case TYPE_INT64:
2264      params[0] = ((GLint64 *) p)[0];
2265      break;
2266
2267   case TYPE_BOOLEAN:
2268      params[0] = ((GLboolean*) p)[0];
2269      break;
2270
2271   case TYPE_MATRIX:
2272      m = *(GLmatrix **) p;
2273      for (i = 0; i < 16; i++)
2274	 params[i] = FLOAT_TO_INT64(m->m[i]);
2275      break;
2276
2277   case TYPE_MATRIX_T:
2278      m = *(GLmatrix **) p;
2279      for (i = 0; i < 16; i++)
2280	 params[i] = FLOAT_TO_INT64(m->m[transpose[i]]);
2281      break;
2282
2283   case TYPE_BIT_0:
2284   case TYPE_BIT_1:
2285   case TYPE_BIT_2:
2286   case TYPE_BIT_3:
2287   case TYPE_BIT_4:
2288   case TYPE_BIT_5:
2289   case TYPE_BIT_6:
2290   case TYPE_BIT_7:
2291      shift = d->type - TYPE_BIT_0;
2292      params[0] = (*(GLbitfield *) p >> shift) & 1;
2293      break;
2294   }
2295}
2296#endif /* FEATURE_ARB_sync */
2297
2298void GLAPIENTRY
2299_mesa_GetDoublev(GLenum pname, GLdouble *params)
2300{
2301   const struct value_desc *d;
2302   union value v;
2303   GLmatrix *m;
2304   int shift, i;
2305   void *p;
2306   GET_CURRENT_CONTEXT(ctx);
2307
2308   ASSERT_OUTSIDE_BEGIN_END(ctx);
2309
2310   d = find_value("glGetDoublev", pname, &p, &v);
2311   switch (d->type) {
2312   case TYPE_INVALID:
2313      break;
2314   case TYPE_CONST:
2315      params[0] = d->offset;
2316      break;
2317
2318   case TYPE_FLOAT_4:
2319   case TYPE_FLOATN_4:
2320      params[3] = ((GLfloat *) p)[3];
2321   case TYPE_FLOAT_3:
2322   case TYPE_FLOATN_3:
2323      params[2] = ((GLfloat *) p)[2];
2324   case TYPE_FLOAT_2:
2325   case TYPE_FLOATN_2:
2326      params[1] = ((GLfloat *) p)[1];
2327   case TYPE_FLOAT:
2328   case TYPE_FLOATN:
2329      params[0] = ((GLfloat *) p)[0];
2330      break;
2331
2332   case TYPE_DOUBLEN:
2333      params[0] = ((GLdouble *) p)[0];
2334      break;
2335
2336   case TYPE_INT_4:
2337      params[3] = ((GLint *) p)[3];
2338   case TYPE_INT_3:
2339      params[2] = ((GLint *) p)[2];
2340   case TYPE_INT_2:
2341   case TYPE_ENUM_2:
2342      params[1] = ((GLint *) p)[1];
2343   case TYPE_INT:
2344   case TYPE_ENUM:
2345      params[0] = ((GLint *) p)[0];
2346      break;
2347
2348   case TYPE_INT_N:
2349      for (i = 0; i < v.value_int_n.n; i++)
2350	 params[i] = v.value_int_n.ints[i];
2351      break;
2352
2353   case TYPE_INT64:
2354      params[0] = ((GLint64 *) p)[0];
2355      break;
2356
2357   case TYPE_BOOLEAN:
2358      params[0] = *(GLboolean*) p;
2359      break;
2360
2361   case TYPE_MATRIX:
2362      m = *(GLmatrix **) p;
2363      for (i = 0; i < 16; i++)
2364	 params[i] = m->m[i];
2365      break;
2366
2367   case TYPE_MATRIX_T:
2368      m = *(GLmatrix **) p;
2369      for (i = 0; i < 16; i++)
2370	 params[i] = m->m[transpose[i]];
2371      break;
2372
2373   case TYPE_BIT_0:
2374   case TYPE_BIT_1:
2375   case TYPE_BIT_2:
2376   case TYPE_BIT_3:
2377   case TYPE_BIT_4:
2378   case TYPE_BIT_5:
2379   case TYPE_BIT_6:
2380   case TYPE_BIT_7:
2381      shift = d->type - TYPE_BIT_0;
2382      params[0] = (*(GLbitfield *) p >> shift) & 1;
2383      break;
2384   }
2385}
2386
2387static enum value_type
2388find_value_indexed(const char *func, GLenum pname, int index, union value *v)
2389{
2390   GET_CURRENT_CONTEXT(ctx);
2391
2392   switch (pname) {
2393
2394   case GL_BLEND:
2395      if (index >= ctx->Const.MaxDrawBuffers)
2396	 goto invalid_value;
2397      if (!ctx->Extensions.EXT_draw_buffers2)
2398	 goto invalid_enum;
2399      v->value_int = (ctx->Color.BlendEnabled >> index) & 1;
2400      return TYPE_INT;
2401
2402   case GL_BLEND_SRC:
2403      /* fall-through */
2404   case GL_BLEND_SRC_RGB:
2405      if (index >= ctx->Const.MaxDrawBuffers)
2406	 goto invalid_value;
2407      if (!ctx->Extensions.ARB_draw_buffers_blend)
2408	 goto invalid_enum;
2409      v->value_int = ctx->Color.Blend[index].SrcRGB;
2410      return TYPE_INT;
2411   case GL_BLEND_SRC_ALPHA:
2412      if (index >= ctx->Const.MaxDrawBuffers)
2413	 goto invalid_value;
2414      if (!ctx->Extensions.ARB_draw_buffers_blend)
2415	 goto invalid_enum;
2416      v->value_int = ctx->Color.Blend[index].SrcA;
2417      return TYPE_INT;
2418   case GL_BLEND_DST:
2419      /* fall-through */
2420   case GL_BLEND_DST_RGB:
2421      if (index >= ctx->Const.MaxDrawBuffers)
2422	 goto invalid_value;
2423      if (!ctx->Extensions.ARB_draw_buffers_blend)
2424	 goto invalid_enum;
2425      v->value_int = ctx->Color.Blend[index].DstRGB;
2426      return TYPE_INT;
2427   case GL_BLEND_DST_ALPHA:
2428      if (index >= ctx->Const.MaxDrawBuffers)
2429	 goto invalid_value;
2430      if (!ctx->Extensions.ARB_draw_buffers_blend)
2431	 goto invalid_enum;
2432      v->value_int = ctx->Color.Blend[index].DstA;
2433      return TYPE_INT;
2434   case GL_BLEND_EQUATION_RGB:
2435      if (index >= ctx->Const.MaxDrawBuffers)
2436	 goto invalid_value;
2437      if (!ctx->Extensions.ARB_draw_buffers_blend)
2438	 goto invalid_enum;
2439      v->value_int = ctx->Color.Blend[index].EquationRGB;
2440      return TYPE_INT;
2441   case GL_BLEND_EQUATION_ALPHA:
2442      if (index >= ctx->Const.MaxDrawBuffers)
2443	 goto invalid_value;
2444      if (!ctx->Extensions.ARB_draw_buffers_blend)
2445	 goto invalid_enum;
2446      v->value_int = ctx->Color.Blend[index].EquationA;
2447      return TYPE_INT;
2448
2449   case GL_COLOR_WRITEMASK:
2450      if (index >= ctx->Const.MaxDrawBuffers)
2451	 goto invalid_value;
2452      if (!ctx->Extensions.EXT_draw_buffers2)
2453	 goto invalid_enum;
2454      v->value_int_4[0] = ctx->Color.ColorMask[index][RCOMP] ? 1 : 0;
2455      v->value_int_4[1] = ctx->Color.ColorMask[index][GCOMP] ? 1 : 0;
2456      v->value_int_4[2] = ctx->Color.ColorMask[index][BCOMP] ? 1 : 0;
2457      v->value_int_4[3] = ctx->Color.ColorMask[index][ACOMP] ? 1 : 0;
2458      return TYPE_INT_4;
2459
2460   case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2461      if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
2462	 goto invalid_value;
2463      if (!ctx->Extensions.EXT_transform_feedback)
2464	 goto invalid_enum;
2465      v->value_int64 = ctx->TransformFeedback.CurrentObject->Offset[index];
2466      return TYPE_INT64;
2467
2468   case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2469      if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
2470	 goto invalid_value;
2471      if (!ctx->Extensions.EXT_transform_feedback)
2472	 goto invalid_enum;
2473      v->value_int64 = ctx->TransformFeedback.CurrentObject->Size[index];
2474      return TYPE_INT64;
2475
2476   case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2477      if (index >= ctx->Const.MaxTransformFeedbackSeparateAttribs)
2478	 goto invalid_value;
2479      if (!ctx->Extensions.EXT_transform_feedback)
2480	 goto invalid_enum;
2481      v->value_int = ctx->TransformFeedback.CurrentObject->Buffers[index]->Name;
2482      return TYPE_INT;
2483   }
2484
2485 invalid_enum:
2486   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
2487               _mesa_lookup_enum_by_nr(pname));
2488   return TYPE_INVALID;
2489 invalid_value:
2490   _mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=%s)", func,
2491               _mesa_lookup_enum_by_nr(pname));
2492   return TYPE_INVALID;
2493}
2494
2495void GLAPIENTRY
2496_mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )
2497{
2498   union value v;
2499   enum value_type type =
2500      find_value_indexed("glGetBooleanIndexedv", pname, index, &v);
2501
2502   switch (type) {
2503   case TYPE_INT:
2504      params[0] = INT_TO_BOOLEAN(v.value_int);
2505      break;
2506   case TYPE_INT_4:
2507      params[0] = INT_TO_BOOLEAN(v.value_int_4[0]);
2508      params[1] = INT_TO_BOOLEAN(v.value_int_4[1]);
2509      params[2] = INT_TO_BOOLEAN(v.value_int_4[2]);
2510      params[3] = INT_TO_BOOLEAN(v.value_int_4[3]);
2511      break;
2512   case TYPE_INT64:
2513      params[0] = INT64_TO_BOOLEAN(v.value_int);
2514      break;
2515   default:
2516      ; /* nothing - GL error was recorded */
2517   }
2518}
2519
2520void GLAPIENTRY
2521_mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )
2522{
2523   union value v;
2524   enum value_type type =
2525      find_value_indexed("glGetIntegerIndexedv", pname, index, &v);
2526
2527   switch (type) {
2528   case TYPE_INT:
2529      params[0] = v.value_int;
2530      break;
2531   case TYPE_INT_4:
2532      params[0] = v.value_int_4[0];
2533      params[1] = v.value_int_4[1];
2534      params[2] = v.value_int_4[2];
2535      params[3] = v.value_int_4[3];
2536      break;
2537   case TYPE_INT64:
2538      params[0] = INT64_TO_INT(v.value_int);
2539      break;
2540   default:
2541      ; /* nothing - GL error was recorded */
2542   }
2543}
2544
2545#if FEATURE_ARB_sync
2546void GLAPIENTRY
2547_mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )
2548{
2549   union value v;
2550   enum value_type type =
2551      find_value_indexed("glGetIntegerIndexedv", pname, index, &v);
2552
2553   switch (type) {
2554   case TYPE_INT:
2555      params[0] = v.value_int;
2556      break;
2557   case TYPE_INT_4:
2558      params[0] = v.value_int_4[0];
2559      params[1] = v.value_int_4[1];
2560      params[2] = v.value_int_4[2];
2561      params[3] = v.value_int_4[3];
2562      break;
2563   case TYPE_INT64:
2564      params[0] = v.value_int;
2565      break;
2566   default:
2567      ; /* nothing - GL error was recorded */
2568   }
2569}
2570#endif /* FEATURE_ARB_sync */
2571
2572#if FEATURE_ES1
2573void GLAPIENTRY
2574_mesa_GetFixedv(GLenum pname, GLfixed *params)
2575{
2576   const struct value_desc *d;
2577   union value v;
2578   GLmatrix *m;
2579   int shift, i;
2580   void *p;
2581
2582   d = find_value("glGetDoublev", pname, &p, &v);
2583   switch (d->type) {
2584   case TYPE_INVALID:
2585      break;
2586   case TYPE_CONST:
2587      params[0] = INT_TO_FIXED(d->offset);
2588      break;
2589
2590   case TYPE_FLOAT_4:
2591   case TYPE_FLOATN_4:
2592      params[3] = FLOAT_TO_FIXED(((GLfloat *) p)[3]);
2593   case TYPE_FLOAT_3:
2594   case TYPE_FLOATN_3:
2595      params[2] = FLOAT_TO_FIXED(((GLfloat *) p)[2]);
2596   case TYPE_FLOAT_2:
2597   case TYPE_FLOATN_2:
2598      params[1] = FLOAT_TO_FIXED(((GLfloat *) p)[1]);
2599   case TYPE_FLOAT:
2600   case TYPE_FLOATN:
2601      params[0] = FLOAT_TO_FIXED(((GLfloat *) p)[0]);
2602      break;
2603
2604   case TYPE_DOUBLEN:
2605      params[0] = FLOAT_TO_FIXED(((GLdouble *) p)[0]);
2606      break;
2607
2608   case TYPE_INT_4:
2609      params[3] = INT_TO_FIXED(((GLint *) p)[3]);
2610   case TYPE_INT_3:
2611      params[2] = INT_TO_FIXED(((GLint *) p)[2]);
2612   case TYPE_INT_2:
2613   case TYPE_ENUM_2:
2614      params[1] = INT_TO_FIXED(((GLint *) p)[1]);
2615   case TYPE_INT:
2616   case TYPE_ENUM:
2617      params[0] = INT_TO_FIXED(((GLint *) p)[0]);
2618      break;
2619
2620   case TYPE_INT_N:
2621      for (i = 0; i < v.value_int_n.n; i++)
2622	 params[i] = INT_TO_FIXED(v.value_int_n.ints[i]);
2623      break;
2624
2625   case TYPE_INT64:
2626      params[0] = ((GLint64 *) p)[0];
2627      break;
2628
2629   case TYPE_BOOLEAN:
2630      params[0] = BOOLEAN_TO_FIXED(((GLboolean*) p)[0]);
2631      break;
2632
2633   case TYPE_MATRIX:
2634      m = *(GLmatrix **) p;
2635      for (i = 0; i < 16; i++)
2636	 params[i] = FLOAT_TO_FIXED(m->m[i]);
2637      break;
2638
2639   case TYPE_MATRIX_T:
2640      m = *(GLmatrix **) p;
2641      for (i = 0; i < 16; i++)
2642	 params[i] = FLOAT_TO_FIXED(m->m[transpose[i]]);
2643      break;
2644
2645   case TYPE_BIT_0:
2646   case TYPE_BIT_1:
2647   case TYPE_BIT_2:
2648   case TYPE_BIT_3:
2649   case TYPE_BIT_4:
2650   case TYPE_BIT_5:
2651   case TYPE_BIT_6:
2652   case TYPE_BIT_7:
2653      shift = d->type - TYPE_BIT_0;
2654      params[0] = BOOLEAN_TO_FIXED((*(GLbitfield *) p >> shift) & 1);
2655      break;
2656   }
2657}
2658#endif
2659