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  */
54 static void
client_state(struct gl_context * ctx,GLenum cap,GLboolean state)55 client_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 
164 invalid_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  */
177 void GLAPIENTRY
_mesa_EnableClientState(GLenum cap)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  */
193 void GLAPIENTRY
_mesa_DisableClientState(GLenum cap)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  */
219 static struct gl_texture_unit *
get_texcoord_unit(struct gl_context * ctx)220 get_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  */
237 static GLboolean
enable_texture(struct gl_context * ctx,GLboolean state,GLbitfield texBit)238 enable_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  */
265 void
_mesa_set_enable(struct gl_context * ctx,GLenum cap,GLboolean state)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 
1077 invalid_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  */
1087 void GLAPIENTRY
_mesa_Enable(GLenum cap)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  */
1101 void GLAPIENTRY
_mesa_Disable(GLenum cap)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  */
1115 void
_mesa_set_enablei(struct gl_context * ctx,GLenum cap,GLuint index,GLboolean state)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 
1143 invalid_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 
1150 void GLAPIENTRY
_mesa_DisableIndexed(GLenum cap,GLuint index)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 
1159 void GLAPIENTRY
_mesa_EnableIndexed(GLenum cap,GLuint index)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 
1168 GLboolean GLAPIENTRY
_mesa_IsEnabledIndexed(GLenum cap,GLuint index)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  */
1207 static GLboolean
is_texture_enabled(struct gl_context * ctx,GLbitfield bit)1208 is_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  */
1225 GLboolean GLAPIENTRY
_mesa_IsEnabled(GLenum cap)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 
1734 invalid_enum_error:
1735    _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(%s)",
1736                _mesa_lookup_enum_by_nr(cap));
1737    return GL_FALSE;
1738 }
1739