enable.c revision a8bb7a65
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_has_ARB_depth_clamp(ctx) &&
1008             !_mesa_has_EXT_depth_clamp(ctx))
1009            goto invalid_enum_error;
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         CHECK_EXTENSION(EXT_framebuffer_sRGB, cap);
1129         _mesa_set_framebuffer_srgb(ctx, state);
1130         return;
1131
1132      /* GL_OES_EGL_image_external */
1133      case GL_TEXTURE_EXTERNAL_OES:
1134         if (!_mesa_is_gles(ctx))
1135            goto invalid_enum_error;
1136         CHECK_EXTENSION(OES_EGL_image_external, cap);
1137         if (!enable_texture(ctx, state, TEXTURE_EXTERNAL_BIT)) {
1138            return;
1139         }
1140         break;
1141
1142      /* ARB_texture_multisample */
1143      case GL_SAMPLE_MASK:
1144         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles31(ctx))
1145            goto invalid_enum_error;
1146         CHECK_EXTENSION(ARB_texture_multisample, cap);
1147         if (ctx->Multisample.SampleMask == state)
1148            return;
1149         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 :
1150                                                         _NEW_MULTISAMPLE);
1151         ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask;
1152         ctx->Multisample.SampleMask = state;
1153         break;
1154
1155      case GL_BLEND_ADVANCED_COHERENT_KHR:
1156         CHECK_EXTENSION(KHR_blend_equation_advanced_coherent, cap);
1157         if (ctx->Color.BlendCoherent == state)
1158            return;
1159         FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR);
1160         ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
1161         ctx->Color.BlendCoherent = state;
1162         break;
1163
1164      default:
1165         goto invalid_enum_error;
1166   }
1167
1168   if (ctx->Driver.Enable) {
1169      ctx->Driver.Enable( ctx, cap, state );
1170   }
1171
1172   return;
1173
1174invalid_enum_error:
1175   _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(%s)",
1176               state ? "Enable" : "Disable", _mesa_enum_to_string(cap));
1177}
1178
1179
1180/**
1181 * Enable GL capability.  Called by glEnable()
1182 * \param cap  state to enable.
1183 */
1184void GLAPIENTRY
1185_mesa_Enable( GLenum cap )
1186{
1187   GET_CURRENT_CONTEXT(ctx);
1188
1189   _mesa_set_enable( ctx, cap, GL_TRUE );
1190}
1191
1192
1193/**
1194 * Disable GL capability.  Called by glDisable()
1195 * \param cap  state to disable.
1196 */
1197void GLAPIENTRY
1198_mesa_Disable( GLenum cap )
1199{
1200   GET_CURRENT_CONTEXT(ctx);
1201
1202   _mesa_set_enable( ctx, cap, GL_FALSE );
1203}
1204
1205
1206
1207/**
1208 * Enable/disable an indexed state var.
1209 */
1210void
1211_mesa_set_enablei(struct gl_context *ctx, GLenum cap,
1212                  GLuint index, GLboolean state)
1213{
1214   assert(state == 0 || state == 1);
1215   switch (cap) {
1216   case GL_BLEND:
1217      if (!ctx->Extensions.EXT_draw_buffers2) {
1218         goto invalid_enum_error;
1219      }
1220      if (index >= ctx->Const.MaxDrawBuffers) {
1221         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1222                     state ? "glEnableIndexed" : "glDisableIndexed", index);
1223         return;
1224      }
1225      if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
1226         GLbitfield enabled = ctx->Color.BlendEnabled;
1227
1228         if (state)
1229            enabled |= (1 << index);
1230         else
1231            enabled &= ~(1 << index);
1232
1233         _mesa_flush_vertices_for_blend_adv(ctx, enabled,
1234                                            ctx->Color._AdvancedBlendMode);
1235         ctx->Color.BlendEnabled = enabled;
1236      }
1237      break;
1238   case GL_SCISSOR_TEST:
1239      if (index >= ctx->Const.MaxViewports) {
1240         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1241                     state ? "glEnablei" : "glDisablei", index);
1242         return;
1243      }
1244      if (((ctx->Scissor.EnableFlags >> index) & 1) != state) {
1245         FLUSH_VERTICES(ctx,
1246                        ctx->DriverFlags.NewScissorTest ? 0 : _NEW_SCISSOR);
1247         ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest;
1248         if (state)
1249            ctx->Scissor.EnableFlags |= (1 << index);
1250         else
1251            ctx->Scissor.EnableFlags &= ~(1 << index);
1252      }
1253      break;
1254   default:
1255      goto invalid_enum_error;
1256   }
1257   return;
1258
1259invalid_enum_error:
1260    _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
1261                state ? "glEnablei" : "glDisablei",
1262                _mesa_enum_to_string(cap));
1263}
1264
1265
1266void GLAPIENTRY
1267_mesa_Disablei( GLenum cap, GLuint index )
1268{
1269   GET_CURRENT_CONTEXT(ctx);
1270   _mesa_set_enablei(ctx, cap, index, GL_FALSE);
1271}
1272
1273
1274void GLAPIENTRY
1275_mesa_Enablei( GLenum cap, GLuint index )
1276{
1277   GET_CURRENT_CONTEXT(ctx);
1278   _mesa_set_enablei(ctx, cap, index, GL_TRUE);
1279}
1280
1281
1282GLboolean GLAPIENTRY
1283_mesa_IsEnabledi( GLenum cap, GLuint index )
1284{
1285   GET_CURRENT_CONTEXT(ctx);
1286   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1287   switch (cap) {
1288   case GL_BLEND:
1289      if (index >= ctx->Const.MaxDrawBuffers) {
1290         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1291                     index);
1292         return GL_FALSE;
1293      }
1294      return (ctx->Color.BlendEnabled >> index) & 1;
1295   case GL_SCISSOR_TEST:
1296      if (index >= ctx->Const.MaxViewports) {
1297         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1298                     index);
1299         return GL_FALSE;
1300      }
1301      return (ctx->Scissor.EnableFlags >> index) & 1;
1302   default:
1303      _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
1304                  _mesa_enum_to_string(cap));
1305      return GL_FALSE;
1306   }
1307}
1308
1309
1310
1311
1312#undef CHECK_EXTENSION
1313#define CHECK_EXTENSION(EXTNAME)			\
1314   if (!ctx->Extensions.EXTNAME) {			\
1315      goto invalid_enum_error;				\
1316   }
1317
1318#undef CHECK_EXTENSION2
1319#define CHECK_EXTENSION2(EXT1, EXT2)				\
1320   if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) {	\
1321      goto invalid_enum_error;					\
1322   }
1323
1324
1325/**
1326 * Helper function to determine whether a texture target is enabled.
1327 */
1328static GLboolean
1329is_texture_enabled(struct gl_context *ctx, GLbitfield bit)
1330{
1331   const struct gl_fixedfunc_texture_unit *const texUnit =
1332      _mesa_get_current_fixedfunc_tex_unit(ctx);
1333
1334   if (!texUnit)
1335      return GL_FALSE;
1336
1337   return (texUnit->Enabled & bit) ? GL_TRUE : GL_FALSE;
1338}
1339
1340
1341/**
1342 * Return simple enable/disable state.
1343 *
1344 * \param cap  state variable to query.
1345 *
1346 * Returns the state of the specified capability from the current GL context.
1347 * For the capabilities associated with extensions verifies that those
1348 * extensions are effectively present before reporting.
1349 */
1350GLboolean GLAPIENTRY
1351_mesa_IsEnabled( GLenum cap )
1352{
1353   GET_CURRENT_CONTEXT(ctx);
1354   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1355
1356   switch (cap) {
1357      case GL_ALPHA_TEST:
1358         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1359            goto invalid_enum_error;
1360         return ctx->Color.AlphaEnabled;
1361      case GL_AUTO_NORMAL:
1362         if (ctx->API != API_OPENGL_COMPAT)
1363            goto invalid_enum_error;
1364         return ctx->Eval.AutoNormal;
1365      case GL_BLEND:
1366         return ctx->Color.BlendEnabled & 1;  /* return state for buffer[0] */
1367      case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */
1368      case GL_CLIP_DISTANCE1:
1369      case GL_CLIP_DISTANCE2:
1370      case GL_CLIP_DISTANCE3:
1371      case GL_CLIP_DISTANCE4:
1372      case GL_CLIP_DISTANCE5:
1373      case GL_CLIP_DISTANCE6:
1374      case GL_CLIP_DISTANCE7: {
1375         const GLuint p = cap - GL_CLIP_DISTANCE0;
1376
1377         if (p >= ctx->Const.MaxClipPlanes)
1378            goto invalid_enum_error;
1379
1380         return (ctx->Transform.ClipPlanesEnabled >> p) & 1;
1381      }
1382      case GL_COLOR_MATERIAL:
1383         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1384            goto invalid_enum_error;
1385         return ctx->Light.ColorMaterialEnabled;
1386      case GL_CULL_FACE:
1387         return ctx->Polygon.CullFlag;
1388      case GL_DEBUG_OUTPUT:
1389      case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
1390         return (GLboolean) _mesa_get_debug_state_int(ctx, cap);
1391      case GL_DEPTH_TEST:
1392         return ctx->Depth.Test;
1393      case GL_DITHER:
1394         return ctx->Color.DitherFlag;
1395      case GL_FOG:
1396         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1397            goto invalid_enum_error;
1398         return ctx->Fog.Enabled;
1399      case GL_LIGHTING:
1400         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1401            goto invalid_enum_error;
1402         return ctx->Light.Enabled;
1403      case GL_LIGHT0:
1404      case GL_LIGHT1:
1405      case GL_LIGHT2:
1406      case GL_LIGHT3:
1407      case GL_LIGHT4:
1408      case GL_LIGHT5:
1409      case GL_LIGHT6:
1410      case GL_LIGHT7:
1411         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1412            goto invalid_enum_error;
1413         return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
1414      case GL_LINE_SMOOTH:
1415         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1416            goto invalid_enum_error;
1417         return ctx->Line.SmoothFlag;
1418      case GL_LINE_STIPPLE:
1419         if (ctx->API != API_OPENGL_COMPAT)
1420            goto invalid_enum_error;
1421         return ctx->Line.StippleFlag;
1422      case GL_INDEX_LOGIC_OP:
1423         if (ctx->API != API_OPENGL_COMPAT)
1424            goto invalid_enum_error;
1425         return ctx->Color.IndexLogicOpEnabled;
1426      case GL_COLOR_LOGIC_OP:
1427         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1428            goto invalid_enum_error;
1429         return ctx->Color.ColorLogicOpEnabled;
1430      case GL_MAP1_COLOR_4:
1431         if (ctx->API != API_OPENGL_COMPAT)
1432            goto invalid_enum_error;
1433         return ctx->Eval.Map1Color4;
1434      case GL_MAP1_INDEX:
1435         if (ctx->API != API_OPENGL_COMPAT)
1436            goto invalid_enum_error;
1437         return ctx->Eval.Map1Index;
1438      case GL_MAP1_NORMAL:
1439         if (ctx->API != API_OPENGL_COMPAT)
1440            goto invalid_enum_error;
1441         return ctx->Eval.Map1Normal;
1442      case GL_MAP1_TEXTURE_COORD_1:
1443         if (ctx->API != API_OPENGL_COMPAT)
1444            goto invalid_enum_error;
1445         return ctx->Eval.Map1TextureCoord1;
1446      case GL_MAP1_TEXTURE_COORD_2:
1447         if (ctx->API != API_OPENGL_COMPAT)
1448            goto invalid_enum_error;
1449         return ctx->Eval.Map1TextureCoord2;
1450      case GL_MAP1_TEXTURE_COORD_3:
1451         if (ctx->API != API_OPENGL_COMPAT)
1452            goto invalid_enum_error;
1453         return ctx->Eval.Map1TextureCoord3;
1454      case GL_MAP1_TEXTURE_COORD_4:
1455         if (ctx->API != API_OPENGL_COMPAT)
1456            goto invalid_enum_error;
1457         return ctx->Eval.Map1TextureCoord4;
1458      case GL_MAP1_VERTEX_3:
1459         if (ctx->API != API_OPENGL_COMPAT)
1460            goto invalid_enum_error;
1461         return ctx->Eval.Map1Vertex3;
1462      case GL_MAP1_VERTEX_4:
1463         if (ctx->API != API_OPENGL_COMPAT)
1464            goto invalid_enum_error;
1465         return ctx->Eval.Map1Vertex4;
1466      case GL_MAP2_COLOR_4:
1467         if (ctx->API != API_OPENGL_COMPAT)
1468            goto invalid_enum_error;
1469         return ctx->Eval.Map2Color4;
1470      case GL_MAP2_INDEX:
1471         if (ctx->API != API_OPENGL_COMPAT)
1472            goto invalid_enum_error;
1473         return ctx->Eval.Map2Index;
1474      case GL_MAP2_NORMAL:
1475         if (ctx->API != API_OPENGL_COMPAT)
1476            goto invalid_enum_error;
1477         return ctx->Eval.Map2Normal;
1478      case GL_MAP2_TEXTURE_COORD_1:
1479         if (ctx->API != API_OPENGL_COMPAT)
1480            goto invalid_enum_error;
1481         return ctx->Eval.Map2TextureCoord1;
1482      case GL_MAP2_TEXTURE_COORD_2:
1483         if (ctx->API != API_OPENGL_COMPAT)
1484            goto invalid_enum_error;
1485         return ctx->Eval.Map2TextureCoord2;
1486      case GL_MAP2_TEXTURE_COORD_3:
1487         if (ctx->API != API_OPENGL_COMPAT)
1488            goto invalid_enum_error;
1489         return ctx->Eval.Map2TextureCoord3;
1490      case GL_MAP2_TEXTURE_COORD_4:
1491         if (ctx->API != API_OPENGL_COMPAT)
1492            goto invalid_enum_error;
1493         return ctx->Eval.Map2TextureCoord4;
1494      case GL_MAP2_VERTEX_3:
1495         if (ctx->API != API_OPENGL_COMPAT)
1496            goto invalid_enum_error;
1497         return ctx->Eval.Map2Vertex3;
1498      case GL_MAP2_VERTEX_4:
1499         if (ctx->API != API_OPENGL_COMPAT)
1500            goto invalid_enum_error;
1501         return ctx->Eval.Map2Vertex4;
1502      case GL_NORMALIZE:
1503         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1504            goto invalid_enum_error;
1505         return ctx->Transform.Normalize;
1506      case GL_POINT_SMOOTH:
1507         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1508            goto invalid_enum_error;
1509         return ctx->Point.SmoothFlag;
1510      case GL_POLYGON_SMOOTH:
1511         if (!_mesa_is_desktop_gl(ctx))
1512            goto invalid_enum_error;
1513         return ctx->Polygon.SmoothFlag;
1514      case GL_POLYGON_STIPPLE:
1515         if (ctx->API != API_OPENGL_COMPAT)
1516            goto invalid_enum_error;
1517         return ctx->Polygon.StippleFlag;
1518      case GL_POLYGON_OFFSET_POINT:
1519         if (!_mesa_is_desktop_gl(ctx))
1520            goto invalid_enum_error;
1521         return ctx->Polygon.OffsetPoint;
1522      case GL_POLYGON_OFFSET_LINE:
1523         if (!_mesa_is_desktop_gl(ctx))
1524            goto invalid_enum_error;
1525         return ctx->Polygon.OffsetLine;
1526      case GL_POLYGON_OFFSET_FILL:
1527         return ctx->Polygon.OffsetFill;
1528      case GL_RESCALE_NORMAL_EXT:
1529         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1530            goto invalid_enum_error;
1531         return ctx->Transform.RescaleNormals;
1532      case GL_SCISSOR_TEST:
1533         return ctx->Scissor.EnableFlags & 1;  /* return state for index 0 */
1534      case GL_STENCIL_TEST:
1535         return ctx->Stencil.Enabled;
1536      case GL_TEXTURE_1D:
1537         if (ctx->API != API_OPENGL_COMPAT)
1538            goto invalid_enum_error;
1539         return is_texture_enabled(ctx, TEXTURE_1D_BIT);
1540      case GL_TEXTURE_2D:
1541         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1542            goto invalid_enum_error;
1543         return is_texture_enabled(ctx, TEXTURE_2D_BIT);
1544      case GL_TEXTURE_3D:
1545         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1546            goto invalid_enum_error;
1547         return is_texture_enabled(ctx, TEXTURE_3D_BIT);
1548      case GL_TEXTURE_GEN_S:
1549      case GL_TEXTURE_GEN_T:
1550      case GL_TEXTURE_GEN_R:
1551      case GL_TEXTURE_GEN_Q:
1552         {
1553            const struct gl_fixedfunc_texture_unit *texUnit =
1554               get_texcoord_unit(ctx);
1555
1556            if (ctx->API != API_OPENGL_COMPAT)
1557               goto invalid_enum_error;
1558
1559            if (texUnit) {
1560               GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
1561               return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE;
1562            }
1563         }
1564         return GL_FALSE;
1565      case GL_TEXTURE_GEN_STR_OES:
1566         {
1567            const struct gl_fixedfunc_texture_unit *texUnit =
1568               get_texcoord_unit(ctx);
1569
1570            if (ctx->API != API_OPENGLES)
1571               goto invalid_enum_error;
1572
1573            if (texUnit) {
1574               return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS
1575                  ? GL_TRUE : GL_FALSE;
1576            }
1577         }
1578
1579      /* client-side state */
1580      case GL_VERTEX_ARRAY:
1581         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1582            goto invalid_enum_error;
1583         return !!(ctx->Array.VAO->Enabled & VERT_BIT_POS);
1584      case GL_NORMAL_ARRAY:
1585         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1586            goto invalid_enum_error;
1587         return !!(ctx->Array.VAO->Enabled & VERT_BIT_NORMAL);
1588      case GL_COLOR_ARRAY:
1589         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1590            goto invalid_enum_error;
1591         return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR0);
1592      case GL_INDEX_ARRAY:
1593         if (ctx->API != API_OPENGL_COMPAT)
1594            goto invalid_enum_error;
1595         return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR_INDEX);
1596      case GL_TEXTURE_COORD_ARRAY:
1597         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1598            goto invalid_enum_error;
1599         return !!(ctx->Array.VAO->Enabled &
1600                   VERT_BIT_TEX(ctx->Array.ActiveTexture));
1601      case GL_EDGE_FLAG_ARRAY:
1602         if (ctx->API != API_OPENGL_COMPAT)
1603            goto invalid_enum_error;
1604         return !!(ctx->Array.VAO->Enabled & VERT_BIT_EDGEFLAG);
1605      case GL_FOG_COORDINATE_ARRAY_EXT:
1606         if (ctx->API != API_OPENGL_COMPAT)
1607            goto invalid_enum_error;
1608         return !!(ctx->Array.VAO->Enabled & VERT_BIT_FOG);
1609      case GL_SECONDARY_COLOR_ARRAY_EXT:
1610         if (ctx->API != API_OPENGL_COMPAT)
1611            goto invalid_enum_error;
1612         return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR1);
1613      case GL_POINT_SIZE_ARRAY_OES:
1614         if (ctx->API != API_OPENGLES)
1615            goto invalid_enum_error;
1616         return !!(ctx->Array.VAO->Enabled & VERT_BIT_POINT_SIZE);
1617
1618      /* GL_ARB_texture_cube_map */
1619      case GL_TEXTURE_CUBE_MAP:
1620         CHECK_EXTENSION(ARB_texture_cube_map);
1621         return is_texture_enabled(ctx, TEXTURE_CUBE_BIT);
1622
1623      /* GL_EXT_secondary_color */
1624      case GL_COLOR_SUM_EXT:
1625         if (ctx->API != API_OPENGL_COMPAT)
1626            goto invalid_enum_error;
1627         return ctx->Fog.ColorSumEnabled;
1628
1629      /* GL_ARB_multisample */
1630      case GL_MULTISAMPLE_ARB:
1631         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1632            goto invalid_enum_error;
1633         return ctx->Multisample.Enabled;
1634      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
1635         return ctx->Multisample.SampleAlphaToCoverage;
1636      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
1637         if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1638            goto invalid_enum_error;
1639         return ctx->Multisample.SampleAlphaToOne;
1640      case GL_SAMPLE_COVERAGE_ARB:
1641         return ctx->Multisample.SampleCoverage;
1642      case GL_SAMPLE_COVERAGE_INVERT_ARB:
1643         if (!_mesa_is_desktop_gl(ctx))
1644            goto invalid_enum_error;
1645         return ctx->Multisample.SampleCoverageInvert;
1646
1647      /* GL_IBM_rasterpos_clip */
1648      case GL_RASTER_POSITION_UNCLIPPED_IBM:
1649         if (ctx->API != API_OPENGL_COMPAT)
1650            goto invalid_enum_error;
1651         return ctx->Transform.RasterPositionUnclipped;
1652
1653      /* GL_NV_point_sprite */
1654      case GL_POINT_SPRITE_NV:
1655         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1656            goto invalid_enum_error;
1657         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite)
1658         return ctx->Point.PointSprite;
1659
1660      case GL_VERTEX_PROGRAM_ARB:
1661         if (ctx->API != API_OPENGL_COMPAT)
1662            goto invalid_enum_error;
1663         CHECK_EXTENSION(ARB_vertex_program);
1664         return ctx->VertexProgram.Enabled;
1665      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1666         /* This was added with ARB_vertex_program, but it is also used with
1667          * GLSL vertex shaders on desktop.
1668          */
1669         if (!_mesa_is_desktop_gl(ctx))
1670            goto invalid_enum_error;
1671         CHECK_EXTENSION(ARB_vertex_program);
1672         return ctx->VertexProgram.PointSizeEnabled;
1673      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
1674         if (ctx->API != API_OPENGL_COMPAT)
1675            goto invalid_enum_error;
1676         CHECK_EXTENSION(ARB_vertex_program);
1677         return ctx->VertexProgram.TwoSideEnabled;
1678
1679      /* GL_NV_texture_rectangle */
1680      case GL_TEXTURE_RECTANGLE_NV:
1681         if (ctx->API != API_OPENGL_COMPAT)
1682            goto invalid_enum_error;
1683         CHECK_EXTENSION(NV_texture_rectangle);
1684         return is_texture_enabled(ctx, TEXTURE_RECT_BIT);
1685
1686      /* GL_EXT_stencil_two_side */
1687      case GL_STENCIL_TEST_TWO_SIDE_EXT:
1688         if (ctx->API != API_OPENGL_COMPAT)
1689            goto invalid_enum_error;
1690         CHECK_EXTENSION(EXT_stencil_two_side);
1691         return ctx->Stencil.TestTwoSide;
1692
1693      case GL_FRAGMENT_PROGRAM_ARB:
1694         if (ctx->API != API_OPENGL_COMPAT)
1695            goto invalid_enum_error;
1696         return ctx->FragmentProgram.Enabled;
1697
1698      /* GL_EXT_depth_bounds_test */
1699      case GL_DEPTH_BOUNDS_TEST_EXT:
1700         if (!_mesa_is_desktop_gl(ctx))
1701            goto invalid_enum_error;
1702         CHECK_EXTENSION(EXT_depth_bounds_test);
1703         return ctx->Depth.BoundsTest;
1704
1705      /* GL_ARB_depth_clamp */
1706      case GL_DEPTH_CLAMP:
1707         if (!_mesa_has_ARB_depth_clamp(ctx) &&
1708             !_mesa_has_EXT_depth_clamp(ctx))
1709            goto invalid_enum_error;
1710         return ctx->Transform.DepthClampNear ||
1711                ctx->Transform.DepthClampFar;
1712
1713      case GL_DEPTH_CLAMP_NEAR_AMD:
1714         if (!_mesa_is_desktop_gl(ctx))
1715            goto invalid_enum_error;
1716         CHECK_EXTENSION(AMD_depth_clamp_separate);
1717         return ctx->Transform.DepthClampNear;
1718
1719      case GL_DEPTH_CLAMP_FAR_AMD:
1720         if (!_mesa_is_desktop_gl(ctx))
1721            goto invalid_enum_error;
1722         CHECK_EXTENSION(AMD_depth_clamp_separate);
1723         return ctx->Transform.DepthClampFar;
1724
1725      case GL_FRAGMENT_SHADER_ATI:
1726         if (ctx->API != API_OPENGL_COMPAT)
1727            goto invalid_enum_error;
1728         CHECK_EXTENSION(ATI_fragment_shader);
1729         return ctx->ATIFragmentShader.Enabled;
1730
1731      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1732         if (!_mesa_is_desktop_gl(ctx))
1733            goto invalid_enum_error;
1734         CHECK_EXTENSION(ARB_seamless_cube_map);
1735         return ctx->Texture.CubeMapSeamless;
1736
1737      case GL_RASTERIZER_DISCARD:
1738         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1739            goto invalid_enum_error;
1740         CHECK_EXTENSION(EXT_transform_feedback);
1741         return ctx->RasterDiscard;
1742
1743      /* GL_NV_primitive_restart */
1744      case GL_PRIMITIVE_RESTART_NV:
1745         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.NV_primitive_restart) {
1746            goto invalid_enum_error;
1747         }
1748         return ctx->Array.PrimitiveRestart;
1749
1750      /* GL 3.1 primitive restart */
1751      case GL_PRIMITIVE_RESTART:
1752         if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 31) {
1753            goto invalid_enum_error;
1754         }
1755         return ctx->Array.PrimitiveRestart;
1756
1757      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1758         if (!_mesa_is_gles3(ctx) && !ctx->Extensions.ARB_ES3_compatibility) {
1759            goto invalid_enum_error;
1760         }
1761         return ctx->Array.PrimitiveRestartFixedIndex;
1762
1763      /* GL3.0 - GL_framebuffer_sRGB */
1764      case GL_FRAMEBUFFER_SRGB_EXT:
1765         CHECK_EXTENSION(EXT_framebuffer_sRGB);
1766         return ctx->Color.sRGBEnabled;
1767
1768      /* GL_OES_EGL_image_external */
1769      case GL_TEXTURE_EXTERNAL_OES:
1770         if (!_mesa_is_gles(ctx))
1771            goto invalid_enum_error;
1772         CHECK_EXTENSION(OES_EGL_image_external);
1773         return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT);
1774
1775      /* ARB_texture_multisample */
1776      case GL_SAMPLE_MASK:
1777         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles31(ctx))
1778            goto invalid_enum_error;
1779         CHECK_EXTENSION(ARB_texture_multisample);
1780         return ctx->Multisample.SampleMask;
1781
1782      /* ARB_sample_shading */
1783      case GL_SAMPLE_SHADING:
1784         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1785            goto invalid_enum_error;
1786         CHECK_EXTENSION(ARB_sample_shading);
1787         return ctx->Multisample.SampleShading;
1788
1789      case GL_BLEND_ADVANCED_COHERENT_KHR:
1790         CHECK_EXTENSION(KHR_blend_equation_advanced_coherent);
1791         return ctx->Color.BlendCoherent;
1792
1793      case GL_CONSERVATIVE_RASTERIZATION_INTEL:
1794         CHECK_EXTENSION(INTEL_conservative_rasterization);
1795         return ctx->IntelConservativeRasterization;
1796
1797      case GL_CONSERVATIVE_RASTERIZATION_NV:
1798         CHECK_EXTENSION(NV_conservative_raster);
1799         return ctx->ConservativeRasterization;
1800
1801      case GL_TILE_RASTER_ORDER_FIXED_MESA:
1802         CHECK_EXTENSION(MESA_tile_raster_order);
1803         return ctx->TileRasterOrderFixed;
1804
1805      case GL_TILE_RASTER_ORDER_INCREASING_X_MESA:
1806         CHECK_EXTENSION(MESA_tile_raster_order);
1807         return ctx->TileRasterOrderIncreasingX;
1808
1809      case GL_TILE_RASTER_ORDER_INCREASING_Y_MESA:
1810         CHECK_EXTENSION(MESA_tile_raster_order);
1811         return ctx->TileRasterOrderIncreasingY;
1812
1813      default:
1814         goto invalid_enum_error;
1815   }
1816
1817   return GL_FALSE;
1818
1819invalid_enum_error:
1820   _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(%s)",
1821               _mesa_enum_to_string(cap));
1822   return GL_FALSE;
1823}
1824