enable.c revision 192baaac0fc4701e82dcc3e19b3033f81dd82a62
1/**
2 * \file enable.c
3 * Enable/disable/query GL capabilities.
4 */
5
6/*
7 * Mesa 3-D graphics library
8 *
9 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29
30#include "glheader.h"
31#include "clip.h"
32#include "context.h"
33#include "enable.h"
34#include "light.h"
35#include "simple_list.h"
36#include "mfeatures.h"
37#include "mtypes.h"
38#include "enums.h"
39#include "api_arrayelt.h"
40#include "texstate.h"
41
42
43
44#define CHECK_EXTENSION(EXTNAME, CAP)					\
45   if (!ctx->Extensions.EXTNAME) {					\
46      goto invalid_enum_error;						\
47   }
48
49
50/**
51 * Helper to enable/disable client-side state.
52 */
53static void
54client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
55{
56   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
57   GLuint flag;
58   GLboolean *var;
59
60   switch (cap) {
61      case GL_VERTEX_ARRAY:
62         var = &arrayObj->Vertex.Enabled;
63         flag = _NEW_ARRAY_VERTEX;
64         break;
65      case GL_NORMAL_ARRAY:
66         var = &arrayObj->Normal.Enabled;
67         flag = _NEW_ARRAY_NORMAL;
68         break;
69      case GL_COLOR_ARRAY:
70         var = &arrayObj->Color.Enabled;
71         flag = _NEW_ARRAY_COLOR0;
72         break;
73      case GL_INDEX_ARRAY:
74         var = &arrayObj->Index.Enabled;
75         flag = _NEW_ARRAY_INDEX;
76         break;
77      case GL_TEXTURE_COORD_ARRAY:
78         var = &arrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled;
79         flag = _NEW_ARRAY_TEXCOORD(ctx->Array.ActiveTexture);
80         break;
81      case GL_EDGE_FLAG_ARRAY:
82         var = &arrayObj->EdgeFlag.Enabled;
83         flag = _NEW_ARRAY_EDGEFLAG;
84         break;
85      case GL_FOG_COORDINATE_ARRAY_EXT:
86         var = &arrayObj->FogCoord.Enabled;
87         flag = _NEW_ARRAY_FOGCOORD;
88         break;
89      case GL_SECONDARY_COLOR_ARRAY_EXT:
90         var = &arrayObj->SecondaryColor.Enabled;
91         flag = _NEW_ARRAY_COLOR1;
92         break;
93
94#if FEATURE_point_size_array
95      case GL_POINT_SIZE_ARRAY_OES:
96         var = &arrayObj->PointSize.Enabled;
97         flag = _NEW_ARRAY_POINT_SIZE;
98         break;
99#endif
100
101#if FEATURE_NV_vertex_program
102      case GL_VERTEX_ATTRIB_ARRAY0_NV:
103      case GL_VERTEX_ATTRIB_ARRAY1_NV:
104      case GL_VERTEX_ATTRIB_ARRAY2_NV:
105      case GL_VERTEX_ATTRIB_ARRAY3_NV:
106      case GL_VERTEX_ATTRIB_ARRAY4_NV:
107      case GL_VERTEX_ATTRIB_ARRAY5_NV:
108      case GL_VERTEX_ATTRIB_ARRAY6_NV:
109      case GL_VERTEX_ATTRIB_ARRAY7_NV:
110      case GL_VERTEX_ATTRIB_ARRAY8_NV:
111      case GL_VERTEX_ATTRIB_ARRAY9_NV:
112      case GL_VERTEX_ATTRIB_ARRAY10_NV:
113      case GL_VERTEX_ATTRIB_ARRAY11_NV:
114      case GL_VERTEX_ATTRIB_ARRAY12_NV:
115      case GL_VERTEX_ATTRIB_ARRAY13_NV:
116      case GL_VERTEX_ATTRIB_ARRAY14_NV:
117      case GL_VERTEX_ATTRIB_ARRAY15_NV:
118         CHECK_EXTENSION(NV_vertex_program, cap);
119         {
120            GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
121            ASSERT(n < Elements(ctx->Array.ArrayObj->VertexAttrib));
122            var = &arrayObj->VertexAttrib[n].Enabled;
123            flag = _NEW_ARRAY_ATTRIB(n);
124         }
125         break;
126#endif /* FEATURE_NV_vertex_program */
127
128      /* GL_NV_primitive_restart */
129      case GL_PRIMITIVE_RESTART_NV:
130	 if (!ctx->Extensions.NV_primitive_restart) {
131            goto invalid_enum_error;
132         }
133         var = &ctx->Array.PrimitiveRestart;
134         flag = 0;
135         break;
136
137      default:
138         goto invalid_enum_error;
139   }
140
141   if (*var == state)
142      return;
143
144   FLUSH_VERTICES(ctx, _NEW_ARRAY);
145   ctx->Array.NewState |= flag;
146
147   _ae_invalidate_state(ctx, _NEW_ARRAY);
148
149   *var = state;
150
151   if (state)
152      ctx->Array.ArrayObj->_Enabled |= flag;
153   else
154      ctx->Array.ArrayObj->_Enabled &= ~flag;
155
156   if (ctx->Driver.Enable) {
157      ctx->Driver.Enable( ctx, cap, state );
158   }
159
160   return;
161
162invalid_enum_error:
163   _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(0x%x)",
164               state ? "Enable" : "Disable", cap);
165}
166
167
168/**
169 * Enable GL capability.
170 * \param cap  state to enable/disable.
171 *
172 * Get's the current context, assures that we're outside glBegin()/glEnd() and
173 * calls client_state().
174 */
175void GLAPIENTRY
176_mesa_EnableClientState( GLenum cap )
177{
178   GET_CURRENT_CONTEXT(ctx);
179   ASSERT_OUTSIDE_BEGIN_END(ctx);
180   client_state( ctx, cap, GL_TRUE );
181}
182
183
184/**
185 * Disable GL capability.
186 * \param cap  state to enable/disable.
187 *
188 * Get's the current context, assures that we're outside glBegin()/glEnd() and
189 * calls client_state().
190 */
191void GLAPIENTRY
192_mesa_DisableClientState( GLenum cap )
193{
194   GET_CURRENT_CONTEXT(ctx);
195   ASSERT_OUTSIDE_BEGIN_END(ctx);
196   client_state( ctx, cap, GL_FALSE );
197}
198
199
200#undef CHECK_EXTENSION
201#define CHECK_EXTENSION(EXTNAME, CAP)					\
202   if (!ctx->Extensions.EXTNAME) {					\
203      goto invalid_enum_error;						\
204   }
205
206#define CHECK_EXTENSION2(EXT1, EXT2, CAP)				\
207   if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) {		\
208      goto invalid_enum_error;						\
209   }
210
211
212
213/**
214 * Return pointer to current texture unit for setting/getting coordinate
215 * state.
216 * Note that we'll set GL_INVALID_OPERATION and return NULL if the active
217 * texture unit is higher than the number of supported coordinate units.
218 */
219static struct gl_texture_unit *
220get_texcoord_unit(struct gl_context *ctx)
221{
222   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
223      _mesa_error(ctx, GL_INVALID_OPERATION, "glEnable/Disable(texcoord unit)");
224      return NULL;
225   }
226   else {
227      return &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
228   }
229}
230
231
232/**
233 * Helper function to enable or disable a texture target.
234 * \param bit  one of the TEXTURE_x_BIT values
235 * \return GL_TRUE if state is changing or GL_FALSE if no change
236 */
237static GLboolean
238enable_texture(struct gl_context *ctx, GLboolean state, GLbitfield texBit)
239{
240   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
241   const GLbitfield newenabled = state
242      ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
243
244   if (texUnit->Enabled == newenabled)
245       return GL_FALSE;
246
247   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
248   texUnit->Enabled = newenabled;
249   return GL_TRUE;
250}
251
252
253/**
254 * Helper function to enable or disable state.
255 *
256 * \param ctx GL context.
257 * \param cap  the state to enable/disable
258 * \param state whether to enable or disable the specified capability.
259 *
260 * Updates the current context and flushes the vertices as needed. For
261 * capabilities associated with extensions it verifies that those extensions
262 * are effectivly present before updating. Notifies the driver via
263 * dd_function_table::Enable.
264 */
265void
266_mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
267{
268   if (MESA_VERBOSE & VERBOSE_API)
269      _mesa_debug(ctx, "%s %s (newstate is %x)\n",
270                  state ? "glEnable" : "glDisable",
271                  _mesa_lookup_enum_by_nr(cap),
272                  ctx->NewState);
273
274   switch (cap) {
275      case GL_ALPHA_TEST:
276         if (ctx->Color.AlphaEnabled == state)
277            return;
278         FLUSH_VERTICES(ctx, _NEW_COLOR);
279         ctx->Color.AlphaEnabled = state;
280         break;
281      case GL_AUTO_NORMAL:
282         if (ctx->Eval.AutoNormal == state)
283            return;
284         FLUSH_VERTICES(ctx, _NEW_EVAL);
285         ctx->Eval.AutoNormal = state;
286         break;
287      case GL_BLEND:
288         {
289            GLbitfield newEnabled =
290               state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
291            if (newEnabled != ctx->Color.BlendEnabled) {
292               FLUSH_VERTICES(ctx, _NEW_COLOR);
293               ctx->Color.BlendEnabled = newEnabled;
294            }
295         }
296         break;
297#if FEATURE_userclip
298      case GL_CLIP_PLANE0:
299      case GL_CLIP_PLANE1:
300      case GL_CLIP_PLANE2:
301      case GL_CLIP_PLANE3:
302      case GL_CLIP_PLANE4:
303      case GL_CLIP_PLANE5:
304         {
305            const GLuint p = cap - GL_CLIP_PLANE0;
306
307            if ((ctx->Transform.ClipPlanesEnabled & (1 << p))
308                == ((GLuint) state << p))
309               return;
310
311            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
312
313            if (state) {
314               ctx->Transform.ClipPlanesEnabled |= (1 << p);
315               _mesa_update_clip_plane(ctx, p);
316            }
317            else {
318               ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
319            }
320         }
321         break;
322#endif
323      case GL_COLOR_MATERIAL:
324         if (ctx->Light.ColorMaterialEnabled == state)
325            return;
326         FLUSH_VERTICES(ctx, _NEW_LIGHT);
327         FLUSH_CURRENT(ctx, 0);
328         ctx->Light.ColorMaterialEnabled = state;
329         if (state) {
330            _mesa_update_color_material( ctx,
331                                  ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
332         }
333         break;
334      case GL_CULL_FACE:
335         if (ctx->Polygon.CullFlag == state)
336            return;
337         FLUSH_VERTICES(ctx, _NEW_POLYGON);
338         ctx->Polygon.CullFlag = state;
339         break;
340      case GL_DEPTH_TEST:
341         if (ctx->Depth.Test == state)
342            return;
343         FLUSH_VERTICES(ctx, _NEW_DEPTH);
344         ctx->Depth.Test = state;
345         break;
346      case GL_DITHER:
347         if (ctx->Color.DitherFlag == state)
348            return;
349         FLUSH_VERTICES(ctx, _NEW_COLOR);
350         ctx->Color.DitherFlag = state;
351         break;
352      case GL_FOG:
353         if (ctx->Fog.Enabled == state)
354            return;
355         FLUSH_VERTICES(ctx, _NEW_FOG);
356         ctx->Fog.Enabled = state;
357         break;
358      case GL_LIGHT0:
359      case GL_LIGHT1:
360      case GL_LIGHT2:
361      case GL_LIGHT3:
362      case GL_LIGHT4:
363      case GL_LIGHT5:
364      case GL_LIGHT6:
365      case GL_LIGHT7:
366         if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
367            return;
368         FLUSH_VERTICES(ctx, _NEW_LIGHT);
369         ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
370         if (state) {
371            insert_at_tail(&ctx->Light.EnabledList,
372                           &ctx->Light.Light[cap-GL_LIGHT0]);
373         }
374         else {
375            remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
376         }
377         break;
378      case GL_LIGHTING:
379         if (ctx->Light.Enabled == state)
380            return;
381         FLUSH_VERTICES(ctx, _NEW_LIGHT);
382         ctx->Light.Enabled = state;
383         if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
384            ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
385         else
386            ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
387         break;
388      case GL_LINE_SMOOTH:
389         if (ctx->Line.SmoothFlag == state)
390            return;
391         FLUSH_VERTICES(ctx, _NEW_LINE);
392         ctx->Line.SmoothFlag = state;
393         ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
394         break;
395      case GL_LINE_STIPPLE:
396         if (ctx->Line.StippleFlag == state)
397            return;
398         FLUSH_VERTICES(ctx, _NEW_LINE);
399         ctx->Line.StippleFlag = state;
400         ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
401         break;
402      case GL_INDEX_LOGIC_OP:
403         if (ctx->Color.IndexLogicOpEnabled == state)
404            return;
405         FLUSH_VERTICES(ctx, _NEW_COLOR);
406         ctx->Color.IndexLogicOpEnabled = state;
407         break;
408      case GL_COLOR_LOGIC_OP:
409         if (ctx->Color.ColorLogicOpEnabled == state)
410            return;
411         FLUSH_VERTICES(ctx, _NEW_COLOR);
412         ctx->Color.ColorLogicOpEnabled = state;
413         break;
414      case GL_MAP1_COLOR_4:
415         if (ctx->Eval.Map1Color4 == state)
416            return;
417         FLUSH_VERTICES(ctx, _NEW_EVAL);
418         ctx->Eval.Map1Color4 = state;
419         break;
420      case GL_MAP1_INDEX:
421         if (ctx->Eval.Map1Index == state)
422            return;
423         FLUSH_VERTICES(ctx, _NEW_EVAL);
424         ctx->Eval.Map1Index = state;
425         break;
426      case GL_MAP1_NORMAL:
427         if (ctx->Eval.Map1Normal == state)
428            return;
429         FLUSH_VERTICES(ctx, _NEW_EVAL);
430         ctx->Eval.Map1Normal = state;
431         break;
432      case GL_MAP1_TEXTURE_COORD_1:
433         if (ctx->Eval.Map1TextureCoord1 == state)
434            return;
435         FLUSH_VERTICES(ctx, _NEW_EVAL);
436         ctx->Eval.Map1TextureCoord1 = state;
437         break;
438      case GL_MAP1_TEXTURE_COORD_2:
439         if (ctx->Eval.Map1TextureCoord2 == state)
440            return;
441         FLUSH_VERTICES(ctx, _NEW_EVAL);
442         ctx->Eval.Map1TextureCoord2 = state;
443         break;
444      case GL_MAP1_TEXTURE_COORD_3:
445         if (ctx->Eval.Map1TextureCoord3 == state)
446            return;
447         FLUSH_VERTICES(ctx, _NEW_EVAL);
448         ctx->Eval.Map1TextureCoord3 = state;
449         break;
450      case GL_MAP1_TEXTURE_COORD_4:
451         if (ctx->Eval.Map1TextureCoord4 == state)
452            return;
453         FLUSH_VERTICES(ctx, _NEW_EVAL);
454         ctx->Eval.Map1TextureCoord4 = state;
455         break;
456      case GL_MAP1_VERTEX_3:
457         if (ctx->Eval.Map1Vertex3 == state)
458            return;
459         FLUSH_VERTICES(ctx, _NEW_EVAL);
460         ctx->Eval.Map1Vertex3 = state;
461         break;
462      case GL_MAP1_VERTEX_4:
463         if (ctx->Eval.Map1Vertex4 == state)
464            return;
465         FLUSH_VERTICES(ctx, _NEW_EVAL);
466         ctx->Eval.Map1Vertex4 = state;
467         break;
468      case GL_MAP2_COLOR_4:
469         if (ctx->Eval.Map2Color4 == state)
470            return;
471         FLUSH_VERTICES(ctx, _NEW_EVAL);
472         ctx->Eval.Map2Color4 = state;
473         break;
474      case GL_MAP2_INDEX:
475         if (ctx->Eval.Map2Index == state)
476            return;
477         FLUSH_VERTICES(ctx, _NEW_EVAL);
478         ctx->Eval.Map2Index = state;
479         break;
480      case GL_MAP2_NORMAL:
481         if (ctx->Eval.Map2Normal == state)
482            return;
483         FLUSH_VERTICES(ctx, _NEW_EVAL);
484         ctx->Eval.Map2Normal = state;
485         break;
486      case GL_MAP2_TEXTURE_COORD_1:
487         if (ctx->Eval.Map2TextureCoord1 == state)
488            return;
489         FLUSH_VERTICES(ctx, _NEW_EVAL);
490         ctx->Eval.Map2TextureCoord1 = state;
491         break;
492      case GL_MAP2_TEXTURE_COORD_2:
493         if (ctx->Eval.Map2TextureCoord2 == state)
494            return;
495         FLUSH_VERTICES(ctx, _NEW_EVAL);
496         ctx->Eval.Map2TextureCoord2 = state;
497         break;
498      case GL_MAP2_TEXTURE_COORD_3:
499         if (ctx->Eval.Map2TextureCoord3 == state)
500            return;
501         FLUSH_VERTICES(ctx, _NEW_EVAL);
502         ctx->Eval.Map2TextureCoord3 = state;
503         break;
504      case GL_MAP2_TEXTURE_COORD_4:
505         if (ctx->Eval.Map2TextureCoord4 == state)
506            return;
507         FLUSH_VERTICES(ctx, _NEW_EVAL);
508         ctx->Eval.Map2TextureCoord4 = state;
509         break;
510      case GL_MAP2_VERTEX_3:
511         if (ctx->Eval.Map2Vertex3 == state)
512            return;
513         FLUSH_VERTICES(ctx, _NEW_EVAL);
514         ctx->Eval.Map2Vertex3 = state;
515         break;
516      case GL_MAP2_VERTEX_4:
517         if (ctx->Eval.Map2Vertex4 == state)
518            return;
519         FLUSH_VERTICES(ctx, _NEW_EVAL);
520         ctx->Eval.Map2Vertex4 = state;
521         break;
522      case GL_NORMALIZE:
523         if (ctx->Transform.Normalize == state)
524            return;
525         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
526         ctx->Transform.Normalize = state;
527         break;
528      case GL_POINT_SMOOTH:
529         if (ctx->Point.SmoothFlag == state)
530            return;
531         FLUSH_VERTICES(ctx, _NEW_POINT);
532         ctx->Point.SmoothFlag = state;
533         ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
534         break;
535      case GL_POLYGON_SMOOTH:
536         if (ctx->Polygon.SmoothFlag == state)
537            return;
538         FLUSH_VERTICES(ctx, _NEW_POLYGON);
539         ctx->Polygon.SmoothFlag = state;
540         ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
541         break;
542      case GL_POLYGON_STIPPLE:
543         if (ctx->Polygon.StippleFlag == state)
544            return;
545         FLUSH_VERTICES(ctx, _NEW_POLYGON);
546         ctx->Polygon.StippleFlag = state;
547         ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
548         break;
549      case GL_POLYGON_OFFSET_POINT:
550         if (ctx->Polygon.OffsetPoint == state)
551            return;
552         FLUSH_VERTICES(ctx, _NEW_POLYGON);
553         ctx->Polygon.OffsetPoint = state;
554         break;
555      case GL_POLYGON_OFFSET_LINE:
556         if (ctx->Polygon.OffsetLine == state)
557            return;
558         FLUSH_VERTICES(ctx, _NEW_POLYGON);
559         ctx->Polygon.OffsetLine = state;
560         break;
561      case GL_POLYGON_OFFSET_FILL:
562         if (ctx->Polygon.OffsetFill == state)
563            return;
564         FLUSH_VERTICES(ctx, _NEW_POLYGON);
565         ctx->Polygon.OffsetFill = state;
566         break;
567      case GL_RESCALE_NORMAL_EXT:
568         if (ctx->Transform.RescaleNormals == state)
569            return;
570         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
571         ctx->Transform.RescaleNormals = state;
572         break;
573      case GL_SCISSOR_TEST:
574         if (ctx->Scissor.Enabled == state)
575            return;
576         FLUSH_VERTICES(ctx, _NEW_SCISSOR);
577         ctx->Scissor.Enabled = state;
578         break;
579      case GL_SHARED_TEXTURE_PALETTE_EXT:
580         if (ctx->Texture.SharedPalette == state)
581            return;
582         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
583         ctx->Texture.SharedPalette = state;
584         break;
585      case GL_STENCIL_TEST:
586         if (ctx->Stencil.Enabled == state)
587            return;
588         FLUSH_VERTICES(ctx, _NEW_STENCIL);
589         ctx->Stencil.Enabled = state;
590         break;
591      case GL_TEXTURE_1D:
592         if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
593            return;
594         }
595         break;
596      case GL_TEXTURE_2D:
597         if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) {
598            return;
599         }
600         break;
601      case GL_TEXTURE_3D:
602         if (!enable_texture(ctx, state, TEXTURE_3D_BIT)) {
603            return;
604         }
605         break;
606      case GL_TEXTURE_GEN_S:
607      case GL_TEXTURE_GEN_T:
608      case GL_TEXTURE_GEN_R:
609      case GL_TEXTURE_GEN_Q:
610         {
611            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
612            if (texUnit) {
613               GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
614               GLbitfield newenabled = texUnit->TexGenEnabled & ~coordBit;
615               if (state)
616                  newenabled |= coordBit;
617               if (texUnit->TexGenEnabled == newenabled)
618                  return;
619               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
620               texUnit->TexGenEnabled = newenabled;
621            }
622         }
623         break;
624
625#if FEATURE_ES1
626      case GL_TEXTURE_GEN_STR_OES:
627	 /* disable S, T, and R at the same time */
628	 {
629            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
630            if (texUnit) {
631               GLuint newenabled =
632		  texUnit->TexGenEnabled & ~STR_BITS;
633               if (state)
634                  newenabled |= STR_BITS;
635               if (texUnit->TexGenEnabled == newenabled)
636                  return;
637               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
638               texUnit->TexGenEnabled = newenabled;
639            }
640         }
641         break;
642#endif
643
644      /* client-side state */
645      case GL_VERTEX_ARRAY:
646      case GL_NORMAL_ARRAY:
647      case GL_COLOR_ARRAY:
648      case GL_INDEX_ARRAY:
649      case GL_TEXTURE_COORD_ARRAY:
650      case GL_EDGE_FLAG_ARRAY:
651      case GL_FOG_COORDINATE_ARRAY_EXT:
652      case GL_SECONDARY_COLOR_ARRAY_EXT:
653      case GL_POINT_SIZE_ARRAY_OES:
654         client_state( ctx, cap, state );
655         return;
656
657      /* GL_ARB_texture_cube_map */
658      case GL_TEXTURE_CUBE_MAP_ARB:
659         CHECK_EXTENSION(ARB_texture_cube_map, cap);
660         if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) {
661            return;
662         }
663         break;
664
665      /* GL_EXT_secondary_color */
666      case GL_COLOR_SUM_EXT:
667         CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program, cap);
668         if (ctx->Fog.ColorSumEnabled == state)
669            return;
670         FLUSH_VERTICES(ctx, _NEW_FOG);
671         ctx->Fog.ColorSumEnabled = state;
672         break;
673
674      /* GL_ARB_multisample */
675      case GL_MULTISAMPLE_ARB:
676         if (ctx->Multisample.Enabled == state)
677            return;
678         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
679         ctx->Multisample.Enabled = state;
680         break;
681      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
682         if (ctx->Multisample.SampleAlphaToCoverage == state)
683            return;
684         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
685         ctx->Multisample.SampleAlphaToCoverage = state;
686         break;
687      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
688         if (ctx->Multisample.SampleAlphaToOne == state)
689            return;
690         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
691         ctx->Multisample.SampleAlphaToOne = state;
692         break;
693      case GL_SAMPLE_COVERAGE_ARB:
694         if (ctx->Multisample.SampleCoverage == state)
695            return;
696         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
697         ctx->Multisample.SampleCoverage = state;
698         break;
699      case GL_SAMPLE_COVERAGE_INVERT_ARB:
700         if (ctx->Multisample.SampleCoverageInvert == state)
701            return;
702         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
703         ctx->Multisample.SampleCoverageInvert = state;
704         break;
705
706      /* GL_IBM_rasterpos_clip */
707      case GL_RASTER_POSITION_UNCLIPPED_IBM:
708         CHECK_EXTENSION(IBM_rasterpos_clip, cap);
709         if (ctx->Transform.RasterPositionUnclipped == state)
710            return;
711         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
712         ctx->Transform.RasterPositionUnclipped = state;
713         break;
714
715      /* GL_NV_point_sprite */
716      case GL_POINT_SPRITE_NV:
717         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
718         if (ctx->Point.PointSprite == state)
719            return;
720         FLUSH_VERTICES(ctx, _NEW_POINT);
721         ctx->Point.PointSprite = state;
722         break;
723
724#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
725      case GL_VERTEX_PROGRAM_ARB:
726         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
727         if (ctx->VertexProgram.Enabled == state)
728            return;
729         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
730         ctx->VertexProgram.Enabled = state;
731         break;
732      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
733         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
734         if (ctx->VertexProgram.PointSizeEnabled == state)
735            return;
736         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
737         ctx->VertexProgram.PointSizeEnabled = state;
738         break;
739      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
740         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
741         if (ctx->VertexProgram.TwoSideEnabled == state)
742            return;
743         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
744         ctx->VertexProgram.TwoSideEnabled = state;
745         break;
746#endif
747#if FEATURE_NV_vertex_program
748      case GL_MAP1_VERTEX_ATTRIB0_4_NV:
749      case GL_MAP1_VERTEX_ATTRIB1_4_NV:
750      case GL_MAP1_VERTEX_ATTRIB2_4_NV:
751      case GL_MAP1_VERTEX_ATTRIB3_4_NV:
752      case GL_MAP1_VERTEX_ATTRIB4_4_NV:
753      case GL_MAP1_VERTEX_ATTRIB5_4_NV:
754      case GL_MAP1_VERTEX_ATTRIB6_4_NV:
755      case GL_MAP1_VERTEX_ATTRIB7_4_NV:
756      case GL_MAP1_VERTEX_ATTRIB8_4_NV:
757      case GL_MAP1_VERTEX_ATTRIB9_4_NV:
758      case GL_MAP1_VERTEX_ATTRIB10_4_NV:
759      case GL_MAP1_VERTEX_ATTRIB11_4_NV:
760      case GL_MAP1_VERTEX_ATTRIB12_4_NV:
761      case GL_MAP1_VERTEX_ATTRIB13_4_NV:
762      case GL_MAP1_VERTEX_ATTRIB14_4_NV:
763      case GL_MAP1_VERTEX_ATTRIB15_4_NV:
764         CHECK_EXTENSION(NV_vertex_program, cap);
765         {
766            const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
767            FLUSH_VERTICES(ctx, _NEW_EVAL);
768            ctx->Eval.Map1Attrib[map] = state;
769         }
770         break;
771      case GL_MAP2_VERTEX_ATTRIB0_4_NV:
772      case GL_MAP2_VERTEX_ATTRIB1_4_NV:
773      case GL_MAP2_VERTEX_ATTRIB2_4_NV:
774      case GL_MAP2_VERTEX_ATTRIB3_4_NV:
775      case GL_MAP2_VERTEX_ATTRIB4_4_NV:
776      case GL_MAP2_VERTEX_ATTRIB5_4_NV:
777      case GL_MAP2_VERTEX_ATTRIB6_4_NV:
778      case GL_MAP2_VERTEX_ATTRIB7_4_NV:
779      case GL_MAP2_VERTEX_ATTRIB8_4_NV:
780      case GL_MAP2_VERTEX_ATTRIB9_4_NV:
781      case GL_MAP2_VERTEX_ATTRIB10_4_NV:
782      case GL_MAP2_VERTEX_ATTRIB11_4_NV:
783      case GL_MAP2_VERTEX_ATTRIB12_4_NV:
784      case GL_MAP2_VERTEX_ATTRIB13_4_NV:
785      case GL_MAP2_VERTEX_ATTRIB14_4_NV:
786      case GL_MAP2_VERTEX_ATTRIB15_4_NV:
787         CHECK_EXTENSION(NV_vertex_program, cap);
788         {
789            const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
790            FLUSH_VERTICES(ctx, _NEW_EVAL);
791            ctx->Eval.Map2Attrib[map] = state;
792         }
793         break;
794#endif /* FEATURE_NV_vertex_program */
795
796#if FEATURE_NV_fragment_program
797      case GL_FRAGMENT_PROGRAM_NV:
798         CHECK_EXTENSION(NV_fragment_program, cap);
799         if (ctx->FragmentProgram.Enabled == state)
800            return;
801         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
802         ctx->FragmentProgram.Enabled = state;
803         break;
804#endif /* FEATURE_NV_fragment_program */
805
806      /* GL_NV_texture_rectangle */
807      case GL_TEXTURE_RECTANGLE_NV:
808         CHECK_EXTENSION(NV_texture_rectangle, cap);
809         if (!enable_texture(ctx, state, TEXTURE_RECT_BIT)) {
810            return;
811         }
812         break;
813
814      /* GL_EXT_stencil_two_side */
815      case GL_STENCIL_TEST_TWO_SIDE_EXT:
816         CHECK_EXTENSION(EXT_stencil_two_side, cap);
817         if (ctx->Stencil.TestTwoSide == state)
818            return;
819         FLUSH_VERTICES(ctx, _NEW_STENCIL);
820         ctx->Stencil.TestTwoSide = state;
821         if (state) {
822            ctx->Stencil._BackFace = 2;
823            ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
824         } else {
825            ctx->Stencil._BackFace = 1;
826            ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL;
827         }
828         break;
829
830#if FEATURE_ARB_fragment_program
831      case GL_FRAGMENT_PROGRAM_ARB:
832         CHECK_EXTENSION(ARB_fragment_program, cap);
833         if (ctx->FragmentProgram.Enabled == state)
834            return;
835         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
836         ctx->FragmentProgram.Enabled = state;
837         break;
838#endif /* FEATURE_ARB_fragment_program */
839
840      /* GL_EXT_depth_bounds_test */
841      case GL_DEPTH_BOUNDS_TEST_EXT:
842         CHECK_EXTENSION(EXT_depth_bounds_test, cap);
843         if (ctx->Depth.BoundsTest == state)
844            return;
845         FLUSH_VERTICES(ctx, _NEW_DEPTH);
846         ctx->Depth.BoundsTest = state;
847         break;
848
849      case GL_DEPTH_CLAMP:
850         if (ctx->Transform.DepthClamp == state)
851            return;
852	 CHECK_EXTENSION(ARB_depth_clamp, cap);
853         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
854	 ctx->Transform.DepthClamp = state;
855	 break;
856
857#if FEATURE_ATI_fragment_shader
858      case GL_FRAGMENT_SHADER_ATI:
859        CHECK_EXTENSION(ATI_fragment_shader, cap);
860	if (ctx->ATIFragmentShader.Enabled == state)
861	  return;
862	FLUSH_VERTICES(ctx, _NEW_PROGRAM);
863	ctx->ATIFragmentShader.Enabled = state;
864        break;
865#endif
866
867      /* GL_MESA_texture_array */
868      case GL_TEXTURE_1D_ARRAY_EXT:
869         CHECK_EXTENSION(MESA_texture_array, cap);
870         if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) {
871            return;
872         }
873         break;
874
875      case GL_TEXTURE_2D_ARRAY_EXT:
876         CHECK_EXTENSION(MESA_texture_array, cap);
877         if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) {
878            return;
879         }
880         break;
881
882      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
883	 CHECK_EXTENSION(ARB_seamless_cube_map, cap);
884	 if (ctx->Texture.CubeMapSeamless != state) {
885	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
886	    ctx->Texture.CubeMapSeamless = state;
887	 }
888	 break;
889
890#if FEATURE_EXT_transform_feedback
891      case GL_RASTERIZER_DISCARD:
892	 CHECK_EXTENSION(EXT_transform_feedback, cap);
893         if (ctx->TransformFeedback.RasterDiscard != state) {
894            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
895            ctx->TransformFeedback.RasterDiscard = state;
896         }
897         break;
898#endif
899
900      /* GL 3.1 primitive restart.  Note: this enum is different from
901       * GL_PRIMITIVE_RESTART_NV (which is client state).
902       */
903      case GL_PRIMITIVE_RESTART:
904         if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
905            goto invalid_enum_error;
906         }
907         if (ctx->Array.PrimitiveRestart != state) {
908            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
909            ctx->Array.PrimitiveRestart = state;
910         }
911         break;
912
913      /* GL3.0 - GL_framebuffer_sRGB */
914      case GL_FRAMEBUFFER_SRGB_EXT:
915         CHECK_EXTENSION(EXT_framebuffer_sRGB, cap);
916         FLUSH_VERTICES(ctx, _NEW_BUFFERS);
917         ctx->Color.sRGBEnabled = state;
918         break;
919
920      default:
921         goto invalid_enum_error;
922   }
923
924   if (ctx->Driver.Enable) {
925      ctx->Driver.Enable( ctx, cap, state );
926   }
927
928   return;
929
930invalid_enum_error:
931   _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(0x%x)",
932               state ? "Enable" : "Disable", cap);
933}
934
935
936/**
937 * Enable GL capability.  Called by glEnable()
938 * \param cap  state to enable.
939 */
940void GLAPIENTRY
941_mesa_Enable( GLenum cap )
942{
943   GET_CURRENT_CONTEXT(ctx);
944   ASSERT_OUTSIDE_BEGIN_END(ctx);
945
946   _mesa_set_enable( ctx, cap, GL_TRUE );
947}
948
949
950/**
951 * Disable GL capability.  Called by glDisable()
952 * \param cap  state to disable.
953 */
954void GLAPIENTRY
955_mesa_Disable( GLenum cap )
956{
957   GET_CURRENT_CONTEXT(ctx);
958   ASSERT_OUTSIDE_BEGIN_END(ctx);
959
960   _mesa_set_enable( ctx, cap, GL_FALSE );
961}
962
963
964
965/**
966 * Enable/disable an indexed state var.
967 */
968void
969_mesa_set_enablei(struct gl_context *ctx, GLenum cap,
970                  GLuint index, GLboolean state)
971{
972   ASSERT(state == 0 || state == 1);
973   switch (cap) {
974   case GL_BLEND:
975      if (!ctx->Extensions.EXT_draw_buffers2) {
976         goto invalid_enum_error;
977      }
978      if (index >= ctx->Const.MaxDrawBuffers) {
979         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
980                     state ? "glEnableIndexed" : "glDisableIndexed", index);
981         return;
982      }
983      if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
984         FLUSH_VERTICES(ctx, _NEW_COLOR);
985         if (state)
986            ctx->Color.BlendEnabled |= (1 << index);
987         else
988            ctx->Color.BlendEnabled &= ~(1 << index);
989      }
990      break;
991   default:
992      goto invalid_enum_error;
993   }
994   return;
995
996invalid_enum_error:
997    _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
998                state ? "glEnablei" : "glDisablei",
999                _mesa_lookup_enum_by_nr(cap));
1000}
1001
1002
1003void GLAPIENTRY
1004_mesa_DisableIndexed( GLenum cap, GLuint index )
1005{
1006   GET_CURRENT_CONTEXT(ctx);
1007   ASSERT_OUTSIDE_BEGIN_END(ctx);
1008   _mesa_set_enablei(ctx, cap, index, GL_FALSE);
1009}
1010
1011
1012void GLAPIENTRY
1013_mesa_EnableIndexed( GLenum cap, GLuint index )
1014{
1015   GET_CURRENT_CONTEXT(ctx);
1016   ASSERT_OUTSIDE_BEGIN_END(ctx);
1017   _mesa_set_enablei(ctx, cap, index, GL_TRUE);
1018}
1019
1020
1021GLboolean GLAPIENTRY
1022_mesa_IsEnabledIndexed( GLenum cap, GLuint index )
1023{
1024   GET_CURRENT_CONTEXT(ctx);
1025   switch (cap) {
1026   case GL_BLEND:
1027      if (index >= ctx->Const.MaxDrawBuffers) {
1028         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1029                     index);
1030         return GL_FALSE;
1031      }
1032      return (ctx->Color.BlendEnabled >> index) & 1;
1033   default:
1034      _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
1035                  _mesa_lookup_enum_by_nr(cap));
1036      return GL_FALSE;
1037   }
1038}
1039
1040
1041
1042
1043#undef CHECK_EXTENSION
1044#define CHECK_EXTENSION(EXTNAME)			\
1045   if (!ctx->Extensions.EXTNAME) {			\
1046      goto invalid_enum_error;				\
1047   }
1048
1049#undef CHECK_EXTENSION2
1050#define CHECK_EXTENSION2(EXT1, EXT2)				\
1051   if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) {	\
1052      goto invalid_enum_error;					\
1053   }
1054
1055
1056/**
1057 * Helper function to determine whether a texture target is enabled.
1058 */
1059static GLboolean
1060is_texture_enabled(struct gl_context *ctx, GLbitfield bit)
1061{
1062   const struct gl_texture_unit *const texUnit =
1063       &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1064   return (texUnit->Enabled & bit) ? GL_TRUE : GL_FALSE;
1065}
1066
1067
1068/**
1069 * Return simple enable/disable state.
1070 *
1071 * \param cap  state variable to query.
1072 *
1073 * Returns the state of the specified capability from the current GL context.
1074 * For the capabilities associated with extensions verifies that those
1075 * extensions are effectively present before reporting.
1076 */
1077GLboolean GLAPIENTRY
1078_mesa_IsEnabled( GLenum cap )
1079{
1080   GET_CURRENT_CONTEXT(ctx);
1081   switch (cap) {
1082      case GL_ALPHA_TEST:
1083         return ctx->Color.AlphaEnabled;
1084      case GL_AUTO_NORMAL:
1085	 return ctx->Eval.AutoNormal;
1086      case GL_BLEND:
1087         return ctx->Color.BlendEnabled & 1;  /* return state for buffer[0] */
1088      case GL_CLIP_PLANE0:
1089      case GL_CLIP_PLANE1:
1090      case GL_CLIP_PLANE2:
1091      case GL_CLIP_PLANE3:
1092      case GL_CLIP_PLANE4:
1093      case GL_CLIP_PLANE5:
1094	 return (ctx->Transform.ClipPlanesEnabled >> (cap - GL_CLIP_PLANE0)) & 1;
1095      case GL_COLOR_MATERIAL:
1096	 return ctx->Light.ColorMaterialEnabled;
1097      case GL_CULL_FACE:
1098         return ctx->Polygon.CullFlag;
1099      case GL_DEPTH_TEST:
1100         return ctx->Depth.Test;
1101      case GL_DITHER:
1102	 return ctx->Color.DitherFlag;
1103      case GL_FOG:
1104	 return ctx->Fog.Enabled;
1105      case GL_LIGHTING:
1106         return ctx->Light.Enabled;
1107      case GL_LIGHT0:
1108      case GL_LIGHT1:
1109      case GL_LIGHT2:
1110      case GL_LIGHT3:
1111      case GL_LIGHT4:
1112      case GL_LIGHT5:
1113      case GL_LIGHT6:
1114      case GL_LIGHT7:
1115         return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
1116      case GL_LINE_SMOOTH:
1117	 return ctx->Line.SmoothFlag;
1118      case GL_LINE_STIPPLE:
1119	 return ctx->Line.StippleFlag;
1120      case GL_INDEX_LOGIC_OP:
1121	 return ctx->Color.IndexLogicOpEnabled;
1122      case GL_COLOR_LOGIC_OP:
1123	 return ctx->Color.ColorLogicOpEnabled;
1124      case GL_MAP1_COLOR_4:
1125	 return ctx->Eval.Map1Color4;
1126      case GL_MAP1_INDEX:
1127	 return ctx->Eval.Map1Index;
1128      case GL_MAP1_NORMAL:
1129	 return ctx->Eval.Map1Normal;
1130      case GL_MAP1_TEXTURE_COORD_1:
1131	 return ctx->Eval.Map1TextureCoord1;
1132      case GL_MAP1_TEXTURE_COORD_2:
1133	 return ctx->Eval.Map1TextureCoord2;
1134      case GL_MAP1_TEXTURE_COORD_3:
1135	 return ctx->Eval.Map1TextureCoord3;
1136      case GL_MAP1_TEXTURE_COORD_4:
1137	 return ctx->Eval.Map1TextureCoord4;
1138      case GL_MAP1_VERTEX_3:
1139	 return ctx->Eval.Map1Vertex3;
1140      case GL_MAP1_VERTEX_4:
1141	 return ctx->Eval.Map1Vertex4;
1142      case GL_MAP2_COLOR_4:
1143	 return ctx->Eval.Map2Color4;
1144      case GL_MAP2_INDEX:
1145	 return ctx->Eval.Map2Index;
1146      case GL_MAP2_NORMAL:
1147	 return ctx->Eval.Map2Normal;
1148      case GL_MAP2_TEXTURE_COORD_1:
1149	 return ctx->Eval.Map2TextureCoord1;
1150      case GL_MAP2_TEXTURE_COORD_2:
1151	 return ctx->Eval.Map2TextureCoord2;
1152      case GL_MAP2_TEXTURE_COORD_3:
1153	 return ctx->Eval.Map2TextureCoord3;
1154      case GL_MAP2_TEXTURE_COORD_4:
1155	 return ctx->Eval.Map2TextureCoord4;
1156      case GL_MAP2_VERTEX_3:
1157	 return ctx->Eval.Map2Vertex3;
1158      case GL_MAP2_VERTEX_4:
1159	 return ctx->Eval.Map2Vertex4;
1160      case GL_NORMALIZE:
1161	 return ctx->Transform.Normalize;
1162      case GL_POINT_SMOOTH:
1163	 return ctx->Point.SmoothFlag;
1164      case GL_POLYGON_SMOOTH:
1165	 return ctx->Polygon.SmoothFlag;
1166      case GL_POLYGON_STIPPLE:
1167	 return ctx->Polygon.StippleFlag;
1168      case GL_POLYGON_OFFSET_POINT:
1169	 return ctx->Polygon.OffsetPoint;
1170      case GL_POLYGON_OFFSET_LINE:
1171	 return ctx->Polygon.OffsetLine;
1172      case GL_POLYGON_OFFSET_FILL:
1173	 return ctx->Polygon.OffsetFill;
1174      case GL_RESCALE_NORMAL_EXT:
1175         return ctx->Transform.RescaleNormals;
1176      case GL_SCISSOR_TEST:
1177	 return ctx->Scissor.Enabled;
1178      case GL_SHARED_TEXTURE_PALETTE_EXT:
1179         return ctx->Texture.SharedPalette;
1180      case GL_STENCIL_TEST:
1181	 return ctx->Stencil.Enabled;
1182      case GL_TEXTURE_1D:
1183         return is_texture_enabled(ctx, TEXTURE_1D_BIT);
1184      case GL_TEXTURE_2D:
1185         return is_texture_enabled(ctx, TEXTURE_2D_BIT);
1186      case GL_TEXTURE_3D:
1187         return is_texture_enabled(ctx, TEXTURE_3D_BIT);
1188      case GL_TEXTURE_GEN_S:
1189      case GL_TEXTURE_GEN_T:
1190      case GL_TEXTURE_GEN_R:
1191      case GL_TEXTURE_GEN_Q:
1192         {
1193            const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
1194            if (texUnit) {
1195               GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
1196               return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE;
1197            }
1198         }
1199         return GL_FALSE;
1200#if FEATURE_ES1
1201      case GL_TEXTURE_GEN_STR_OES:
1202	 {
1203            const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
1204            if (texUnit) {
1205               return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS
1206                  ? GL_TRUE : GL_FALSE;
1207            }
1208         }
1209#endif
1210
1211      /* client-side state */
1212      case GL_VERTEX_ARRAY:
1213         return (ctx->Array.ArrayObj->Vertex.Enabled != 0);
1214      case GL_NORMAL_ARRAY:
1215         return (ctx->Array.ArrayObj->Normal.Enabled != 0);
1216      case GL_COLOR_ARRAY:
1217         return (ctx->Array.ArrayObj->Color.Enabled != 0);
1218      case GL_INDEX_ARRAY:
1219         return (ctx->Array.ArrayObj->Index.Enabled != 0);
1220      case GL_TEXTURE_COORD_ARRAY:
1221         return (ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture]
1222                 .Enabled != 0);
1223      case GL_EDGE_FLAG_ARRAY:
1224         return (ctx->Array.ArrayObj->EdgeFlag.Enabled != 0);
1225      case GL_FOG_COORDINATE_ARRAY_EXT:
1226         CHECK_EXTENSION(EXT_fog_coord);
1227         return (ctx->Array.ArrayObj->FogCoord.Enabled != 0);
1228      case GL_SECONDARY_COLOR_ARRAY_EXT:
1229         CHECK_EXTENSION(EXT_secondary_color);
1230         return (ctx->Array.ArrayObj->SecondaryColor.Enabled != 0);
1231#if FEATURE_point_size_array
1232      case GL_POINT_SIZE_ARRAY_OES:
1233         return (ctx->Array.ArrayObj->PointSize.Enabled != 0);
1234#endif
1235
1236      /* GL_ARB_texture_cube_map */
1237      case GL_TEXTURE_CUBE_MAP_ARB:
1238         CHECK_EXTENSION(ARB_texture_cube_map);
1239         return is_texture_enabled(ctx, TEXTURE_CUBE_BIT);
1240
1241      /* GL_EXT_secondary_color */
1242      case GL_COLOR_SUM_EXT:
1243         CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program);
1244         return ctx->Fog.ColorSumEnabled;
1245
1246      /* GL_ARB_multisample */
1247      case GL_MULTISAMPLE_ARB:
1248         return ctx->Multisample.Enabled;
1249      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
1250         return ctx->Multisample.SampleAlphaToCoverage;
1251      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
1252         return ctx->Multisample.SampleAlphaToOne;
1253      case GL_SAMPLE_COVERAGE_ARB:
1254         return ctx->Multisample.SampleCoverage;
1255      case GL_SAMPLE_COVERAGE_INVERT_ARB:
1256         return ctx->Multisample.SampleCoverageInvert;
1257
1258      /* GL_IBM_rasterpos_clip */
1259      case GL_RASTER_POSITION_UNCLIPPED_IBM:
1260         CHECK_EXTENSION(IBM_rasterpos_clip);
1261         return ctx->Transform.RasterPositionUnclipped;
1262
1263      /* GL_NV_point_sprite */
1264      case GL_POINT_SPRITE_NV:
1265         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite)
1266         return ctx->Point.PointSprite;
1267
1268#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
1269      case GL_VERTEX_PROGRAM_ARB:
1270         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1271         return ctx->VertexProgram.Enabled;
1272      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1273         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1274         return ctx->VertexProgram.PointSizeEnabled;
1275      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
1276         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1277         return ctx->VertexProgram.TwoSideEnabled;
1278#endif
1279#if FEATURE_NV_vertex_program
1280      case GL_VERTEX_ATTRIB_ARRAY0_NV:
1281      case GL_VERTEX_ATTRIB_ARRAY1_NV:
1282      case GL_VERTEX_ATTRIB_ARRAY2_NV:
1283      case GL_VERTEX_ATTRIB_ARRAY3_NV:
1284      case GL_VERTEX_ATTRIB_ARRAY4_NV:
1285      case GL_VERTEX_ATTRIB_ARRAY5_NV:
1286      case GL_VERTEX_ATTRIB_ARRAY6_NV:
1287      case GL_VERTEX_ATTRIB_ARRAY7_NV:
1288      case GL_VERTEX_ATTRIB_ARRAY8_NV:
1289      case GL_VERTEX_ATTRIB_ARRAY9_NV:
1290      case GL_VERTEX_ATTRIB_ARRAY10_NV:
1291      case GL_VERTEX_ATTRIB_ARRAY11_NV:
1292      case GL_VERTEX_ATTRIB_ARRAY12_NV:
1293      case GL_VERTEX_ATTRIB_ARRAY13_NV:
1294      case GL_VERTEX_ATTRIB_ARRAY14_NV:
1295      case GL_VERTEX_ATTRIB_ARRAY15_NV:
1296         CHECK_EXTENSION(NV_vertex_program);
1297         {
1298            GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
1299            ASSERT(n < Elements(ctx->Array.ArrayObj->VertexAttrib));
1300            return (ctx->Array.ArrayObj->VertexAttrib[n].Enabled != 0);
1301         }
1302      case GL_MAP1_VERTEX_ATTRIB0_4_NV:
1303      case GL_MAP1_VERTEX_ATTRIB1_4_NV:
1304      case GL_MAP1_VERTEX_ATTRIB2_4_NV:
1305      case GL_MAP1_VERTEX_ATTRIB3_4_NV:
1306      case GL_MAP1_VERTEX_ATTRIB4_4_NV:
1307      case GL_MAP1_VERTEX_ATTRIB5_4_NV:
1308      case GL_MAP1_VERTEX_ATTRIB6_4_NV:
1309      case GL_MAP1_VERTEX_ATTRIB7_4_NV:
1310      case GL_MAP1_VERTEX_ATTRIB8_4_NV:
1311      case GL_MAP1_VERTEX_ATTRIB9_4_NV:
1312      case GL_MAP1_VERTEX_ATTRIB10_4_NV:
1313      case GL_MAP1_VERTEX_ATTRIB11_4_NV:
1314      case GL_MAP1_VERTEX_ATTRIB12_4_NV:
1315      case GL_MAP1_VERTEX_ATTRIB13_4_NV:
1316      case GL_MAP1_VERTEX_ATTRIB14_4_NV:
1317      case GL_MAP1_VERTEX_ATTRIB15_4_NV:
1318         CHECK_EXTENSION(NV_vertex_program);
1319         {
1320            const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
1321            return ctx->Eval.Map1Attrib[map];
1322         }
1323      case GL_MAP2_VERTEX_ATTRIB0_4_NV:
1324      case GL_MAP2_VERTEX_ATTRIB1_4_NV:
1325      case GL_MAP2_VERTEX_ATTRIB2_4_NV:
1326      case GL_MAP2_VERTEX_ATTRIB3_4_NV:
1327      case GL_MAP2_VERTEX_ATTRIB4_4_NV:
1328      case GL_MAP2_VERTEX_ATTRIB5_4_NV:
1329      case GL_MAP2_VERTEX_ATTRIB6_4_NV:
1330      case GL_MAP2_VERTEX_ATTRIB7_4_NV:
1331      case GL_MAP2_VERTEX_ATTRIB8_4_NV:
1332      case GL_MAP2_VERTEX_ATTRIB9_4_NV:
1333      case GL_MAP2_VERTEX_ATTRIB10_4_NV:
1334      case GL_MAP2_VERTEX_ATTRIB11_4_NV:
1335      case GL_MAP2_VERTEX_ATTRIB12_4_NV:
1336      case GL_MAP2_VERTEX_ATTRIB13_4_NV:
1337      case GL_MAP2_VERTEX_ATTRIB14_4_NV:
1338      case GL_MAP2_VERTEX_ATTRIB15_4_NV:
1339         CHECK_EXTENSION(NV_vertex_program);
1340         {
1341            const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
1342            return ctx->Eval.Map2Attrib[map];
1343         }
1344#endif /* FEATURE_NV_vertex_program */
1345
1346#if FEATURE_NV_fragment_program
1347      case GL_FRAGMENT_PROGRAM_NV:
1348         CHECK_EXTENSION(NV_fragment_program);
1349         return ctx->FragmentProgram.Enabled;
1350#endif /* FEATURE_NV_fragment_program */
1351
1352      /* GL_NV_texture_rectangle */
1353      case GL_TEXTURE_RECTANGLE_NV:
1354         CHECK_EXTENSION(NV_texture_rectangle);
1355         return is_texture_enabled(ctx, TEXTURE_RECT_BIT);
1356
1357      /* GL_EXT_stencil_two_side */
1358      case GL_STENCIL_TEST_TWO_SIDE_EXT:
1359         CHECK_EXTENSION(EXT_stencil_two_side);
1360         return ctx->Stencil.TestTwoSide;
1361
1362#if FEATURE_ARB_fragment_program
1363      case GL_FRAGMENT_PROGRAM_ARB:
1364         return ctx->FragmentProgram.Enabled;
1365#endif /* FEATURE_ARB_fragment_program */
1366
1367      /* GL_EXT_depth_bounds_test */
1368      case GL_DEPTH_BOUNDS_TEST_EXT:
1369         CHECK_EXTENSION(EXT_depth_bounds_test);
1370         return ctx->Depth.BoundsTest;
1371
1372      /* GL_ARB_depth_clamp */
1373      case GL_DEPTH_CLAMP:
1374         CHECK_EXTENSION(ARB_depth_clamp);
1375         return ctx->Transform.DepthClamp;
1376
1377#if FEATURE_ATI_fragment_shader
1378      case GL_FRAGMENT_SHADER_ATI:
1379	 CHECK_EXTENSION(ATI_fragment_shader);
1380	 return ctx->ATIFragmentShader.Enabled;
1381#endif /* FEATURE_ATI_fragment_shader */
1382
1383      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1384	 CHECK_EXTENSION(ARB_seamless_cube_map);
1385	 return ctx->Texture.CubeMapSeamless;
1386
1387#if FEATURE_EXT_transform_feedback
1388      case GL_RASTERIZER_DISCARD:
1389	 CHECK_EXTENSION(EXT_transform_feedback);
1390         return ctx->TransformFeedback.RasterDiscard;
1391#endif
1392
1393      /* GL_NV_primitive_restart */
1394      case GL_PRIMITIVE_RESTART_NV:
1395	 if (!ctx->Extensions.NV_primitive_restart) {
1396            goto invalid_enum_error;
1397         }
1398         return ctx->Array.PrimitiveRestart;
1399
1400      /* GL 3.1 primitive restart */
1401      case GL_PRIMITIVE_RESTART:
1402         if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
1403            goto invalid_enum_error;
1404         }
1405         return ctx->Array.PrimitiveRestart;
1406
1407      /* GL3.0 - GL_framebuffer_sRGB */
1408      case GL_FRAMEBUFFER_SRGB_EXT:
1409	 CHECK_EXTENSION(EXT_framebuffer_sRGB);
1410	 return ctx->Color.sRGBEnabled;
1411
1412      default:
1413         goto invalid_enum_error;
1414   }
1415
1416   return GL_FALSE;
1417
1418invalid_enum_error:
1419   _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap);
1420   return GL_FALSE;
1421}
1422