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 52 update_derived_primitive_restart_state(struct gl_context *ctx) 53 { 54 /* Update derived primitive restart state. 55 */ 56 ctx->Array._PrimitiveRestart = ctx->Array.PrimitiveRestart 57 || ctx->Array.PrimitiveRestartFixedIndex; 58 } 59 60 /** 61 * Helper to enable/disable client-side state. 62 */ 63 static void 64 client_state(struct gl_context *ctx, GLenum cap, GLboolean state) 65 { 66 struct gl_vertex_array_object *vao = ctx->Array.VAO; 67 GLbitfield64 flag; 68 GLboolean *var; 69 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 162 _mesa_EnableClientState( GLenum cap ) 163 { 164 GET_CURRENT_CONTEXT(ctx); 165 client_state( ctx, cap, GL_TRUE ); 166 } 167 168 169 /** 170 * Disable GL capability. 171 * \param cap state to enable/disable. 172 * 173 * Get's the current context, assures that we're outside glBegin()/glEnd() and 174 * calls client_state(). 175 */ 176 void GLAPIENTRY 177 _mesa_DisableClientState( GLenum cap ) 178 { 179 GET_CURRENT_CONTEXT(ctx); 180 client_state( ctx, cap, GL_FALSE ); 181 } 182 183 184 #undef CHECK_EXTENSION 185 #define CHECK_EXTENSION(EXTNAME, CAP) \ 186 if (!ctx->Extensions.EXTNAME) { \ 187 goto invalid_enum_error; \ 188 } 189 190 #define CHECK_EXTENSION2(EXT1, EXT2, CAP) \ 191 if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \ 192 goto invalid_enum_error; \ 193 } 194 195 /** 196 * Return pointer to current texture unit for setting/getting coordinate 197 * state. 198 * Note that we'll set GL_INVALID_OPERATION and return NULL if the active 199 * texture unit is higher than the number of supported coordinate units. 200 */ 201 static struct gl_texture_unit * 202 get_texcoord_unit(struct gl_context *ctx) 203 { 204 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 205 _mesa_error(ctx, GL_INVALID_OPERATION, "glEnable/Disable(texcoord unit)"); 206 return NULL; 207 } 208 else { 209 return &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 210 } 211 } 212 213 214 /** 215 * Helper function to enable or disable a texture target. 216 * \param bit one of the TEXTURE_x_BIT values 217 * \return GL_TRUE if state is changing or GL_FALSE if no change 218 */ 219 static GLboolean 220 enable_texture(struct gl_context *ctx, GLboolean state, GLbitfield texBit) 221 { 222 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 223 const GLbitfield newenabled = state 224 ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit); 225 226 if (texUnit->Enabled == newenabled) 227 return GL_FALSE; 228 229 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 230 texUnit->Enabled = newenabled; 231 return GL_TRUE; 232 } 233 234 235 /** 236 * Helper function to enable or disable GL_MULTISAMPLE, skipping the check for 237 * whether the API supports it (GLES doesn't). 238 */ 239 void 240 _mesa_set_multisample(struct gl_context *ctx, GLboolean state) 241 { 242 if (ctx->Multisample.Enabled == state) 243 return; 244 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 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 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 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 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 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 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 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 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 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 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