enable.c revision 08be1d288f216232d3974f5997b266a8dd720928
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   GLbitfield64 flag;
58   GLboolean *var;
59
60   switch (cap) {
61      case GL_VERTEX_ARRAY:
62         var = &arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled;
63         flag = VERT_BIT_POS;
64         break;
65      case GL_NORMAL_ARRAY:
66         var = &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled;
67         flag = VERT_BIT_NORMAL;
68         break;
69      case GL_COLOR_ARRAY:
70         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled;
71         flag = VERT_BIT_COLOR0;
72         break;
73      case GL_INDEX_ARRAY:
74         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled;
75         flag = VERT_BIT_COLOR_INDEX;
76         break;
77      case GL_TEXTURE_COORD_ARRAY:
78         var = &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Enabled;
79         flag = VERT_BIT_TEX(ctx->Array.ActiveTexture);
80         break;
81      case GL_EDGE_FLAG_ARRAY:
82         var = &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled;
83         flag = VERT_BIT_EDGEFLAG;
84         break;
85      case GL_FOG_COORDINATE_ARRAY_EXT:
86         var = &arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled;
87         flag = VERT_BIT_FOG;
88         break;
89      case GL_SECONDARY_COLOR_ARRAY_EXT:
90         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled;
91         flag = VERT_BIT_COLOR1;
92         break;
93
94#if FEATURE_point_size_array
95      case GL_POINT_SIZE_ARRAY_OES:
96         var = &arrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Enabled;
97         flag = VERT_BIT_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(VERT_ATTRIB_GENERIC(n) < Elements(arrayObj->VertexAttrib));
122            var = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(n)].Enabled;
123            flag = VERT_BIT_GENERIC(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
146   _ae_invalidate_state(ctx, _NEW_ARRAY);
147
148   *var = state;
149
150   if (state)
151      arrayObj->_Enabled |= flag;
152   else
153      arrayObj->_Enabled &= ~flag;
154
155   arrayObj->NewArrays |= flag;
156
157   if (ctx->Driver.Enable) {
158      ctx->Driver.Enable( ctx, cap, state );
159   }
160
161   return;
162
163invalid_enum_error:
164   _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(%s)",
165               state ? "Enable" : "Disable", _mesa_lookup_enum_by_nr(cap));
166}
167
168
169/**
170 * Enable GL capability.
171 * \param cap  state to enable/disable.
172 *
173 * Get's the current context, assures that we're outside glBegin()/glEnd() and
174 * calls client_state().
175 */
176void GLAPIENTRY
177_mesa_EnableClientState( GLenum cap )
178{
179   GET_CURRENT_CONTEXT(ctx);
180   ASSERT_OUTSIDE_BEGIN_END(ctx);
181   client_state( ctx, cap, GL_TRUE );
182}
183
184
185/**
186 * Disable GL capability.
187 * \param cap  state to enable/disable.
188 *
189 * Get's the current context, assures that we're outside glBegin()/glEnd() and
190 * calls client_state().
191 */
192void GLAPIENTRY
193_mesa_DisableClientState( GLenum cap )
194{
195   GET_CURRENT_CONTEXT(ctx);
196   ASSERT_OUTSIDE_BEGIN_END(ctx);
197   client_state( ctx, cap, GL_FALSE );
198}
199
200
201#undef CHECK_EXTENSION
202#define CHECK_EXTENSION(EXTNAME, CAP)					\
203   if (!ctx->Extensions.EXTNAME) {					\
204      goto invalid_enum_error;						\
205   }
206
207#define CHECK_EXTENSION2(EXT1, EXT2, CAP)				\
208   if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) {		\
209      goto invalid_enum_error;						\
210   }
211
212/**
213 * Return pointer to current texture unit for setting/getting coordinate
214 * state.
215 * Note that we'll set GL_INVALID_OPERATION and return NULL if the active
216 * texture unit is higher than the number of supported coordinate units.
217 */
218static struct gl_texture_unit *
219get_texcoord_unit(struct gl_context *ctx)
220{
221   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
222      _mesa_error(ctx, GL_INVALID_OPERATION, "glEnable/Disable(texcoord unit)");
223      return NULL;
224   }
225   else {
226      return &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
227   }
228}
229
230
231/**
232 * Helper function to enable or disable a texture target.
233 * \param bit  one of the TEXTURE_x_BIT values
234 * \return GL_TRUE if state is changing or GL_FALSE if no change
235 */
236static GLboolean
237enable_texture(struct gl_context *ctx, GLboolean state, GLbitfield texBit)
238{
239   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
240   const GLbitfield newenabled = state
241      ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
242
243   if (texUnit->Enabled == newenabled)
244       return GL_FALSE;
245
246   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
247   texUnit->Enabled = newenabled;
248   return GL_TRUE;
249}
250
251
252/**
253 * Helper function to enable or disable state.
254 *
255 * \param ctx GL context.
256 * \param cap  the state to enable/disable
257 * \param state whether to enable or disable the specified capability.
258 *
259 * Updates the current context and flushes the vertices as needed. For
260 * capabilities associated with extensions it verifies that those extensions
261 * are effectivly present before updating. Notifies the driver via
262 * dd_function_table::Enable.
263 */
264void
265_mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
266{
267   if (MESA_VERBOSE & VERBOSE_API)
268      _mesa_debug(ctx, "%s %s (newstate is %x)\n",
269                  state ? "glEnable" : "glDisable",
270                  _mesa_lookup_enum_by_nr(cap),
271                  ctx->NewState);
272
273   switch (cap) {
274      case GL_ALPHA_TEST:
275         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
276            goto invalid_enum_error;
277         if (ctx->Color.AlphaEnabled == state)
278            return;
279         FLUSH_VERTICES(ctx, _NEW_COLOR);
280         ctx->Color.AlphaEnabled = state;
281         break;
282      case GL_AUTO_NORMAL:
283         if (ctx->API != API_OPENGL)
284            goto invalid_enum_error;
285         if (ctx->Eval.AutoNormal == state)
286            return;
287         FLUSH_VERTICES(ctx, _NEW_EVAL);
288         ctx->Eval.AutoNormal = state;
289         break;
290      case GL_BLEND:
291         {
292            GLbitfield newEnabled =
293               state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
294            if (newEnabled != ctx->Color.BlendEnabled) {
295               FLUSH_VERTICES(ctx, _NEW_COLOR);
296               ctx->Color.BlendEnabled = newEnabled;
297            }
298         }
299         break;
300#if FEATURE_userclip
301      case GL_CLIP_DISTANCE0:
302      case GL_CLIP_DISTANCE1:
303      case GL_CLIP_DISTANCE2:
304      case GL_CLIP_DISTANCE3:
305      case GL_CLIP_DISTANCE4:
306      case GL_CLIP_DISTANCE5:
307      case GL_CLIP_DISTANCE6:
308      case GL_CLIP_DISTANCE7:
309         {
310            const GLuint p = cap - GL_CLIP_DISTANCE0;
311
312            if (p >= ctx->Const.MaxClipPlanes)
313               goto invalid_enum_error;
314
315            if ((ctx->Transform.ClipPlanesEnabled & (1 << p))
316                == ((GLuint) state << p))
317               return;
318
319            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
320
321            if (state) {
322               ctx->Transform.ClipPlanesEnabled |= (1 << p);
323               _mesa_update_clip_plane(ctx, p);
324            }
325            else {
326               ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
327            }
328         }
329         break;
330#endif
331      case GL_COLOR_MATERIAL:
332         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
333            goto invalid_enum_error;
334         if (ctx->Light.ColorMaterialEnabled == state)
335            return;
336         FLUSH_VERTICES(ctx, _NEW_LIGHT);
337         FLUSH_CURRENT(ctx, 0);
338         ctx->Light.ColorMaterialEnabled = state;
339         if (state) {
340            _mesa_update_color_material( ctx,
341                                  ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
342         }
343         break;
344      case GL_CULL_FACE:
345         if (ctx->Polygon.CullFlag == state)
346            return;
347         FLUSH_VERTICES(ctx, _NEW_POLYGON);
348         ctx->Polygon.CullFlag = state;
349         break;
350      case GL_DEPTH_TEST:
351         if (ctx->Depth.Test == state)
352            return;
353         FLUSH_VERTICES(ctx, _NEW_DEPTH);
354         ctx->Depth.Test = state;
355         break;
356      case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
357         if (!_mesa_is_desktop_gl(ctx))
358            goto invalid_enum_error;
359         ctx->Debug.SyncOutput = state;
360         break;
361      case GL_DITHER:
362         if (ctx->Color.DitherFlag == state)
363            return;
364         FLUSH_VERTICES(ctx, _NEW_COLOR);
365         ctx->Color.DitherFlag = state;
366         break;
367      case GL_FOG:
368         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
369            goto invalid_enum_error;
370         if (ctx->Fog.Enabled == state)
371            return;
372         FLUSH_VERTICES(ctx, _NEW_FOG);
373         ctx->Fog.Enabled = state;
374         break;
375      case GL_LIGHT0:
376      case GL_LIGHT1:
377      case GL_LIGHT2:
378      case GL_LIGHT3:
379      case GL_LIGHT4:
380      case GL_LIGHT5:
381      case GL_LIGHT6:
382      case GL_LIGHT7:
383         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
384            goto invalid_enum_error;
385         if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
386            return;
387         FLUSH_VERTICES(ctx, _NEW_LIGHT);
388         ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
389         if (state) {
390            insert_at_tail(&ctx->Light.EnabledList,
391                           &ctx->Light.Light[cap-GL_LIGHT0]);
392         }
393         else {
394            remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
395         }
396         break;
397      case GL_LIGHTING:
398         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
399            goto invalid_enum_error;
400         if (ctx->Light.Enabled == state)
401            return;
402         FLUSH_VERTICES(ctx, _NEW_LIGHT);
403         ctx->Light.Enabled = state;
404         if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
405            ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
406         else
407            ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
408         break;
409      case GL_LINE_SMOOTH:
410         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
411            goto invalid_enum_error;
412         if (ctx->Line.SmoothFlag == state)
413            return;
414         FLUSH_VERTICES(ctx, _NEW_LINE);
415         ctx->Line.SmoothFlag = state;
416         ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
417         break;
418      case GL_LINE_STIPPLE:
419         if (ctx->API != API_OPENGL)
420            goto invalid_enum_error;
421         if (ctx->Line.StippleFlag == state)
422            return;
423         FLUSH_VERTICES(ctx, _NEW_LINE);
424         ctx->Line.StippleFlag = state;
425         ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
426         break;
427      case GL_INDEX_LOGIC_OP:
428         if (ctx->API != API_OPENGL)
429            goto invalid_enum_error;
430         if (ctx->Color.IndexLogicOpEnabled == state)
431            return;
432         FLUSH_VERTICES(ctx, _NEW_COLOR);
433         ctx->Color.IndexLogicOpEnabled = state;
434         break;
435      case GL_COLOR_LOGIC_OP:
436         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
437            goto invalid_enum_error;
438         if (ctx->Color.ColorLogicOpEnabled == state)
439            return;
440         FLUSH_VERTICES(ctx, _NEW_COLOR);
441         ctx->Color.ColorLogicOpEnabled = state;
442         break;
443      case GL_MAP1_COLOR_4:
444         if (ctx->API != API_OPENGL)
445            goto invalid_enum_error;
446         if (ctx->Eval.Map1Color4 == state)
447            return;
448         FLUSH_VERTICES(ctx, _NEW_EVAL);
449         ctx->Eval.Map1Color4 = state;
450         break;
451      case GL_MAP1_INDEX:
452         if (ctx->API != API_OPENGL)
453            goto invalid_enum_error;
454         if (ctx->Eval.Map1Index == state)
455            return;
456         FLUSH_VERTICES(ctx, _NEW_EVAL);
457         ctx->Eval.Map1Index = state;
458         break;
459      case GL_MAP1_NORMAL:
460         if (ctx->API != API_OPENGL)
461            goto invalid_enum_error;
462         if (ctx->Eval.Map1Normal == state)
463            return;
464         FLUSH_VERTICES(ctx, _NEW_EVAL);
465         ctx->Eval.Map1Normal = state;
466         break;
467      case GL_MAP1_TEXTURE_COORD_1:
468         if (ctx->API != API_OPENGL)
469            goto invalid_enum_error;
470         if (ctx->Eval.Map1TextureCoord1 == state)
471            return;
472         FLUSH_VERTICES(ctx, _NEW_EVAL);
473         ctx->Eval.Map1TextureCoord1 = state;
474         break;
475      case GL_MAP1_TEXTURE_COORD_2:
476         if (ctx->API != API_OPENGL)
477            goto invalid_enum_error;
478         if (ctx->Eval.Map1TextureCoord2 == state)
479            return;
480         FLUSH_VERTICES(ctx, _NEW_EVAL);
481         ctx->Eval.Map1TextureCoord2 = state;
482         break;
483      case GL_MAP1_TEXTURE_COORD_3:
484         if (ctx->API != API_OPENGL)
485            goto invalid_enum_error;
486         if (ctx->Eval.Map1TextureCoord3 == state)
487            return;
488         FLUSH_VERTICES(ctx, _NEW_EVAL);
489         ctx->Eval.Map1TextureCoord3 = state;
490         break;
491      case GL_MAP1_TEXTURE_COORD_4:
492         if (ctx->API != API_OPENGL)
493            goto invalid_enum_error;
494         if (ctx->Eval.Map1TextureCoord4 == state)
495            return;
496         FLUSH_VERTICES(ctx, _NEW_EVAL);
497         ctx->Eval.Map1TextureCoord4 = state;
498         break;
499      case GL_MAP1_VERTEX_3:
500         if (ctx->API != API_OPENGL)
501            goto invalid_enum_error;
502         if (ctx->Eval.Map1Vertex3 == state)
503            return;
504         FLUSH_VERTICES(ctx, _NEW_EVAL);
505         ctx->Eval.Map1Vertex3 = state;
506         break;
507      case GL_MAP1_VERTEX_4:
508         if (ctx->API != API_OPENGL)
509            goto invalid_enum_error;
510         if (ctx->Eval.Map1Vertex4 == state)
511            return;
512         FLUSH_VERTICES(ctx, _NEW_EVAL);
513         ctx->Eval.Map1Vertex4 = state;
514         break;
515      case GL_MAP2_COLOR_4:
516         if (ctx->API != API_OPENGL)
517            goto invalid_enum_error;
518         if (ctx->Eval.Map2Color4 == state)
519            return;
520         FLUSH_VERTICES(ctx, _NEW_EVAL);
521         ctx->Eval.Map2Color4 = state;
522         break;
523      case GL_MAP2_INDEX:
524         if (ctx->API != API_OPENGL)
525            goto invalid_enum_error;
526         if (ctx->Eval.Map2Index == state)
527            return;
528         FLUSH_VERTICES(ctx, _NEW_EVAL);
529         ctx->Eval.Map2Index = state;
530         break;
531      case GL_MAP2_NORMAL:
532         if (ctx->API != API_OPENGL)
533            goto invalid_enum_error;
534         if (ctx->Eval.Map2Normal == state)
535            return;
536         FLUSH_VERTICES(ctx, _NEW_EVAL);
537         ctx->Eval.Map2Normal = state;
538         break;
539      case GL_MAP2_TEXTURE_COORD_1:
540         if (ctx->API != API_OPENGL)
541            goto invalid_enum_error;
542         if (ctx->Eval.Map2TextureCoord1 == state)
543            return;
544         FLUSH_VERTICES(ctx, _NEW_EVAL);
545         ctx->Eval.Map2TextureCoord1 = state;
546         break;
547      case GL_MAP2_TEXTURE_COORD_2:
548         if (ctx->API != API_OPENGL)
549            goto invalid_enum_error;
550         if (ctx->Eval.Map2TextureCoord2 == state)
551            return;
552         FLUSH_VERTICES(ctx, _NEW_EVAL);
553         ctx->Eval.Map2TextureCoord2 = state;
554         break;
555      case GL_MAP2_TEXTURE_COORD_3:
556         if (ctx->API != API_OPENGL)
557            goto invalid_enum_error;
558         if (ctx->Eval.Map2TextureCoord3 == state)
559            return;
560         FLUSH_VERTICES(ctx, _NEW_EVAL);
561         ctx->Eval.Map2TextureCoord3 = state;
562         break;
563      case GL_MAP2_TEXTURE_COORD_4:
564         if (ctx->API != API_OPENGL)
565            goto invalid_enum_error;
566         if (ctx->Eval.Map2TextureCoord4 == state)
567            return;
568         FLUSH_VERTICES(ctx, _NEW_EVAL);
569         ctx->Eval.Map2TextureCoord4 = state;
570         break;
571      case GL_MAP2_VERTEX_3:
572         if (ctx->API != API_OPENGL)
573            goto invalid_enum_error;
574         if (ctx->Eval.Map2Vertex3 == state)
575            return;
576         FLUSH_VERTICES(ctx, _NEW_EVAL);
577         ctx->Eval.Map2Vertex3 = state;
578         break;
579      case GL_MAP2_VERTEX_4:
580         if (ctx->API != API_OPENGL)
581            goto invalid_enum_error;
582         if (ctx->Eval.Map2Vertex4 == state)
583            return;
584         FLUSH_VERTICES(ctx, _NEW_EVAL);
585         ctx->Eval.Map2Vertex4 = state;
586         break;
587      case GL_NORMALIZE:
588         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
589            goto invalid_enum_error;
590         if (ctx->Transform.Normalize == state)
591            return;
592         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
593         ctx->Transform.Normalize = state;
594         break;
595      case GL_POINT_SMOOTH:
596         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
597            goto invalid_enum_error;
598         if (ctx->Point.SmoothFlag == state)
599            return;
600         FLUSH_VERTICES(ctx, _NEW_POINT);
601         ctx->Point.SmoothFlag = state;
602         ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
603         break;
604      case GL_POLYGON_SMOOTH:
605         if (!_mesa_is_desktop_gl(ctx))
606            goto invalid_enum_error;
607         if (ctx->Polygon.SmoothFlag == state)
608            return;
609         FLUSH_VERTICES(ctx, _NEW_POLYGON);
610         ctx->Polygon.SmoothFlag = state;
611         ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
612         break;
613      case GL_POLYGON_STIPPLE:
614         if (ctx->API != API_OPENGL)
615            goto invalid_enum_error;
616         if (ctx->Polygon.StippleFlag == state)
617            return;
618         FLUSH_VERTICES(ctx, _NEW_POLYGON);
619         ctx->Polygon.StippleFlag = state;
620         ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
621         break;
622      case GL_POLYGON_OFFSET_POINT:
623         if (!_mesa_is_desktop_gl(ctx))
624            goto invalid_enum_error;
625         if (ctx->Polygon.OffsetPoint == state)
626            return;
627         FLUSH_VERTICES(ctx, _NEW_POLYGON);
628         ctx->Polygon.OffsetPoint = state;
629         break;
630      case GL_POLYGON_OFFSET_LINE:
631         if (!_mesa_is_desktop_gl(ctx))
632            goto invalid_enum_error;
633         if (ctx->Polygon.OffsetLine == state)
634            return;
635         FLUSH_VERTICES(ctx, _NEW_POLYGON);
636         ctx->Polygon.OffsetLine = state;
637         break;
638      case GL_POLYGON_OFFSET_FILL:
639         if (ctx->Polygon.OffsetFill == state)
640            return;
641         FLUSH_VERTICES(ctx, _NEW_POLYGON);
642         ctx->Polygon.OffsetFill = state;
643         break;
644      case GL_RESCALE_NORMAL_EXT:
645         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
646            goto invalid_enum_error;
647         if (ctx->Transform.RescaleNormals == state)
648            return;
649         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
650         ctx->Transform.RescaleNormals = state;
651         break;
652      case GL_SCISSOR_TEST:
653         if (ctx->Scissor.Enabled == state)
654            return;
655         FLUSH_VERTICES(ctx, _NEW_SCISSOR);
656         ctx->Scissor.Enabled = state;
657         break;
658      case GL_STENCIL_TEST:
659         if (ctx->Stencil.Enabled == state)
660            return;
661         FLUSH_VERTICES(ctx, _NEW_STENCIL);
662         ctx->Stencil.Enabled = state;
663         break;
664      case GL_TEXTURE_1D:
665         if (ctx->API != API_OPENGL)
666            goto invalid_enum_error;
667         if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
668            return;
669         }
670         break;
671      case GL_TEXTURE_2D:
672         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
673            goto invalid_enum_error;
674         if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) {
675            return;
676         }
677         break;
678      case GL_TEXTURE_3D:
679         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
680            goto invalid_enum_error;
681         if (!enable_texture(ctx, state, TEXTURE_3D_BIT)) {
682            return;
683         }
684         break;
685      case GL_TEXTURE_GEN_S:
686      case GL_TEXTURE_GEN_T:
687      case GL_TEXTURE_GEN_R:
688      case GL_TEXTURE_GEN_Q:
689         {
690            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
691
692            if (ctx->API != API_OPENGL)
693               goto invalid_enum_error;
694
695            if (texUnit) {
696               GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
697               GLbitfield newenabled = texUnit->TexGenEnabled & ~coordBit;
698               if (state)
699                  newenabled |= coordBit;
700               if (texUnit->TexGenEnabled == newenabled)
701                  return;
702               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
703               texUnit->TexGenEnabled = newenabled;
704            }
705         }
706         break;
707
708#if FEATURE_ES1
709      case GL_TEXTURE_GEN_STR_OES:
710	 /* disable S, T, and R at the same time */
711	 {
712            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
713
714            if (ctx->API != API_OPENGLES)
715               goto invalid_enum_error;
716
717            if (texUnit) {
718               GLuint newenabled =
719		  texUnit->TexGenEnabled & ~STR_BITS;
720               if (state)
721                  newenabled |= STR_BITS;
722               if (texUnit->TexGenEnabled == newenabled)
723                  return;
724               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
725               texUnit->TexGenEnabled = newenabled;
726            }
727         }
728         break;
729#endif
730
731      /* client-side state */
732      case GL_VERTEX_ARRAY:
733      case GL_NORMAL_ARRAY:
734      case GL_COLOR_ARRAY:
735      case GL_INDEX_ARRAY:
736      case GL_TEXTURE_COORD_ARRAY:
737      case GL_EDGE_FLAG_ARRAY:
738      case GL_FOG_COORDINATE_ARRAY_EXT:
739      case GL_SECONDARY_COLOR_ARRAY_EXT:
740      case GL_POINT_SIZE_ARRAY_OES:
741         client_state( ctx, cap, state );
742         return;
743
744      /* GL_ARB_texture_cube_map */
745      case GL_TEXTURE_CUBE_MAP_ARB:
746         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
747            goto invalid_enum_error;
748         CHECK_EXTENSION(ARB_texture_cube_map, cap);
749         if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) {
750            return;
751         }
752         break;
753
754      /* GL_EXT_secondary_color */
755      case GL_COLOR_SUM_EXT:
756         if (ctx->API != API_OPENGL)
757            goto invalid_enum_error;
758         CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program, cap);
759         if (ctx->Fog.ColorSumEnabled == state)
760            return;
761         FLUSH_VERTICES(ctx, _NEW_FOG);
762         ctx->Fog.ColorSumEnabled = state;
763         break;
764
765      /* GL_ARB_multisample */
766      case GL_MULTISAMPLE_ARB:
767         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
768            goto invalid_enum_error;
769         if (ctx->Multisample.Enabled == state)
770            return;
771         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
772         ctx->Multisample.Enabled = state;
773         break;
774      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
775         if (ctx->Multisample.SampleAlphaToCoverage == state)
776            return;
777         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
778         ctx->Multisample.SampleAlphaToCoverage = state;
779         break;
780      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
781         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
782            goto invalid_enum_error;
783         if (ctx->Multisample.SampleAlphaToOne == state)
784            return;
785         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
786         ctx->Multisample.SampleAlphaToOne = state;
787         break;
788      case GL_SAMPLE_COVERAGE_ARB:
789         if (ctx->Multisample.SampleCoverage == state)
790            return;
791         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
792         ctx->Multisample.SampleCoverage = state;
793         break;
794      case GL_SAMPLE_COVERAGE_INVERT_ARB:
795         if (!_mesa_is_desktop_gl(ctx))
796            goto invalid_enum_error;
797         if (ctx->Multisample.SampleCoverageInvert == state)
798            return;
799         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
800         ctx->Multisample.SampleCoverageInvert = state;
801         break;
802
803      /* GL_IBM_rasterpos_clip */
804      case GL_RASTER_POSITION_UNCLIPPED_IBM:
805         if (ctx->API != API_OPENGL)
806            goto invalid_enum_error;
807         CHECK_EXTENSION(IBM_rasterpos_clip, cap);
808         if (ctx->Transform.RasterPositionUnclipped == state)
809            return;
810         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
811         ctx->Transform.RasterPositionUnclipped = state;
812         break;
813
814      /* GL_NV_point_sprite */
815      case GL_POINT_SPRITE_NV:
816         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
817            goto invalid_enum_error;
818         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
819         if (ctx->Point.PointSprite == state)
820            return;
821         FLUSH_VERTICES(ctx, _NEW_POINT);
822         ctx->Point.PointSprite = state;
823         break;
824
825#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
826      case GL_VERTEX_PROGRAM_ARB:
827         if (ctx->API != API_OPENGL)
828            goto invalid_enum_error;
829         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
830         if (ctx->VertexProgram.Enabled == state)
831            return;
832         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
833         ctx->VertexProgram.Enabled = state;
834         break;
835      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
836         /* This was added with ARB_vertex_program, but it is also used with
837          * GLSL vertex shaders on desktop.
838          */
839         if (!_mesa_is_desktop_gl(ctx))
840            goto invalid_enum_error;
841         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
842         if (ctx->VertexProgram.PointSizeEnabled == state)
843            return;
844         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
845         ctx->VertexProgram.PointSizeEnabled = state;
846         break;
847      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
848         if (ctx->API != API_OPENGL)
849            goto invalid_enum_error;
850         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
851         if (ctx->VertexProgram.TwoSideEnabled == state)
852            return;
853         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
854         ctx->VertexProgram.TwoSideEnabled = state;
855         break;
856#endif
857#if FEATURE_NV_vertex_program
858      case GL_MAP1_VERTEX_ATTRIB0_4_NV:
859      case GL_MAP1_VERTEX_ATTRIB1_4_NV:
860      case GL_MAP1_VERTEX_ATTRIB2_4_NV:
861      case GL_MAP1_VERTEX_ATTRIB3_4_NV:
862      case GL_MAP1_VERTEX_ATTRIB4_4_NV:
863      case GL_MAP1_VERTEX_ATTRIB5_4_NV:
864      case GL_MAP1_VERTEX_ATTRIB6_4_NV:
865      case GL_MAP1_VERTEX_ATTRIB7_4_NV:
866      case GL_MAP1_VERTEX_ATTRIB8_4_NV:
867      case GL_MAP1_VERTEX_ATTRIB9_4_NV:
868      case GL_MAP1_VERTEX_ATTRIB10_4_NV:
869      case GL_MAP1_VERTEX_ATTRIB11_4_NV:
870      case GL_MAP1_VERTEX_ATTRIB12_4_NV:
871      case GL_MAP1_VERTEX_ATTRIB13_4_NV:
872      case GL_MAP1_VERTEX_ATTRIB14_4_NV:
873      case GL_MAP1_VERTEX_ATTRIB15_4_NV:
874         if (ctx->API != API_OPENGL)
875            goto invalid_enum_error;
876         CHECK_EXTENSION(NV_vertex_program, cap);
877         {
878            const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
879            FLUSH_VERTICES(ctx, _NEW_EVAL);
880            ctx->Eval.Map1Attrib[map] = state;
881         }
882         break;
883      case GL_MAP2_VERTEX_ATTRIB0_4_NV:
884      case GL_MAP2_VERTEX_ATTRIB1_4_NV:
885      case GL_MAP2_VERTEX_ATTRIB2_4_NV:
886      case GL_MAP2_VERTEX_ATTRIB3_4_NV:
887      case GL_MAP2_VERTEX_ATTRIB4_4_NV:
888      case GL_MAP2_VERTEX_ATTRIB5_4_NV:
889      case GL_MAP2_VERTEX_ATTRIB6_4_NV:
890      case GL_MAP2_VERTEX_ATTRIB7_4_NV:
891      case GL_MAP2_VERTEX_ATTRIB8_4_NV:
892      case GL_MAP2_VERTEX_ATTRIB9_4_NV:
893      case GL_MAP2_VERTEX_ATTRIB10_4_NV:
894      case GL_MAP2_VERTEX_ATTRIB11_4_NV:
895      case GL_MAP2_VERTEX_ATTRIB12_4_NV:
896      case GL_MAP2_VERTEX_ATTRIB13_4_NV:
897      case GL_MAP2_VERTEX_ATTRIB14_4_NV:
898      case GL_MAP2_VERTEX_ATTRIB15_4_NV:
899         if (ctx->API != API_OPENGL)
900            goto invalid_enum_error;
901         CHECK_EXTENSION(NV_vertex_program, cap);
902         {
903            const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
904            FLUSH_VERTICES(ctx, _NEW_EVAL);
905            ctx->Eval.Map2Attrib[map] = state;
906         }
907         break;
908#endif /* FEATURE_NV_vertex_program */
909
910#if FEATURE_NV_fragment_program
911      case GL_FRAGMENT_PROGRAM_NV:
912         if (ctx->API != API_OPENGL)
913            goto invalid_enum_error;
914         CHECK_EXTENSION(NV_fragment_program, cap);
915         if (ctx->FragmentProgram.Enabled == state)
916            return;
917         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
918         ctx->FragmentProgram.Enabled = state;
919         break;
920#endif /* FEATURE_NV_fragment_program */
921
922      /* GL_NV_texture_rectangle */
923      case GL_TEXTURE_RECTANGLE_NV:
924         if (ctx->API != API_OPENGL)
925            goto invalid_enum_error;
926         CHECK_EXTENSION(NV_texture_rectangle, cap);
927         if (!enable_texture(ctx, state, TEXTURE_RECT_BIT)) {
928            return;
929         }
930         break;
931
932      /* GL_EXT_stencil_two_side */
933      case GL_STENCIL_TEST_TWO_SIDE_EXT:
934         if (ctx->API != API_OPENGL)
935            goto invalid_enum_error;
936         CHECK_EXTENSION(EXT_stencil_two_side, cap);
937         if (ctx->Stencil.TestTwoSide == state)
938            return;
939         FLUSH_VERTICES(ctx, _NEW_STENCIL);
940         ctx->Stencil.TestTwoSide = state;
941         if (state) {
942            ctx->Stencil._BackFace = 2;
943         } else {
944            ctx->Stencil._BackFace = 1;
945         }
946         break;
947
948#if FEATURE_ARB_fragment_program
949      case GL_FRAGMENT_PROGRAM_ARB:
950         if (ctx->API != API_OPENGL)
951            goto invalid_enum_error;
952         CHECK_EXTENSION(ARB_fragment_program, cap);
953         if (ctx->FragmentProgram.Enabled == state)
954            return;
955         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
956         ctx->FragmentProgram.Enabled = state;
957         break;
958#endif /* FEATURE_ARB_fragment_program */
959
960      /* GL_EXT_depth_bounds_test */
961      case GL_DEPTH_BOUNDS_TEST_EXT:
962         if (!_mesa_is_desktop_gl(ctx))
963            goto invalid_enum_error;
964         CHECK_EXTENSION(EXT_depth_bounds_test, cap);
965         if (ctx->Depth.BoundsTest == state)
966            return;
967         FLUSH_VERTICES(ctx, _NEW_DEPTH);
968         ctx->Depth.BoundsTest = state;
969         break;
970
971      case GL_DEPTH_CLAMP:
972         if (!_mesa_is_desktop_gl(ctx))
973            goto invalid_enum_error;
974	 CHECK_EXTENSION(ARB_depth_clamp, cap);
975         if (ctx->Transform.DepthClamp == state)
976            return;
977         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
978	 ctx->Transform.DepthClamp = state;
979	 break;
980
981#if FEATURE_ATI_fragment_shader
982      case GL_FRAGMENT_SHADER_ATI:
983         if (ctx->API != API_OPENGL)
984            goto invalid_enum_error;
985        CHECK_EXTENSION(ATI_fragment_shader, cap);
986	if (ctx->ATIFragmentShader.Enabled == state)
987	  return;
988	FLUSH_VERTICES(ctx, _NEW_PROGRAM);
989	ctx->ATIFragmentShader.Enabled = state;
990        break;
991#endif
992
993      /* GL_MESA_texture_array */
994      case GL_TEXTURE_1D_ARRAY_EXT:
995         if (ctx->API != API_OPENGL)
996            goto invalid_enum_error;
997         CHECK_EXTENSION(MESA_texture_array, cap);
998         if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) {
999            return;
1000         }
1001         break;
1002
1003      case GL_TEXTURE_2D_ARRAY_EXT:
1004         if (ctx->API != API_OPENGL)
1005            goto invalid_enum_error;
1006         CHECK_EXTENSION(MESA_texture_array, cap);
1007         if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) {
1008            return;
1009         }
1010         break;
1011
1012      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1013         if (!_mesa_is_desktop_gl(ctx))
1014            goto invalid_enum_error;
1015	 CHECK_EXTENSION(ARB_seamless_cube_map, cap);
1016	 if (ctx->Texture.CubeMapSeamless != state) {
1017	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1018	    ctx->Texture.CubeMapSeamless = state;
1019	 }
1020	 break;
1021
1022#if FEATURE_EXT_transform_feedback
1023      case GL_RASTERIZER_DISCARD:
1024         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1025            goto invalid_enum_error;
1026	 CHECK_EXTENSION(EXT_transform_feedback, cap);
1027         if (ctx->RasterDiscard != state) {
1028            FLUSH_VERTICES(ctx, _NEW_RASTERIZER_DISCARD);
1029            ctx->RasterDiscard = state;
1030         }
1031         break;
1032#endif
1033
1034      /* GL 3.1 primitive restart.  Note: this enum is different from
1035       * GL_PRIMITIVE_RESTART_NV (which is client state).
1036       */
1037      case GL_PRIMITIVE_RESTART:
1038         if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 31) {
1039            goto invalid_enum_error;
1040         }
1041         if (ctx->Array.PrimitiveRestart != state) {
1042            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1043            ctx->Array.PrimitiveRestart = state;
1044         }
1045         break;
1046
1047      /* GL3.0 - GL_framebuffer_sRGB */
1048      case GL_FRAMEBUFFER_SRGB_EXT:
1049         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1050            goto invalid_enum_error;
1051         CHECK_EXTENSION(EXT_framebuffer_sRGB, cap);
1052         FLUSH_VERTICES(ctx, _NEW_BUFFERS);
1053         ctx->Color.sRGBEnabled = state;
1054         break;
1055
1056      /* GL_OES_EGL_image_external */
1057      case GL_TEXTURE_EXTERNAL_OES:
1058         if (!_mesa_is_gles(ctx))
1059            goto invalid_enum_error;
1060         CHECK_EXTENSION(OES_EGL_image_external, cap);
1061         if (!enable_texture(ctx, state, TEXTURE_EXTERNAL_BIT)) {
1062            return;
1063         }
1064         break;
1065
1066      default:
1067         goto invalid_enum_error;
1068   }
1069
1070   if (ctx->Driver.Enable) {
1071      ctx->Driver.Enable( ctx, cap, state );
1072   }
1073
1074   return;
1075
1076invalid_enum_error:
1077   _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(%s)",
1078               state ? "Enable" : "Disable", _mesa_lookup_enum_by_nr(cap));
1079}
1080
1081
1082/**
1083 * Enable GL capability.  Called by glEnable()
1084 * \param cap  state to enable.
1085 */
1086void GLAPIENTRY
1087_mesa_Enable( GLenum cap )
1088{
1089   GET_CURRENT_CONTEXT(ctx);
1090   ASSERT_OUTSIDE_BEGIN_END(ctx);
1091
1092   _mesa_set_enable( ctx, cap, GL_TRUE );
1093}
1094
1095
1096/**
1097 * Disable GL capability.  Called by glDisable()
1098 * \param cap  state to disable.
1099 */
1100void GLAPIENTRY
1101_mesa_Disable( GLenum cap )
1102{
1103   GET_CURRENT_CONTEXT(ctx);
1104   ASSERT_OUTSIDE_BEGIN_END(ctx);
1105
1106   _mesa_set_enable( ctx, cap, GL_FALSE );
1107}
1108
1109
1110
1111/**
1112 * Enable/disable an indexed state var.
1113 */
1114void
1115_mesa_set_enablei(struct gl_context *ctx, GLenum cap,
1116                  GLuint index, GLboolean state)
1117{
1118   ASSERT(state == 0 || state == 1);
1119   switch (cap) {
1120   case GL_BLEND:
1121      if (!ctx->Extensions.EXT_draw_buffers2) {
1122         goto invalid_enum_error;
1123      }
1124      if (index >= ctx->Const.MaxDrawBuffers) {
1125         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1126                     state ? "glEnableIndexed" : "glDisableIndexed", index);
1127         return;
1128      }
1129      if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
1130         FLUSH_VERTICES(ctx, _NEW_COLOR);
1131         if (state)
1132            ctx->Color.BlendEnabled |= (1 << index);
1133         else
1134            ctx->Color.BlendEnabled &= ~(1 << index);
1135      }
1136      break;
1137   default:
1138      goto invalid_enum_error;
1139   }
1140   return;
1141
1142invalid_enum_error:
1143    _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
1144                state ? "glEnablei" : "glDisablei",
1145                _mesa_lookup_enum_by_nr(cap));
1146}
1147
1148
1149void GLAPIENTRY
1150_mesa_DisableIndexed( GLenum cap, GLuint index )
1151{
1152   GET_CURRENT_CONTEXT(ctx);
1153   ASSERT_OUTSIDE_BEGIN_END(ctx);
1154   _mesa_set_enablei(ctx, cap, index, GL_FALSE);
1155}
1156
1157
1158void GLAPIENTRY
1159_mesa_EnableIndexed( GLenum cap, GLuint index )
1160{
1161   GET_CURRENT_CONTEXT(ctx);
1162   ASSERT_OUTSIDE_BEGIN_END(ctx);
1163   _mesa_set_enablei(ctx, cap, index, GL_TRUE);
1164}
1165
1166
1167GLboolean GLAPIENTRY
1168_mesa_IsEnabledIndexed( GLenum cap, GLuint index )
1169{
1170   GET_CURRENT_CONTEXT(ctx);
1171   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1172   switch (cap) {
1173   case GL_BLEND:
1174      if (index >= ctx->Const.MaxDrawBuffers) {
1175         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1176                     index);
1177         return GL_FALSE;
1178      }
1179      return (ctx->Color.BlendEnabled >> index) & 1;
1180   default:
1181      _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
1182                  _mesa_lookup_enum_by_nr(cap));
1183      return GL_FALSE;
1184   }
1185}
1186
1187
1188
1189
1190#undef CHECK_EXTENSION
1191#define CHECK_EXTENSION(EXTNAME)			\
1192   if (!ctx->Extensions.EXTNAME) {			\
1193      goto invalid_enum_error;				\
1194   }
1195
1196#undef CHECK_EXTENSION2
1197#define CHECK_EXTENSION2(EXT1, EXT2)				\
1198   if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) {	\
1199      goto invalid_enum_error;					\
1200   }
1201
1202
1203/**
1204 * Helper function to determine whether a texture target is enabled.
1205 */
1206static GLboolean
1207is_texture_enabled(struct gl_context *ctx, GLbitfield bit)
1208{
1209   const struct gl_texture_unit *const texUnit =
1210       &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1211   return (texUnit->Enabled & bit) ? GL_TRUE : GL_FALSE;
1212}
1213
1214
1215/**
1216 * Return simple enable/disable state.
1217 *
1218 * \param cap  state variable to query.
1219 *
1220 * Returns the state of the specified capability from the current GL context.
1221 * For the capabilities associated with extensions verifies that those
1222 * extensions are effectively present before reporting.
1223 */
1224GLboolean GLAPIENTRY
1225_mesa_IsEnabled( GLenum cap )
1226{
1227   GET_CURRENT_CONTEXT(ctx);
1228   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1229
1230   switch (cap) {
1231      case GL_ALPHA_TEST:
1232         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1233            goto invalid_enum_error;
1234         return ctx->Color.AlphaEnabled;
1235      case GL_AUTO_NORMAL:
1236         if (ctx->API != API_OPENGL)
1237            goto invalid_enum_error;
1238	 return ctx->Eval.AutoNormal;
1239      case GL_BLEND:
1240         return ctx->Color.BlendEnabled & 1;  /* return state for buffer[0] */
1241      case GL_CLIP_DISTANCE0:
1242      case GL_CLIP_DISTANCE1:
1243      case GL_CLIP_DISTANCE2:
1244      case GL_CLIP_DISTANCE3:
1245      case GL_CLIP_DISTANCE4:
1246      case GL_CLIP_DISTANCE5:
1247      case GL_CLIP_DISTANCE6:
1248      case GL_CLIP_DISTANCE7: {
1249         const GLuint p = cap - GL_CLIP_DISTANCE0;
1250
1251         if (p >= ctx->Const.MaxClipPlanes)
1252            goto invalid_enum_error;
1253
1254	 return (ctx->Transform.ClipPlanesEnabled >> p) & 1;
1255      }
1256      case GL_COLOR_MATERIAL:
1257         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1258            goto invalid_enum_error;
1259	 return ctx->Light.ColorMaterialEnabled;
1260      case GL_CULL_FACE:
1261         return ctx->Polygon.CullFlag;
1262      case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
1263         if (!_mesa_is_desktop_gl(ctx))
1264            goto invalid_enum_error;
1265         return ctx->Debug.SyncOutput;
1266      case GL_DEPTH_TEST:
1267         return ctx->Depth.Test;
1268      case GL_DITHER:
1269	 return ctx->Color.DitherFlag;
1270      case GL_FOG:
1271         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1272            goto invalid_enum_error;
1273	 return ctx->Fog.Enabled;
1274      case GL_LIGHTING:
1275         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1276            goto invalid_enum_error;
1277         return ctx->Light.Enabled;
1278      case GL_LIGHT0:
1279      case GL_LIGHT1:
1280      case GL_LIGHT2:
1281      case GL_LIGHT3:
1282      case GL_LIGHT4:
1283      case GL_LIGHT5:
1284      case GL_LIGHT6:
1285      case GL_LIGHT7:
1286         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1287            goto invalid_enum_error;
1288         return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
1289      case GL_LINE_SMOOTH:
1290         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1291            goto invalid_enum_error;
1292	 return ctx->Line.SmoothFlag;
1293      case GL_LINE_STIPPLE:
1294         if (ctx->API != API_OPENGL)
1295            goto invalid_enum_error;
1296	 return ctx->Line.StippleFlag;
1297      case GL_INDEX_LOGIC_OP:
1298         if (ctx->API != API_OPENGL)
1299            goto invalid_enum_error;
1300	 return ctx->Color.IndexLogicOpEnabled;
1301      case GL_COLOR_LOGIC_OP:
1302         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1303            goto invalid_enum_error;
1304	 return ctx->Color.ColorLogicOpEnabled;
1305      case GL_MAP1_COLOR_4:
1306         if (ctx->API != API_OPENGL)
1307            goto invalid_enum_error;
1308	 return ctx->Eval.Map1Color4;
1309      case GL_MAP1_INDEX:
1310         if (ctx->API != API_OPENGL)
1311            goto invalid_enum_error;
1312	 return ctx->Eval.Map1Index;
1313      case GL_MAP1_NORMAL:
1314         if (ctx->API != API_OPENGL)
1315            goto invalid_enum_error;
1316	 return ctx->Eval.Map1Normal;
1317      case GL_MAP1_TEXTURE_COORD_1:
1318         if (ctx->API != API_OPENGL)
1319            goto invalid_enum_error;
1320	 return ctx->Eval.Map1TextureCoord1;
1321      case GL_MAP1_TEXTURE_COORD_2:
1322         if (ctx->API != API_OPENGL)
1323            goto invalid_enum_error;
1324	 return ctx->Eval.Map1TextureCoord2;
1325      case GL_MAP1_TEXTURE_COORD_3:
1326         if (ctx->API != API_OPENGL)
1327            goto invalid_enum_error;
1328	 return ctx->Eval.Map1TextureCoord3;
1329      case GL_MAP1_TEXTURE_COORD_4:
1330         if (ctx->API != API_OPENGL)
1331            goto invalid_enum_error;
1332	 return ctx->Eval.Map1TextureCoord4;
1333      case GL_MAP1_VERTEX_3:
1334         if (ctx->API != API_OPENGL)
1335            goto invalid_enum_error;
1336	 return ctx->Eval.Map1Vertex3;
1337      case GL_MAP1_VERTEX_4:
1338         if (ctx->API != API_OPENGL)
1339            goto invalid_enum_error;
1340	 return ctx->Eval.Map1Vertex4;
1341      case GL_MAP2_COLOR_4:
1342         if (ctx->API != API_OPENGL)
1343            goto invalid_enum_error;
1344	 return ctx->Eval.Map2Color4;
1345      case GL_MAP2_INDEX:
1346         if (ctx->API != API_OPENGL)
1347            goto invalid_enum_error;
1348	 return ctx->Eval.Map2Index;
1349      case GL_MAP2_NORMAL:
1350         if (ctx->API != API_OPENGL)
1351            goto invalid_enum_error;
1352	 return ctx->Eval.Map2Normal;
1353      case GL_MAP2_TEXTURE_COORD_1:
1354         if (ctx->API != API_OPENGL)
1355            goto invalid_enum_error;
1356	 return ctx->Eval.Map2TextureCoord1;
1357      case GL_MAP2_TEXTURE_COORD_2:
1358         if (ctx->API != API_OPENGL)
1359            goto invalid_enum_error;
1360	 return ctx->Eval.Map2TextureCoord2;
1361      case GL_MAP2_TEXTURE_COORD_3:
1362         if (ctx->API != API_OPENGL)
1363            goto invalid_enum_error;
1364	 return ctx->Eval.Map2TextureCoord3;
1365      case GL_MAP2_TEXTURE_COORD_4:
1366         if (ctx->API != API_OPENGL)
1367            goto invalid_enum_error;
1368	 return ctx->Eval.Map2TextureCoord4;
1369      case GL_MAP2_VERTEX_3:
1370         if (ctx->API != API_OPENGL)
1371            goto invalid_enum_error;
1372	 return ctx->Eval.Map2Vertex3;
1373      case GL_MAP2_VERTEX_4:
1374         if (ctx->API != API_OPENGL)
1375            goto invalid_enum_error;
1376	 return ctx->Eval.Map2Vertex4;
1377      case GL_NORMALIZE:
1378         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1379            goto invalid_enum_error;
1380	 return ctx->Transform.Normalize;
1381      case GL_POINT_SMOOTH:
1382         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1383            goto invalid_enum_error;
1384	 return ctx->Point.SmoothFlag;
1385      case GL_POLYGON_SMOOTH:
1386         if (!_mesa_is_desktop_gl(ctx))
1387            goto invalid_enum_error;
1388	 return ctx->Polygon.SmoothFlag;
1389      case GL_POLYGON_STIPPLE:
1390         if (ctx->API != API_OPENGL)
1391            goto invalid_enum_error;
1392	 return ctx->Polygon.StippleFlag;
1393      case GL_POLYGON_OFFSET_POINT:
1394         if (!_mesa_is_desktop_gl(ctx))
1395            goto invalid_enum_error;
1396	 return ctx->Polygon.OffsetPoint;
1397      case GL_POLYGON_OFFSET_LINE:
1398         if (!_mesa_is_desktop_gl(ctx))
1399            goto invalid_enum_error;
1400	 return ctx->Polygon.OffsetLine;
1401      case GL_POLYGON_OFFSET_FILL:
1402	 return ctx->Polygon.OffsetFill;
1403      case GL_RESCALE_NORMAL_EXT:
1404         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1405            goto invalid_enum_error;
1406         return ctx->Transform.RescaleNormals;
1407      case GL_SCISSOR_TEST:
1408	 return ctx->Scissor.Enabled;
1409      case GL_STENCIL_TEST:
1410	 return ctx->Stencil.Enabled;
1411      case GL_TEXTURE_1D:
1412         if (ctx->API != API_OPENGL)
1413            goto invalid_enum_error;
1414         return is_texture_enabled(ctx, TEXTURE_1D_BIT);
1415      case GL_TEXTURE_2D:
1416         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1417            goto invalid_enum_error;
1418         return is_texture_enabled(ctx, TEXTURE_2D_BIT);
1419      case GL_TEXTURE_3D:
1420         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1421            goto invalid_enum_error;
1422         return is_texture_enabled(ctx, TEXTURE_3D_BIT);
1423      case GL_TEXTURE_GEN_S:
1424      case GL_TEXTURE_GEN_T:
1425      case GL_TEXTURE_GEN_R:
1426      case GL_TEXTURE_GEN_Q:
1427         {
1428            const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
1429
1430            if (ctx->API != API_OPENGL)
1431               goto invalid_enum_error;
1432
1433            if (texUnit) {
1434               GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
1435               return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE;
1436            }
1437         }
1438         return GL_FALSE;
1439#if FEATURE_ES1
1440      case GL_TEXTURE_GEN_STR_OES:
1441	 {
1442            const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
1443
1444            if (ctx->API != API_OPENGLES)
1445               goto invalid_enum_error;
1446
1447            if (texUnit) {
1448               return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS
1449                  ? GL_TRUE : GL_FALSE;
1450            }
1451         }
1452#endif
1453
1454      /* client-side state */
1455      case GL_VERTEX_ARRAY:
1456         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1457            goto invalid_enum_error;
1458         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled != 0);
1459      case GL_NORMAL_ARRAY:
1460         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1461            goto invalid_enum_error;
1462         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled != 0);
1463      case GL_COLOR_ARRAY:
1464         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1465            goto invalid_enum_error;
1466         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled != 0);
1467      case GL_INDEX_ARRAY:
1468         if (ctx->API != API_OPENGL)
1469            goto invalid_enum_error;
1470         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled != 0);
1471      case GL_TEXTURE_COORD_ARRAY:
1472         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1473            goto invalid_enum_error;
1474         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)]
1475                 .Enabled != 0);
1476      case GL_EDGE_FLAG_ARRAY:
1477         if (ctx->API != API_OPENGL)
1478            goto invalid_enum_error;
1479         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled != 0);
1480      case GL_FOG_COORDINATE_ARRAY_EXT:
1481         if (ctx->API != API_OPENGL)
1482            goto invalid_enum_error;
1483         CHECK_EXTENSION(EXT_fog_coord);
1484         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled != 0);
1485      case GL_SECONDARY_COLOR_ARRAY_EXT:
1486         if (ctx->API != API_OPENGL)
1487            goto invalid_enum_error;
1488         CHECK_EXTENSION(EXT_secondary_color);
1489         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled != 0);
1490#if FEATURE_point_size_array
1491      case GL_POINT_SIZE_ARRAY_OES:
1492         if (ctx->API != API_OPENGLES)
1493            goto invalid_enum_error;
1494         return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Enabled != 0);
1495#endif
1496
1497      /* GL_ARB_texture_cube_map */
1498      case GL_TEXTURE_CUBE_MAP_ARB:
1499         CHECK_EXTENSION(ARB_texture_cube_map);
1500         return is_texture_enabled(ctx, TEXTURE_CUBE_BIT);
1501
1502      /* GL_EXT_secondary_color */
1503      case GL_COLOR_SUM_EXT:
1504         if (ctx->API != API_OPENGL)
1505            goto invalid_enum_error;
1506         CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program);
1507         return ctx->Fog.ColorSumEnabled;
1508
1509      /* GL_ARB_multisample */
1510      case GL_MULTISAMPLE_ARB:
1511         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1512            goto invalid_enum_error;
1513         return ctx->Multisample.Enabled;
1514      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
1515         return ctx->Multisample.SampleAlphaToCoverage;
1516      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
1517         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1518            goto invalid_enum_error;
1519         return ctx->Multisample.SampleAlphaToOne;
1520      case GL_SAMPLE_COVERAGE_ARB:
1521         return ctx->Multisample.SampleCoverage;
1522      case GL_SAMPLE_COVERAGE_INVERT_ARB:
1523         if (!_mesa_is_desktop_gl(ctx))
1524            goto invalid_enum_error;
1525         return ctx->Multisample.SampleCoverageInvert;
1526
1527      /* GL_IBM_rasterpos_clip */
1528      case GL_RASTER_POSITION_UNCLIPPED_IBM:
1529         if (ctx->API != API_OPENGL)
1530            goto invalid_enum_error;
1531         CHECK_EXTENSION(IBM_rasterpos_clip);
1532         return ctx->Transform.RasterPositionUnclipped;
1533
1534      /* GL_NV_point_sprite */
1535      case GL_POINT_SPRITE_NV:
1536         if (ctx->API != API_OPENGL && ctx->API != API_OPENGLES)
1537            goto invalid_enum_error;
1538         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite)
1539         return ctx->Point.PointSprite;
1540
1541#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
1542      case GL_VERTEX_PROGRAM_ARB:
1543         if (ctx->API != API_OPENGL)
1544            goto invalid_enum_error;
1545         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1546         return ctx->VertexProgram.Enabled;
1547      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1548         /* This was added with ARB_vertex_program, but it is also used with
1549          * GLSL vertex shaders on desktop.
1550          */
1551         if (!_mesa_is_desktop_gl(ctx))
1552            goto invalid_enum_error;
1553         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1554         return ctx->VertexProgram.PointSizeEnabled;
1555      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
1556         if (ctx->API != API_OPENGL)
1557            goto invalid_enum_error;
1558         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program);
1559         return ctx->VertexProgram.TwoSideEnabled;
1560#endif
1561#if FEATURE_NV_vertex_program
1562      case GL_VERTEX_ATTRIB_ARRAY0_NV:
1563      case GL_VERTEX_ATTRIB_ARRAY1_NV:
1564      case GL_VERTEX_ATTRIB_ARRAY2_NV:
1565      case GL_VERTEX_ATTRIB_ARRAY3_NV:
1566      case GL_VERTEX_ATTRIB_ARRAY4_NV:
1567      case GL_VERTEX_ATTRIB_ARRAY5_NV:
1568      case GL_VERTEX_ATTRIB_ARRAY6_NV:
1569      case GL_VERTEX_ATTRIB_ARRAY7_NV:
1570      case GL_VERTEX_ATTRIB_ARRAY8_NV:
1571      case GL_VERTEX_ATTRIB_ARRAY9_NV:
1572      case GL_VERTEX_ATTRIB_ARRAY10_NV:
1573      case GL_VERTEX_ATTRIB_ARRAY11_NV:
1574      case GL_VERTEX_ATTRIB_ARRAY12_NV:
1575      case GL_VERTEX_ATTRIB_ARRAY13_NV:
1576      case GL_VERTEX_ATTRIB_ARRAY14_NV:
1577      case GL_VERTEX_ATTRIB_ARRAY15_NV:
1578         if (ctx->API != API_OPENGL)
1579            goto invalid_enum_error;
1580         CHECK_EXTENSION(NV_vertex_program);
1581         {
1582            GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
1583            ASSERT(VERT_ATTRIB_GENERIC(n) < Elements(ctx->Array.ArrayObj->VertexAttrib));
1584            return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(n)].Enabled != 0);
1585         }
1586      case GL_MAP1_VERTEX_ATTRIB0_4_NV:
1587      case GL_MAP1_VERTEX_ATTRIB1_4_NV:
1588      case GL_MAP1_VERTEX_ATTRIB2_4_NV:
1589      case GL_MAP1_VERTEX_ATTRIB3_4_NV:
1590      case GL_MAP1_VERTEX_ATTRIB4_4_NV:
1591      case GL_MAP1_VERTEX_ATTRIB5_4_NV:
1592      case GL_MAP1_VERTEX_ATTRIB6_4_NV:
1593      case GL_MAP1_VERTEX_ATTRIB7_4_NV:
1594      case GL_MAP1_VERTEX_ATTRIB8_4_NV:
1595      case GL_MAP1_VERTEX_ATTRIB9_4_NV:
1596      case GL_MAP1_VERTEX_ATTRIB10_4_NV:
1597      case GL_MAP1_VERTEX_ATTRIB11_4_NV:
1598      case GL_MAP1_VERTEX_ATTRIB12_4_NV:
1599      case GL_MAP1_VERTEX_ATTRIB13_4_NV:
1600      case GL_MAP1_VERTEX_ATTRIB14_4_NV:
1601      case GL_MAP1_VERTEX_ATTRIB15_4_NV:
1602         if (ctx->API != API_OPENGL)
1603            goto invalid_enum_error;
1604         CHECK_EXTENSION(NV_vertex_program);
1605         {
1606            const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
1607            return ctx->Eval.Map1Attrib[map];
1608         }
1609      case GL_MAP2_VERTEX_ATTRIB0_4_NV:
1610      case GL_MAP2_VERTEX_ATTRIB1_4_NV:
1611      case GL_MAP2_VERTEX_ATTRIB2_4_NV:
1612      case GL_MAP2_VERTEX_ATTRIB3_4_NV:
1613      case GL_MAP2_VERTEX_ATTRIB4_4_NV:
1614      case GL_MAP2_VERTEX_ATTRIB5_4_NV:
1615      case GL_MAP2_VERTEX_ATTRIB6_4_NV:
1616      case GL_MAP2_VERTEX_ATTRIB7_4_NV:
1617      case GL_MAP2_VERTEX_ATTRIB8_4_NV:
1618      case GL_MAP2_VERTEX_ATTRIB9_4_NV:
1619      case GL_MAP2_VERTEX_ATTRIB10_4_NV:
1620      case GL_MAP2_VERTEX_ATTRIB11_4_NV:
1621      case GL_MAP2_VERTEX_ATTRIB12_4_NV:
1622      case GL_MAP2_VERTEX_ATTRIB13_4_NV:
1623      case GL_MAP2_VERTEX_ATTRIB14_4_NV:
1624      case GL_MAP2_VERTEX_ATTRIB15_4_NV:
1625         if (ctx->API != API_OPENGL)
1626            goto invalid_enum_error;
1627         CHECK_EXTENSION(NV_vertex_program);
1628         {
1629            const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
1630            return ctx->Eval.Map2Attrib[map];
1631         }
1632#endif /* FEATURE_NV_vertex_program */
1633
1634#if FEATURE_NV_fragment_program
1635      case GL_FRAGMENT_PROGRAM_NV:
1636         if (ctx->API != API_OPENGL)
1637            goto invalid_enum_error;
1638         CHECK_EXTENSION(NV_fragment_program);
1639         return ctx->FragmentProgram.Enabled;
1640#endif /* FEATURE_NV_fragment_program */
1641
1642      /* GL_NV_texture_rectangle */
1643      case GL_TEXTURE_RECTANGLE_NV:
1644         if (ctx->API != API_OPENGL)
1645            goto invalid_enum_error;
1646         CHECK_EXTENSION(NV_texture_rectangle);
1647         return is_texture_enabled(ctx, TEXTURE_RECT_BIT);
1648
1649      /* GL_EXT_stencil_two_side */
1650      case GL_STENCIL_TEST_TWO_SIDE_EXT:
1651         if (ctx->API != API_OPENGL)
1652            goto invalid_enum_error;
1653         CHECK_EXTENSION(EXT_stencil_two_side);
1654         return ctx->Stencil.TestTwoSide;
1655
1656#if FEATURE_ARB_fragment_program
1657      case GL_FRAGMENT_PROGRAM_ARB:
1658         if (ctx->API != API_OPENGL)
1659            goto invalid_enum_error;
1660         return ctx->FragmentProgram.Enabled;
1661#endif /* FEATURE_ARB_fragment_program */
1662
1663      /* GL_EXT_depth_bounds_test */
1664      case GL_DEPTH_BOUNDS_TEST_EXT:
1665         if (!_mesa_is_desktop_gl(ctx))
1666            goto invalid_enum_error;
1667         CHECK_EXTENSION(EXT_depth_bounds_test);
1668         return ctx->Depth.BoundsTest;
1669
1670      /* GL_ARB_depth_clamp */
1671      case GL_DEPTH_CLAMP:
1672         if (!_mesa_is_desktop_gl(ctx))
1673            goto invalid_enum_error;
1674         CHECK_EXTENSION(ARB_depth_clamp);
1675         return ctx->Transform.DepthClamp;
1676
1677#if FEATURE_ATI_fragment_shader
1678      case GL_FRAGMENT_SHADER_ATI:
1679         if (ctx->API != API_OPENGL)
1680            goto invalid_enum_error;
1681	 CHECK_EXTENSION(ATI_fragment_shader);
1682	 return ctx->ATIFragmentShader.Enabled;
1683#endif /* FEATURE_ATI_fragment_shader */
1684
1685      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1686         if (!_mesa_is_desktop_gl(ctx))
1687            goto invalid_enum_error;
1688	 CHECK_EXTENSION(ARB_seamless_cube_map);
1689	 return ctx->Texture.CubeMapSeamless;
1690
1691#if FEATURE_EXT_transform_feedback
1692      case GL_RASTERIZER_DISCARD:
1693         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1694            goto invalid_enum_error;
1695	 CHECK_EXTENSION(EXT_transform_feedback);
1696         return ctx->RasterDiscard;
1697#endif
1698
1699      /* GL_NV_primitive_restart */
1700      case GL_PRIMITIVE_RESTART_NV:
1701         if (ctx->API != API_OPENGL || !ctx->Extensions.NV_primitive_restart) {
1702            goto invalid_enum_error;
1703         }
1704         return ctx->Array.PrimitiveRestart;
1705
1706      /* GL 3.1 primitive restart */
1707      case GL_PRIMITIVE_RESTART:
1708         if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 31) {
1709            goto invalid_enum_error;
1710         }
1711         return ctx->Array.PrimitiveRestart;
1712
1713      /* GL3.0 - GL_framebuffer_sRGB */
1714      case GL_FRAMEBUFFER_SRGB_EXT:
1715         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1716            goto invalid_enum_error;
1717	 CHECK_EXTENSION(EXT_framebuffer_sRGB);
1718	 return ctx->Color.sRGBEnabled;
1719
1720      /* GL_OES_EGL_image_external */
1721      case GL_TEXTURE_EXTERNAL_OES:
1722         if (!_mesa_is_gles(ctx))
1723            goto invalid_enum_error;
1724	 CHECK_EXTENSION(OES_EGL_image_external);
1725         return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT);
1726
1727      default:
1728         goto invalid_enum_error;
1729   }
1730
1731   return GL_FALSE;
1732
1733invalid_enum_error:
1734   _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(%s)",
1735               _mesa_lookup_enum_by_nr(cap));
1736   return GL_FALSE;
1737}
1738