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