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