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