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