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