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