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