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