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