Sync with trunk r63637.
[reactos.git] / dll / opengl / 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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29
30 #include <precomp.h>
31
32 #define CHECK_EXTENSION(EXTNAME, CAP) \
33 if (!ctx->Extensions.EXTNAME) { \
34 goto invalid_enum_error; \
35 }
36
37
38 /**
39 * Helper to enable/disable client-side state.
40 */
41 static void
42 client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
43 {
44 GLbitfield64 flag;
45 GLboolean *var;
46
47 switch (cap) {
48 case GL_VERTEX_ARRAY:
49 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled;
50 flag = VERT_BIT_POS;
51 break;
52 case GL_NORMAL_ARRAY:
53 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Enabled;
54 flag = VERT_BIT_NORMAL;
55 break;
56 case GL_COLOR_ARRAY:
57 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR].Enabled;
58 flag = VERT_BIT_COLOR;
59 break;
60 case GL_INDEX_ARRAY:
61 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled;
62 flag = VERT_BIT_COLOR_INDEX;
63 break;
64 case GL_TEXTURE_COORD_ARRAY:
65 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_TEX].Enabled;
66 flag = VERT_BIT_TEX;
67 break;
68 case GL_EDGE_FLAG_ARRAY:
69 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled;
70 flag = VERT_BIT_EDGEFLAG;
71 break;
72 case GL_FOG_COORDINATE_ARRAY_EXT:
73 var = &ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Enabled;
74 flag = VERT_BIT_FOG;
75 break;
76
77 default:
78 goto invalid_enum_error;
79 }
80
81 if (*var == state)
82 return;
83
84 FLUSH_VERTICES(ctx, _NEW_ARRAY);
85 ctx->Array.NewState |= flag;
86
87 _ae_invalidate_state(ctx, _NEW_ARRAY);
88
89 *var = state;
90
91 if (state)
92 ctx->Array._Enabled |= flag;
93 else
94 ctx->Array._Enabled &= ~flag;
95
96 if (ctx->Driver.Enable) {
97 ctx->Driver.Enable( ctx, cap, state );
98 }
99
100 return;
101
102 invalid_enum_error:
103 _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(0x%x)",
104 state ? "Enable" : "Disable", cap);
105 }
106
107
108 /**
109 * Enable GL capability.
110 * \param cap state to enable/disable.
111 *
112 * Get's the current context, assures that we're outside glBegin()/glEnd() and
113 * calls client_state().
114 */
115 void GLAPIENTRY
116 _mesa_EnableClientState( GLenum cap )
117 {
118 GET_CURRENT_CONTEXT(ctx);
119 ASSERT_OUTSIDE_BEGIN_END(ctx);
120 client_state( ctx, cap, GL_TRUE );
121 }
122
123
124 /**
125 * Disable GL capability.
126 * \param cap state to enable/disable.
127 *
128 * Get's the current context, assures that we're outside glBegin()/glEnd() and
129 * calls client_state().
130 */
131 void GLAPIENTRY
132 _mesa_DisableClientState( GLenum cap )
133 {
134 GET_CURRENT_CONTEXT(ctx);
135 ASSERT_OUTSIDE_BEGIN_END(ctx);
136 client_state( ctx, cap, GL_FALSE );
137 }
138
139
140 #undef CHECK_EXTENSION
141 #define CHECK_EXTENSION(EXTNAME, CAP) \
142 if (!ctx->Extensions.EXTNAME) { \
143 goto invalid_enum_error; \
144 }
145
146 #define CHECK_EXTENSION2(EXT1, EXT2, CAP) \
147 if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
148 goto invalid_enum_error; \
149 }
150
151
152
153 /**
154 * Return pointer to current texture unit for setting/getting coordinate
155 * state.
156 * Note that we'll set GL_INVALID_OPERATION and return NULL if the active
157 * texture unit is higher than the number of supported coordinate units.
158 */
159 static inline struct gl_texture_unit *
160 get_texcoord_unit(struct gl_context *ctx)
161 {
162 return &ctx->Texture.Unit;
163 }
164
165
166 /**
167 * Helper function to enable or disable a texture target.
168 * \param bit one of the TEXTURE_x_BIT values
169 * \return GL_TRUE if state is changing or GL_FALSE if no change
170 */
171 static GLboolean
172 enable_texture(struct gl_context *ctx, GLboolean state, GLbitfield texBit)
173 {
174 struct gl_texture_unit *texUnit = &ctx->Texture.Unit;
175 const GLbitfield newenabled = state
176 ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
177
178 if (texUnit->Enabled == newenabled)
179 return GL_FALSE;
180
181 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
182 texUnit->Enabled = newenabled;
183 return GL_TRUE;
184 }
185
186
187 /**
188 * Helper function to enable or disable state.
189 *
190 * \param ctx GL context.
191 * \param cap the state to enable/disable
192 * \param state whether to enable or disable the specified capability.
193 *
194 * Updates the current context and flushes the vertices as needed. For
195 * capabilities associated with extensions it verifies that those extensions
196 * are effectivly present before updating. Notifies the driver via
197 * dd_function_table::Enable.
198 */
199 void
200 _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
201 {
202 if (MESA_VERBOSE & VERBOSE_API)
203 _mesa_debug(ctx, "%s %s (newstate is %x)\n",
204 state ? "glEnable" : "glDisable",
205 _mesa_lookup_enum_by_nr(cap),
206 ctx->NewState);
207
208 switch (cap) {
209 case GL_ALPHA_TEST:
210 if (ctx->Color.AlphaEnabled == state)
211 return;
212 FLUSH_VERTICES(ctx, _NEW_COLOR);
213 ctx->Color.AlphaEnabled = state;
214 break;
215 case GL_AUTO_NORMAL:
216 if (ctx->Eval.AutoNormal == state)
217 return;
218 FLUSH_VERTICES(ctx, _NEW_EVAL);
219 ctx->Eval.AutoNormal = state;
220 break;
221 case GL_BLEND:
222 {
223 if (state != ctx->Color.BlendEnabled) {
224 FLUSH_VERTICES(ctx, _NEW_COLOR);
225 ctx->Color.BlendEnabled = state;
226 }
227 }
228 break;
229 #if FEATURE_userclip
230 case GL_CLIP_DISTANCE0:
231 case GL_CLIP_DISTANCE1:
232 case GL_CLIP_DISTANCE2:
233 case GL_CLIP_DISTANCE3:
234 case GL_CLIP_DISTANCE4:
235 case GL_CLIP_DISTANCE5:
236 case GL_CLIP_DISTANCE6:
237 case GL_CLIP_DISTANCE7:
238 {
239 const GLuint p = cap - GL_CLIP_DISTANCE0;
240
241 if (p >= ctx->Const.MaxClipPlanes)
242 goto invalid_enum_error;
243
244 if ((ctx->Transform.ClipPlanesEnabled & (1 << p))
245 == ((GLuint) state << p))
246 return;
247
248 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
249
250 if (state) {
251 ctx->Transform.ClipPlanesEnabled |= (1 << p);
252 _mesa_update_clip_plane(ctx, p);
253 }
254 else {
255 ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
256 }
257 }
258 break;
259 #endif
260 case GL_COLOR_MATERIAL:
261 if (ctx->Light.ColorMaterialEnabled == state)
262 return;
263 FLUSH_VERTICES(ctx, _NEW_LIGHT);
264 FLUSH_CURRENT(ctx, 0);
265 ctx->Light.ColorMaterialEnabled = state;
266 if (state) {
267 _mesa_update_color_material( ctx,
268 ctx->Current.Attrib[VERT_ATTRIB_COLOR] );
269 }
270 break;
271 case GL_CULL_FACE:
272 if (ctx->Polygon.CullFlag == state)
273 return;
274 FLUSH_VERTICES(ctx, _NEW_POLYGON);
275 ctx->Polygon.CullFlag = state;
276 break;
277 case GL_DEPTH_TEST:
278 if (ctx->Depth.Test == state)
279 return;
280 FLUSH_VERTICES(ctx, _NEW_DEPTH);
281 ctx->Depth.Test = state;
282 break;
283 case GL_DITHER:
284 if (ctx->Color.DitherFlag == state)
285 return;
286 FLUSH_VERTICES(ctx, _NEW_COLOR);
287 ctx->Color.DitherFlag = state;
288 break;
289 case GL_FOG:
290 if (ctx->Fog.Enabled == state)
291 return;
292 FLUSH_VERTICES(ctx, _NEW_FOG);
293 ctx->Fog.Enabled = state;
294 break;
295 case GL_LIGHT0:
296 case GL_LIGHT1:
297 case GL_LIGHT2:
298 case GL_LIGHT3:
299 case GL_LIGHT4:
300 case GL_LIGHT5:
301 case GL_LIGHT6:
302 case GL_LIGHT7:
303 if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
304 return;
305 FLUSH_VERTICES(ctx, _NEW_LIGHT);
306 ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
307 if (state) {
308 insert_at_tail(&ctx->Light.EnabledList,
309 &ctx->Light.Light[cap-GL_LIGHT0]);
310 }
311 else {
312 remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
313 }
314 break;
315 case GL_LIGHTING:
316 if (ctx->Light.Enabled == state)
317 return;
318 FLUSH_VERTICES(ctx, _NEW_LIGHT);
319 ctx->Light.Enabled = state;
320 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
321 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
322 else
323 ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
324 break;
325 case GL_LINE_SMOOTH:
326 if (ctx->Line.SmoothFlag == state)
327 return;
328 FLUSH_VERTICES(ctx, _NEW_LINE);
329 ctx->Line.SmoothFlag = state;
330 ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
331 break;
332 case GL_LINE_STIPPLE:
333 if (ctx->Line.StippleFlag == state)
334 return;
335 FLUSH_VERTICES(ctx, _NEW_LINE);
336 ctx->Line.StippleFlag = state;
337 ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
338 break;
339 case GL_INDEX_LOGIC_OP:
340 if (ctx->Color.IndexLogicOpEnabled == state)
341 return;
342 FLUSH_VERTICES(ctx, _NEW_COLOR);
343 ctx->Color.IndexLogicOpEnabled = state;
344 break;
345 case GL_COLOR_LOGIC_OP:
346 if (ctx->Color.ColorLogicOpEnabled == state)
347 return;
348 FLUSH_VERTICES(ctx, _NEW_COLOR);
349 ctx->Color.ColorLogicOpEnabled = state;
350 break;
351 case GL_MAP1_COLOR_4:
352 if (ctx->Eval.Map1Color4 == state)
353 return;
354 FLUSH_VERTICES(ctx, _NEW_EVAL);
355 ctx->Eval.Map1Color4 = state;
356 break;
357 case GL_MAP1_INDEX:
358 if (ctx->Eval.Map1Index == state)
359 return;
360 FLUSH_VERTICES(ctx, _NEW_EVAL);
361 ctx->Eval.Map1Index = state;
362 break;
363 case GL_MAP1_NORMAL:
364 if (ctx->Eval.Map1Normal == state)
365 return;
366 FLUSH_VERTICES(ctx, _NEW_EVAL);
367 ctx->Eval.Map1Normal = state;
368 break;
369 case GL_MAP1_TEXTURE_COORD_1:
370 if (ctx->Eval.Map1TextureCoord1 == state)
371 return;
372 FLUSH_VERTICES(ctx, _NEW_EVAL);
373 ctx->Eval.Map1TextureCoord1 = state;
374 break;
375 case GL_MAP1_TEXTURE_COORD_2:
376 if (ctx->Eval.Map1TextureCoord2 == state)
377 return;
378 FLUSH_VERTICES(ctx, _NEW_EVAL);
379 ctx->Eval.Map1TextureCoord2 = state;
380 break;
381 case GL_MAP1_TEXTURE_COORD_3:
382 if (ctx->Eval.Map1TextureCoord3 == state)
383 return;
384 FLUSH_VERTICES(ctx, _NEW_EVAL);
385 ctx->Eval.Map1TextureCoord3 = state;
386 break;
387 case GL_MAP1_TEXTURE_COORD_4:
388 if (ctx->Eval.Map1TextureCoord4 == state)
389 return;
390 FLUSH_VERTICES(ctx, _NEW_EVAL);
391 ctx->Eval.Map1TextureCoord4 = state;
392 break;
393 case GL_MAP1_VERTEX_3:
394 if (ctx->Eval.Map1Vertex3 == state)
395 return;
396 FLUSH_VERTICES(ctx, _NEW_EVAL);
397 ctx->Eval.Map1Vertex3 = state;
398 break;
399 case GL_MAP1_VERTEX_4:
400 if (ctx->Eval.Map1Vertex4 == state)
401 return;
402 FLUSH_VERTICES(ctx, _NEW_EVAL);
403 ctx->Eval.Map1Vertex4 = state;
404 break;
405 case GL_MAP2_COLOR_4:
406 if (ctx->Eval.Map2Color4 == state)
407 return;
408 FLUSH_VERTICES(ctx, _NEW_EVAL);
409 ctx->Eval.Map2Color4 = state;
410 break;
411 case GL_MAP2_INDEX:
412 if (ctx->Eval.Map2Index == state)
413 return;
414 FLUSH_VERTICES(ctx, _NEW_EVAL);
415 ctx->Eval.Map2Index = state;
416 break;
417 case GL_MAP2_NORMAL:
418 if (ctx->Eval.Map2Normal == state)
419 return;
420 FLUSH_VERTICES(ctx, _NEW_EVAL);
421 ctx->Eval.Map2Normal = state;
422 break;
423 case GL_MAP2_TEXTURE_COORD_1:
424 if (ctx->Eval.Map2TextureCoord1 == state)
425 return;
426 FLUSH_VERTICES(ctx, _NEW_EVAL);
427 ctx->Eval.Map2TextureCoord1 = state;
428 break;
429 case GL_MAP2_TEXTURE_COORD_2:
430 if (ctx->Eval.Map2TextureCoord2 == state)
431 return;
432 FLUSH_VERTICES(ctx, _NEW_EVAL);
433 ctx->Eval.Map2TextureCoord2 = state;
434 break;
435 case GL_MAP2_TEXTURE_COORD_3:
436 if (ctx->Eval.Map2TextureCoord3 == state)
437 return;
438 FLUSH_VERTICES(ctx, _NEW_EVAL);
439 ctx->Eval.Map2TextureCoord3 = state;
440 break;
441 case GL_MAP2_TEXTURE_COORD_4:
442 if (ctx->Eval.Map2TextureCoord4 == state)
443 return;
444 FLUSH_VERTICES(ctx, _NEW_EVAL);
445 ctx->Eval.Map2TextureCoord4 = state;
446 break;
447 case GL_MAP2_VERTEX_3:
448 if (ctx->Eval.Map2Vertex3 == state)
449 return;
450 FLUSH_VERTICES(ctx, _NEW_EVAL);
451 ctx->Eval.Map2Vertex3 = state;
452 break;
453 case GL_MAP2_VERTEX_4:
454 if (ctx->Eval.Map2Vertex4 == state)
455 return;
456 FLUSH_VERTICES(ctx, _NEW_EVAL);
457 ctx->Eval.Map2Vertex4 = state;
458 break;
459 case GL_NORMALIZE:
460 if (ctx->Transform.Normalize == state)
461 return;
462 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
463 ctx->Transform.Normalize = state;
464 break;
465 case GL_POINT_SMOOTH:
466 if (ctx->Point.SmoothFlag == state)
467 return;
468 FLUSH_VERTICES(ctx, _NEW_POINT);
469 ctx->Point.SmoothFlag = state;
470 ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
471 break;
472 case GL_POLYGON_SMOOTH:
473 if (ctx->Polygon.SmoothFlag == state)
474 return;
475 FLUSH_VERTICES(ctx, _NEW_POLYGON);
476 ctx->Polygon.SmoothFlag = state;
477 ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
478 break;
479 case GL_POLYGON_STIPPLE:
480 if (ctx->Polygon.StippleFlag == state)
481 return;
482 FLUSH_VERTICES(ctx, _NEW_POLYGON);
483 ctx->Polygon.StippleFlag = state;
484 ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
485 break;
486 case GL_POLYGON_OFFSET_POINT:
487 if (ctx->Polygon.OffsetPoint == state)
488 return;
489 FLUSH_VERTICES(ctx, _NEW_POLYGON);
490 ctx->Polygon.OffsetPoint = state;
491 break;
492 case GL_POLYGON_OFFSET_LINE:
493 if (ctx->Polygon.OffsetLine == state)
494 return;
495 FLUSH_VERTICES(ctx, _NEW_POLYGON);
496 ctx->Polygon.OffsetLine = state;
497 break;
498 case GL_POLYGON_OFFSET_FILL:
499 if (ctx->Polygon.OffsetFill == state)
500 return;
501 FLUSH_VERTICES(ctx, _NEW_POLYGON);
502 ctx->Polygon.OffsetFill = state;
503 break;
504 case GL_RESCALE_NORMAL_EXT:
505 if (ctx->Transform.RescaleNormals == state)
506 return;
507 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
508 ctx->Transform.RescaleNormals = state;
509 break;
510 case GL_SCISSOR_TEST:
511 if (ctx->Scissor.Enabled == state)
512 return;
513 FLUSH_VERTICES(ctx, _NEW_SCISSOR);
514 ctx->Scissor.Enabled = state;
515 break;
516 case GL_STENCIL_TEST:
517 if (ctx->Stencil.Enabled == state)
518 return;
519 FLUSH_VERTICES(ctx, _NEW_STENCIL);
520 ctx->Stencil.Enabled = state;
521 break;
522 case GL_TEXTURE_1D:
523 if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
524 return;
525 }
526 break;
527 case GL_TEXTURE_2D:
528 if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) {
529 return;
530 }
531 break;
532 case GL_TEXTURE_GEN_S:
533 case GL_TEXTURE_GEN_T:
534 case GL_TEXTURE_GEN_R:
535 case GL_TEXTURE_GEN_Q:
536 {
537 struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
538 if (texUnit) {
539 GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
540 GLbitfield newenabled = texUnit->TexGenEnabled & ~coordBit;
541 if (state)
542 newenabled |= coordBit;
543 if (texUnit->TexGenEnabled == newenabled)
544 return;
545 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
546 texUnit->TexGenEnabled = newenabled;
547 }
548 }
549 break;
550
551 #if FEATURE_ES1
552 case GL_TEXTURE_GEN_STR_OES:
553 /* disable S, T, and R at the same time */
554 {
555 struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
556 if (texUnit) {
557 GLuint newenabled =
558 texUnit->TexGenEnabled & ~STR_BITS;
559 if (state)
560 newenabled |= STR_BITS;
561 if (texUnit->TexGenEnabled == newenabled)
562 return;
563 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
564 texUnit->TexGenEnabled = newenabled;
565 }
566 }
567 break;
568 #endif
569
570 /* client-side state */
571 case GL_VERTEX_ARRAY:
572 case GL_NORMAL_ARRAY:
573 case GL_COLOR_ARRAY:
574 case GL_INDEX_ARRAY:
575 case GL_TEXTURE_COORD_ARRAY:
576 case GL_EDGE_FLAG_ARRAY:
577 case GL_FOG_COORDINATE_ARRAY_EXT:
578 case GL_SECONDARY_COLOR_ARRAY_EXT:
579 case GL_POINT_SIZE_ARRAY_OES:
580 client_state( ctx, cap, state );
581 return;
582
583 /* GL_ARB_texture_cube_map */
584 case GL_TEXTURE_CUBE_MAP_ARB:
585 CHECK_EXTENSION(ARB_texture_cube_map, cap);
586 if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) {
587 return;
588 }
589 break;
590
591 /* GL_ARB_multisample */
592 case GL_MULTISAMPLE_ARB:
593 if (ctx->Multisample.Enabled == state)
594 return;
595 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
596 ctx->Multisample.Enabled = state;
597 break;
598 case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
599 if (ctx->Multisample.SampleAlphaToCoverage == state)
600 return;
601 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
602 ctx->Multisample.SampleAlphaToCoverage = state;
603 break;
604 case GL_SAMPLE_ALPHA_TO_ONE_ARB:
605 if (ctx->Multisample.SampleAlphaToOne == state)
606 return;
607 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
608 ctx->Multisample.SampleAlphaToOne = state;
609 break;
610 case GL_SAMPLE_COVERAGE_ARB:
611 if (ctx->Multisample.SampleCoverage == state)
612 return;
613 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
614 ctx->Multisample.SampleCoverage = state;
615 break;
616 case GL_SAMPLE_COVERAGE_INVERT_ARB:
617 if (ctx->Multisample.SampleCoverageInvert == state)
618 return;
619 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
620 ctx->Multisample.SampleCoverageInvert = state;
621 break;
622
623 /* GL_IBM_rasterpos_clip */
624 case GL_RASTER_POSITION_UNCLIPPED_IBM:
625 CHECK_EXTENSION(IBM_rasterpos_clip, cap);
626 if (ctx->Transform.RasterPositionUnclipped == state)
627 return;
628 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
629 ctx->Transform.RasterPositionUnclipped = state;
630 break;
631
632 /* GL_NV_point_sprite */
633 case GL_POINT_SPRITE_NV:
634 CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
635 if (ctx->Point.PointSprite == state)
636 return;
637 FLUSH_VERTICES(ctx, _NEW_POINT);
638 ctx->Point.PointSprite = state;
639 break;
640
641 /* GL_EXT_depth_bounds_test */
642 case GL_DEPTH_BOUNDS_TEST_EXT:
643 CHECK_EXTENSION(EXT_depth_bounds_test, cap);
644 if (ctx->Depth.BoundsTest == state)
645 return;
646 FLUSH_VERTICES(ctx, _NEW_DEPTH);
647 ctx->Depth.BoundsTest = state;
648 break;
649
650 default:
651 goto invalid_enum_error;
652 }
653
654 if (ctx->Driver.Enable) {
655 ctx->Driver.Enable( ctx, cap, state );
656 }
657
658 return;
659
660 invalid_enum_error:
661 _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(0x%x)",
662 state ? "Enable" : "Disable", cap);
663 }
664
665
666 /**
667 * Enable GL capability. Called by glEnable()
668 * \param cap state to enable.
669 */
670 void GLAPIENTRY
671 _mesa_Enable( GLenum cap )
672 {
673 GET_CURRENT_CONTEXT(ctx);
674 ASSERT_OUTSIDE_BEGIN_END(ctx);
675
676 _mesa_set_enable( ctx, cap, GL_TRUE );
677 }
678
679
680 /**
681 * Disable GL capability. Called by glDisable()
682 * \param cap state to disable.
683 */
684 void GLAPIENTRY
685 _mesa_Disable( GLenum cap )
686 {
687 GET_CURRENT_CONTEXT(ctx);
688 ASSERT_OUTSIDE_BEGIN_END(ctx);
689
690 _mesa_set_enable( ctx, cap, GL_FALSE );
691 }
692
693
694 #undef CHECK_EXTENSION
695 #define CHECK_EXTENSION(EXTNAME) \
696 if (!ctx->Extensions.EXTNAME) { \
697 goto invalid_enum_error; \
698 }
699
700 #undef CHECK_EXTENSION2
701 #define CHECK_EXTENSION2(EXT1, EXT2) \
702 if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \
703 goto invalid_enum_error; \
704 }
705
706
707 /**
708 * Helper function to determine whether a texture target is enabled.
709 */
710 static GLboolean
711 is_texture_enabled(struct gl_context *ctx, GLbitfield bit)
712 {
713 const struct gl_texture_unit *const texUnit =
714 &ctx->Texture.Unit;
715 return (texUnit->Enabled & bit) ? GL_TRUE : GL_FALSE;
716 }
717
718
719 /**
720 * Return simple enable/disable state.
721 *
722 * \param cap state variable to query.
723 *
724 * Returns the state of the specified capability from the current GL context.
725 * For the capabilities associated with extensions verifies that those
726 * extensions are effectively present before reporting.
727 */
728 GLboolean GLAPIENTRY
729 _mesa_IsEnabled( GLenum cap )
730 {
731 GET_CURRENT_CONTEXT(ctx);
732 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
733
734 switch (cap) {
735 case GL_ALPHA_TEST:
736 return ctx->Color.AlphaEnabled;
737 case GL_AUTO_NORMAL:
738 return ctx->Eval.AutoNormal;
739 case GL_BLEND:
740 return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */
741 case GL_CLIP_DISTANCE0:
742 case GL_CLIP_DISTANCE1:
743 case GL_CLIP_DISTANCE2:
744 case GL_CLIP_DISTANCE3:
745 case GL_CLIP_DISTANCE4:
746 case GL_CLIP_DISTANCE5:
747 case GL_CLIP_DISTANCE6:
748 case GL_CLIP_DISTANCE7: {
749 const GLuint p = cap - GL_CLIP_DISTANCE0;
750
751 if (p >= ctx->Const.MaxClipPlanes)
752 goto invalid_enum_error;
753
754 return (ctx->Transform.ClipPlanesEnabled >> p) & 1;
755 }
756 case GL_COLOR_MATERIAL:
757 return ctx->Light.ColorMaterialEnabled;
758 case GL_CULL_FACE:
759 return ctx->Polygon.CullFlag;
760 case GL_DEPTH_TEST:
761 return ctx->Depth.Test;
762 case GL_DITHER:
763 return ctx->Color.DitherFlag;
764 case GL_FOG:
765 return ctx->Fog.Enabled;
766 case GL_LIGHTING:
767 return ctx->Light.Enabled;
768 case GL_LIGHT0:
769 case GL_LIGHT1:
770 case GL_LIGHT2:
771 case GL_LIGHT3:
772 case GL_LIGHT4:
773 case GL_LIGHT5:
774 case GL_LIGHT6:
775 case GL_LIGHT7:
776 return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
777 case GL_LINE_SMOOTH:
778 return ctx->Line.SmoothFlag;
779 case GL_LINE_STIPPLE:
780 return ctx->Line.StippleFlag;
781 case GL_INDEX_LOGIC_OP:
782 return ctx->Color.IndexLogicOpEnabled;
783 case GL_COLOR_LOGIC_OP:
784 return ctx->Color.ColorLogicOpEnabled;
785 case GL_MAP1_COLOR_4:
786 return ctx->Eval.Map1Color4;
787 case GL_MAP1_INDEX:
788 return ctx->Eval.Map1Index;
789 case GL_MAP1_NORMAL:
790 return ctx->Eval.Map1Normal;
791 case GL_MAP1_TEXTURE_COORD_1:
792 return ctx->Eval.Map1TextureCoord1;
793 case GL_MAP1_TEXTURE_COORD_2:
794 return ctx->Eval.Map1TextureCoord2;
795 case GL_MAP1_TEXTURE_COORD_3:
796 return ctx->Eval.Map1TextureCoord3;
797 case GL_MAP1_TEXTURE_COORD_4:
798 return ctx->Eval.Map1TextureCoord4;
799 case GL_MAP1_VERTEX_3:
800 return ctx->Eval.Map1Vertex3;
801 case GL_MAP1_VERTEX_4:
802 return ctx->Eval.Map1Vertex4;
803 case GL_MAP2_COLOR_4:
804 return ctx->Eval.Map2Color4;
805 case GL_MAP2_INDEX:
806 return ctx->Eval.Map2Index;
807 case GL_MAP2_NORMAL:
808 return ctx->Eval.Map2Normal;
809 case GL_MAP2_TEXTURE_COORD_1:
810 return ctx->Eval.Map2TextureCoord1;
811 case GL_MAP2_TEXTURE_COORD_2:
812 return ctx->Eval.Map2TextureCoord2;
813 case GL_MAP2_TEXTURE_COORD_3:
814 return ctx->Eval.Map2TextureCoord3;
815 case GL_MAP2_TEXTURE_COORD_4:
816 return ctx->Eval.Map2TextureCoord4;
817 case GL_MAP2_VERTEX_3:
818 return ctx->Eval.Map2Vertex3;
819 case GL_MAP2_VERTEX_4:
820 return ctx->Eval.Map2Vertex4;
821 case GL_NORMALIZE:
822 return ctx->Transform.Normalize;
823 case GL_POINT_SMOOTH:
824 return ctx->Point.SmoothFlag;
825 case GL_POLYGON_SMOOTH:
826 return ctx->Polygon.SmoothFlag;
827 case GL_POLYGON_STIPPLE:
828 return ctx->Polygon.StippleFlag;
829 case GL_POLYGON_OFFSET_POINT:
830 return ctx->Polygon.OffsetPoint;
831 case GL_POLYGON_OFFSET_LINE:
832 return ctx->Polygon.OffsetLine;
833 case GL_POLYGON_OFFSET_FILL:
834 return ctx->Polygon.OffsetFill;
835 case GL_RESCALE_NORMAL_EXT:
836 return ctx->Transform.RescaleNormals;
837 case GL_SCISSOR_TEST:
838 return ctx->Scissor.Enabled;
839 case GL_STENCIL_TEST:
840 return ctx->Stencil.Enabled;
841 case GL_TEXTURE_1D:
842 return is_texture_enabled(ctx, TEXTURE_1D_BIT);
843 case GL_TEXTURE_2D:
844 return is_texture_enabled(ctx, TEXTURE_2D_BIT);
845 case GL_TEXTURE_GEN_S:
846 case GL_TEXTURE_GEN_T:
847 case GL_TEXTURE_GEN_R:
848 case GL_TEXTURE_GEN_Q:
849 {
850 const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
851 if (texUnit) {
852 GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
853 return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE;
854 }
855 }
856 return GL_FALSE;
857 #if FEATURE_ES1
858 case GL_TEXTURE_GEN_STR_OES:
859 {
860 const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
861 if (texUnit) {
862 return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS
863 ? GL_TRUE : GL_FALSE;
864 }
865 }
866 #endif
867
868 /* client-side state */
869 case GL_VERTEX_ARRAY:
870 return (ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled != 0);
871 case GL_NORMAL_ARRAY:
872 return (ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Enabled != 0);
873 case GL_COLOR_ARRAY:
874 return (ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR].Enabled != 0);
875 case GL_INDEX_ARRAY:
876 return (ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled != 0);
877 case GL_TEXTURE_COORD_ARRAY:
878 return (ctx->Array.VertexAttrib[VERT_ATTRIB_TEX]
879 .Enabled != 0);
880 case GL_EDGE_FLAG_ARRAY:
881 return (ctx->Array.VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled != 0);
882 case GL_FOG_COORDINATE_ARRAY_EXT:
883 CHECK_EXTENSION(EXT_fog_coord);
884 return (ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Enabled != 0);
885 #if FEATURE_point_size_array
886 case GL_POINT_SIZE_ARRAY_OES:
887 return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Enabled != 0);
888 #endif
889
890 /* GL_ARB_texture_cube_map */
891 case GL_TEXTURE_CUBE_MAP_ARB:
892 CHECK_EXTENSION(ARB_texture_cube_map);
893 return is_texture_enabled(ctx, TEXTURE_CUBE_BIT);
894
895 /* GL_ARB_multisample */
896 case GL_MULTISAMPLE_ARB:
897 return ctx->Multisample.Enabled;
898 case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
899 return ctx->Multisample.SampleAlphaToCoverage;
900 case GL_SAMPLE_ALPHA_TO_ONE_ARB:
901 return ctx->Multisample.SampleAlphaToOne;
902 case GL_SAMPLE_COVERAGE_ARB:
903 return ctx->Multisample.SampleCoverage;
904 case GL_SAMPLE_COVERAGE_INVERT_ARB:
905 return ctx->Multisample.SampleCoverageInvert;
906
907 /* GL_IBM_rasterpos_clip */
908 case GL_RASTER_POSITION_UNCLIPPED_IBM:
909 CHECK_EXTENSION(IBM_rasterpos_clip);
910 return ctx->Transform.RasterPositionUnclipped;
911
912 /* GL_NV_point_sprite */
913 case GL_POINT_SPRITE_NV:
914 CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite)
915 return ctx->Point.PointSprite;
916
917 /* GL_EXT_depth_bounds_test */
918 case GL_DEPTH_BOUNDS_TEST_EXT:
919 CHECK_EXTENSION(EXT_depth_bounds_test);
920 return ctx->Depth.BoundsTest;
921
922 default:
923 goto invalid_enum_error;
924 }
925
926 return GL_FALSE;
927
928 invalid_enum_error:
929 _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap);
930 return GL_FALSE;
931 }