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