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