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