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 "arrayobj.h"
33 #include "blend.h"
34 #include "clip.h"
35 #include "context.h"
36 #include "debug_output.h"
37 #include "draw_validate.h"
38 #include "enable.h"
39 #include "errors.h"
40 #include "light.h"
41 #include "mtypes.h"
42 #include "enums.h"
43 #include "state.h"
44 #include "texstate.h"
45 #include "varray.h"
46
47
48 void
_mesa_update_derived_primitive_restart_state(struct gl_context * ctx)49 _mesa_update_derived_primitive_restart_state(struct gl_context *ctx)
50 {
51 if (ctx->Array.PrimitiveRestart ||
52 ctx->Array.PrimitiveRestartFixedIndex) {
53 unsigned restart_index[3] = {
54 _mesa_primitive_restart_index(ctx, 1),
55 _mesa_primitive_restart_index(ctx, 2),
56 _mesa_primitive_restart_index(ctx, 4),
57 };
58
59 ctx->Array._RestartIndex[0] = restart_index[0];
60 ctx->Array._RestartIndex[1] = restart_index[1];
61 ctx->Array._RestartIndex[2] = restart_index[2];
62
63 /* Enable primitive restart only when the restart index can have an
64 * effect. This is required for correctness in AMD GFX8 support.
65 * Other hardware may also benefit from taking a faster, non-restart path
66 * when possible.
67 */
68 ctx->Array._PrimitiveRestart[0] = true && restart_index[0] <= UINT8_MAX;
69 ctx->Array._PrimitiveRestart[1] = true && restart_index[1] <= UINT16_MAX;
70 ctx->Array._PrimitiveRestart[2] = true;
71 } else {
72 ctx->Array._PrimitiveRestart[0] = false;
73 ctx->Array._PrimitiveRestart[1] = false;
74 ctx->Array._PrimitiveRestart[2] = false;
75 }
76 }
77
78
79 /**
80 * Helper to enable/disable VAO client-side state.
81 */
82 static void
vao_state(struct gl_context * ctx,struct gl_vertex_array_object * vao,gl_vert_attrib attr,GLboolean state)83 vao_state(struct gl_context *ctx, struct gl_vertex_array_object* vao,
84 gl_vert_attrib attr, GLboolean state)
85 {
86 if (state)
87 _mesa_enable_vertex_array_attrib(ctx, vao, attr);
88 else
89 _mesa_disable_vertex_array_attrib(ctx, vao, attr);
90 }
91
92
93 /**
94 * Helper to enable/disable client-side state.
95 */
96 static void
client_state(struct gl_context * ctx,struct gl_vertex_array_object * vao,GLenum cap,GLboolean state)97 client_state(struct gl_context *ctx, struct gl_vertex_array_object* vao,
98 GLenum cap, GLboolean state)
99 {
100 switch (cap) {
101 case GL_VERTEX_ARRAY:
102 vao_state(ctx, vao, VERT_ATTRIB_POS, state);
103 break;
104 case GL_NORMAL_ARRAY:
105 vao_state(ctx, vao, VERT_ATTRIB_NORMAL, state);
106 break;
107 case GL_COLOR_ARRAY:
108 vao_state(ctx, vao, VERT_ATTRIB_COLOR0, state);
109 break;
110 case GL_INDEX_ARRAY:
111 vao_state(ctx, vao, VERT_ATTRIB_COLOR_INDEX, state);
112 break;
113 case GL_TEXTURE_COORD_ARRAY:
114 vao_state(ctx, vao, VERT_ATTRIB_TEX(ctx->Array.ActiveTexture), state);
115 break;
116 case GL_EDGE_FLAG_ARRAY:
117 vao_state(ctx, vao, VERT_ATTRIB_EDGEFLAG, state);
118 break;
119 case GL_FOG_COORDINATE_ARRAY_EXT:
120 vao_state(ctx, vao, VERT_ATTRIB_FOG, state);
121 break;
122 case GL_SECONDARY_COLOR_ARRAY_EXT:
123 vao_state(ctx, vao, VERT_ATTRIB_COLOR1, state);
124 break;
125
126 case GL_POINT_SIZE_ARRAY_OES:
127 if (ctx->VertexProgram.PointSizeEnabled != state) {
128 FLUSH_VERTICES(ctx, _NEW_PROGRAM, 0);
129 ctx->VertexProgram.PointSizeEnabled = state;
130 }
131 vao_state(ctx, vao, VERT_ATTRIB_POINT_SIZE, state);
132 break;
133
134 /* GL_NV_primitive_restart */
135 case GL_PRIMITIVE_RESTART_NV:
136 if (!_mesa_has_NV_primitive_restart(ctx))
137 goto invalid_enum_error;
138 if (ctx->Array.PrimitiveRestart == state)
139 return;
140
141 ctx->Array.PrimitiveRestart = state;
142 _mesa_update_derived_primitive_restart_state(ctx);
143 return;
144
145 default:
146 goto invalid_enum_error;
147 }
148
149 if (ctx->Driver.Enable) {
150 ctx->Driver.Enable( ctx, cap, state );
151 }
152
153 return;
154
155 invalid_enum_error:
156 _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(%s)",
157 state ? "Enable" : "Disable", _mesa_enum_to_string(cap));
158 }
159
160
161 /* Helper for GL_EXT_direct_state_access following functions:
162 * - EnableClientStateIndexedEXT
163 * - EnableClientStateiEXT
164 * - DisableClientStateIndexedEXT
165 * - DisableClientStateiEXT
166 */
167 static void
client_state_i(struct gl_context * ctx,struct gl_vertex_array_object * vao,GLenum cap,GLuint index,GLboolean state)168 client_state_i(struct gl_context *ctx, struct gl_vertex_array_object* vao,
169 GLenum cap, GLuint index, GLboolean state)
170 {
171 int saved_active;
172
173 if (cap != GL_TEXTURE_COORD_ARRAY) {
174 _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientStateiEXT(cap=%s)",
175 state ? "Enable" : "Disable",
176 _mesa_enum_to_string(cap));
177 return;
178 }
179
180 if (index >= ctx->Const.MaxTextureCoordUnits) {
181 _mesa_error(ctx, GL_INVALID_VALUE, "gl%sClientStateiEXT(index=%d)",
182 state ? "Enable" : "Disable",
183 index);
184 return;
185 }
186
187 saved_active = ctx->Array.ActiveTexture;
188 _mesa_ClientActiveTexture(GL_TEXTURE0 + index);
189 client_state(ctx, vao, cap, state);
190 _mesa_ClientActiveTexture(GL_TEXTURE0 + saved_active);
191 }
192
193
194 /**
195 * Enable GL capability.
196 * \param cap state to enable/disable.
197 *
198 * Get's the current context, assures that we're outside glBegin()/glEnd() and
199 * calls client_state().
200 */
201 void GLAPIENTRY
_mesa_EnableClientState(GLenum cap)202 _mesa_EnableClientState( GLenum cap )
203 {
204 GET_CURRENT_CONTEXT(ctx);
205 client_state( ctx, ctx->Array.VAO, cap, GL_TRUE );
206 }
207
208
209 void GLAPIENTRY
_mesa_EnableVertexArrayEXT(GLuint vaobj,GLenum cap)210 _mesa_EnableVertexArrayEXT( GLuint vaobj, GLenum cap )
211 {
212 GET_CURRENT_CONTEXT(ctx);
213 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
214 true,
215 "glEnableVertexArrayEXT");
216 if (!vao)
217 return;
218
219 /* The EXT_direct_state_access spec says:
220 * "Additionally EnableVertexArrayEXT and DisableVertexArrayEXT accept
221 * the tokens TEXTURE0 through TEXTUREn where n is less than the
222 * implementation-dependent limit of MAX_TEXTURE_COORDS. For these
223 * GL_TEXTUREi tokens, EnableVertexArrayEXT and DisableVertexArrayEXT
224 * act identically to EnableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY)
225 * or DisableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY) respectively
226 * as if the active client texture is set to texture coordinate set i
227 * based on the token TEXTUREi indicated by array."
228 */
229 if (GL_TEXTURE0 <= cap && cap < GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits) {
230 GLuint saved_active = ctx->Array.ActiveTexture;
231 _mesa_ClientActiveTexture(cap);
232 client_state(ctx, vao, GL_TEXTURE_COORD_ARRAY, GL_TRUE);
233 _mesa_ClientActiveTexture(GL_TEXTURE0 + saved_active);
234 } else {
235 client_state(ctx, vao, cap, GL_TRUE);
236 }
237 }
238
239
240 void GLAPIENTRY
_mesa_EnableClientStateiEXT(GLenum cap,GLuint index)241 _mesa_EnableClientStateiEXT( GLenum cap, GLuint index )
242 {
243 GET_CURRENT_CONTEXT(ctx);
244 client_state_i(ctx, ctx->Array.VAO, cap, index, GL_TRUE);
245 }
246
247
248 /**
249 * Disable GL capability.
250 * \param cap state to enable/disable.
251 *
252 * Get's the current context, assures that we're outside glBegin()/glEnd() and
253 * calls client_state().
254 */
255 void GLAPIENTRY
_mesa_DisableClientState(GLenum cap)256 _mesa_DisableClientState( GLenum cap )
257 {
258 GET_CURRENT_CONTEXT(ctx);
259 client_state( ctx, ctx->Array.VAO, cap, GL_FALSE );
260 }
261
262 void GLAPIENTRY
_mesa_DisableVertexArrayEXT(GLuint vaobj,GLenum cap)263 _mesa_DisableVertexArrayEXT( GLuint vaobj, GLenum cap )
264 {
265 GET_CURRENT_CONTEXT(ctx);
266 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
267 true,
268 "glDisableVertexArrayEXT");
269 if (!vao)
270 return;
271
272 /* The EXT_direct_state_access spec says:
273 * "Additionally EnableVertexArrayEXT and DisableVertexArrayEXT accept
274 * the tokens TEXTURE0 through TEXTUREn where n is less than the
275 * implementation-dependent limit of MAX_TEXTURE_COORDS. For these
276 * GL_TEXTUREi tokens, EnableVertexArrayEXT and DisableVertexArrayEXT
277 * act identically to EnableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY)
278 * or DisableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY) respectively
279 * as if the active client texture is set to texture coordinate set i
280 * based on the token TEXTUREi indicated by array."
281 */
282 if (GL_TEXTURE0 <= cap && cap < GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits) {
283 GLuint saved_active = ctx->Array.ActiveTexture;
284 _mesa_ClientActiveTexture(cap);
285 client_state(ctx, vao, GL_TEXTURE_COORD_ARRAY, GL_FALSE);
286 _mesa_ClientActiveTexture(GL_TEXTURE0 + saved_active);
287 } else {
288 client_state(ctx, vao, cap, GL_FALSE);
289 }
290 }
291
292 void GLAPIENTRY
_mesa_DisableClientStateiEXT(GLenum cap,GLuint index)293 _mesa_DisableClientStateiEXT( GLenum cap, GLuint index )
294 {
295 GET_CURRENT_CONTEXT(ctx);
296 client_state_i(ctx, ctx->Array.VAO, cap, index, GL_FALSE);
297 }
298
299 /**
300 * Return pointer to current texture unit for setting/getting coordinate
301 * state.
302 * Note that we'll set GL_INVALID_OPERATION and return NULL if the active
303 * texture unit is higher than the number of supported coordinate units.
304 */
305 static struct gl_fixedfunc_texture_unit *
get_texcoord_unit(struct gl_context * ctx)306 get_texcoord_unit(struct gl_context *ctx)
307 {
308 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
309 _mesa_error(ctx, GL_INVALID_OPERATION, "glEnable/Disable(texcoord unit)");
310 return NULL;
311 }
312 else {
313 return &ctx->Texture.FixedFuncUnit[ctx->Texture.CurrentUnit];
314 }
315 }
316
317
318 /**
319 * Helper function to enable or disable a texture target.
320 * \param bit one of the TEXTURE_x_BIT values
321 * \return GL_TRUE if state is changing or GL_FALSE if no change
322 */
323 static GLboolean
enable_texture(struct gl_context * ctx,GLboolean state,GLbitfield texBit)324 enable_texture(struct gl_context *ctx, GLboolean state, GLbitfield texBit)
325 {
326 struct gl_fixedfunc_texture_unit *texUnit =
327 _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
328 if (!texUnit)
329 return GL_FALSE;
330
331 const GLbitfield newenabled = state
332 ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
333
334 if (texUnit->Enabled == newenabled)
335 return GL_FALSE;
336
337 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT | GL_ENABLE_BIT);
338 texUnit->Enabled = newenabled;
339 return GL_TRUE;
340 }
341
342
343 /**
344 * Helper function to enable or disable GL_MULTISAMPLE, skipping the check for
345 * whether the API supports it (GLES doesn't).
346 */
347 void
_mesa_set_multisample(struct gl_context * ctx,GLboolean state)348 _mesa_set_multisample(struct gl_context *ctx, GLboolean state)
349 {
350 if (ctx->Multisample.Enabled == state)
351 return;
352
353 /* GL compatibility needs Multisample.Enable to determine program state
354 * constants.
355 */
356 if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES ||
357 !ctx->DriverFlags.NewMultisampleEnable) {
358 FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
359 } else {
360 FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
361 }
362
363 ctx->NewDriverState |= ctx->DriverFlags.NewMultisampleEnable;
364 ctx->Multisample.Enabled = state;
365
366 if (ctx->Driver.Enable) {
367 ctx->Driver.Enable(ctx, GL_MULTISAMPLE, state);
368 }
369 }
370
371 /**
372 * Helper function to enable or disable GL_FRAMEBUFFER_SRGB, skipping the
373 * check for whether the API supports it (GLES doesn't).
374 */
375 void
_mesa_set_framebuffer_srgb(struct gl_context * ctx,GLboolean state)376 _mesa_set_framebuffer_srgb(struct gl_context *ctx, GLboolean state)
377 {
378 if (ctx->Color.sRGBEnabled == state)
379 return;
380
381 /* TODO: Switch i965 to the new flag and remove the conditional */
382 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewFramebufferSRGB ? 0 : _NEW_BUFFERS,
383 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
384 ctx->NewDriverState |= ctx->DriverFlags.NewFramebufferSRGB;
385 ctx->Color.sRGBEnabled = state;
386
387 if (ctx->Driver.Enable) {
388 ctx->Driver.Enable(ctx, GL_FRAMEBUFFER_SRGB, state);
389 }
390 }
391
392 /**
393 * Helper function to enable or disable state.
394 *
395 * \param ctx GL context.
396 * \param cap the state to enable/disable
397 * \param state whether to enable or disable the specified capability.
398 *
399 * Updates the current context and flushes the vertices as needed. For
400 * capabilities associated with extensions it verifies that those extensions
401 * are effectivly present before updating. Notifies the driver via
402 * dd_function_table::Enable.
403 */
404 void
_mesa_set_enable(struct gl_context * ctx,GLenum cap,GLboolean state)405 _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
406 {
407 if (MESA_VERBOSE & VERBOSE_API)
408 _mesa_debug(ctx, "%s %s (newstate is %x)\n",
409 state ? "glEnable" : "glDisable",
410 _mesa_enum_to_string(cap),
411 ctx->NewState);
412
413 switch (cap) {
414 case GL_ALPHA_TEST:
415 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
416 goto invalid_enum_error;
417 if (ctx->Color.AlphaEnabled == state)
418 return;
419 /* AlphaEnabled is used by the fixed-func fragment program */
420 FLUSH_VERTICES(ctx, _NEW_COLOR | _NEW_FF_FRAG_PROGRAM,
421 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
422 ctx->NewDriverState |= ctx->DriverFlags.NewAlphaTest;
423 ctx->Color.AlphaEnabled = state;
424 break;
425 case GL_AUTO_NORMAL:
426 if (ctx->API != API_OPENGL_COMPAT)
427 goto invalid_enum_error;
428 if (ctx->Eval.AutoNormal == state)
429 return;
430 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
431 vbo_exec_update_eval_maps(ctx);
432 ctx->Eval.AutoNormal = state;
433 break;
434 case GL_BLEND:
435 {
436 GLbitfield newEnabled =
437 state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
438 if (newEnabled != ctx->Color.BlendEnabled) {
439 _mesa_flush_vertices_for_blend_adv(ctx, newEnabled,
440 ctx->Color._AdvancedBlendMode);
441 ctx->PopAttribState |= GL_ENABLE_BIT;
442 ctx->Color.BlendEnabled = newEnabled;
443 _mesa_update_allow_draw_out_of_order(ctx);
444 _mesa_update_valid_to_render_state(ctx);
445 }
446 }
447 break;
448 case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */
449 case GL_CLIP_DISTANCE1:
450 case GL_CLIP_DISTANCE2:
451 case GL_CLIP_DISTANCE3:
452 case GL_CLIP_DISTANCE4:
453 case GL_CLIP_DISTANCE5:
454 case GL_CLIP_DISTANCE6:
455 case GL_CLIP_DISTANCE7:
456 {
457 const GLuint p = cap - GL_CLIP_DISTANCE0;
458
459 if (p >= ctx->Const.MaxClipPlanes)
460 goto invalid_enum_error;
461
462 if ((ctx->Transform.ClipPlanesEnabled & (1 << p))
463 == ((GLuint) state << p))
464 return;
465
466 /* The compatibility profile needs _NEW_TRANSFORM to transform
467 * clip planes according to the projection matrix.
468 */
469 if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES ||
470 !ctx->DriverFlags.NewClipPlaneEnable) {
471 FLUSH_VERTICES(ctx, _NEW_TRANSFORM,
472 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
473 } else {
474 FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT | GL_ENABLE_BIT);
475 }
476 ctx->NewDriverState |= ctx->DriverFlags.NewClipPlaneEnable;
477
478 if (state) {
479 ctx->Transform.ClipPlanesEnabled |= (1 << p);
480
481 /* The projection matrix transforms the clip plane. */
482 /* TODO: glEnable might not be the best place to do it. */
483 if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) {
484 _mesa_update_clip_plane(ctx, p);
485 ctx->NewDriverState |= ctx->DriverFlags.NewClipPlane;
486 }
487 }
488 else {
489 ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
490 }
491 }
492 break;
493 case GL_COLOR_MATERIAL:
494 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
495 goto invalid_enum_error;
496 if (ctx->Light.ColorMaterialEnabled == state)
497 return;
498 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM,
499 GL_LIGHTING_BIT | GL_ENABLE_BIT);
500 FLUSH_CURRENT(ctx, 0);
501 ctx->Light.ColorMaterialEnabled = state;
502 if (state) {
503 _mesa_update_color_material( ctx,
504 ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
505 }
506 break;
507 case GL_CULL_FACE:
508 if (ctx->Polygon.CullFlag == state)
509 return;
510 FLUSH_VERTICES(ctx,
511 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
512 GL_POLYGON_BIT | GL_ENABLE_BIT);
513 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
514 ctx->Polygon.CullFlag = state;
515 break;
516 case GL_DEPTH_TEST:
517 if (ctx->Depth.Test == state)
518 return;
519 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH,
520 GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT);
521 ctx->NewDriverState |= ctx->DriverFlags.NewDepth;
522 ctx->Depth.Test = state;
523 _mesa_update_allow_draw_out_of_order(ctx);
524 break;
525 case GL_DEBUG_OUTPUT:
526 case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
527 _mesa_set_debug_state_int(ctx, cap, state);
528 break;
529 case GL_DITHER:
530 if (ctx->Color.DitherFlag == state)
531 return;
532 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR,
533 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
534 ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
535 ctx->Color.DitherFlag = state;
536 break;
537 case GL_FOG:
538 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
539 goto invalid_enum_error;
540 if (ctx->Fog.Enabled == state)
541 return;
542 FLUSH_VERTICES(ctx, _NEW_FOG | _NEW_FF_FRAG_PROGRAM,
543 GL_FOG_BIT | GL_ENABLE_BIT);
544 ctx->Fog.Enabled = state;
545 ctx->Fog._PackedEnabledMode = state ? ctx->Fog._PackedMode : FOG_NONE;
546 break;
547 case GL_LIGHT0:
548 case GL_LIGHT1:
549 case GL_LIGHT2:
550 case GL_LIGHT3:
551 case GL_LIGHT4:
552 case GL_LIGHT5:
553 case GL_LIGHT6:
554 case GL_LIGHT7:
555 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
556 goto invalid_enum_error;
557 if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
558 return;
559 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM,
560 GL_LIGHTING_BIT | GL_ENABLE_BIT);
561 ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
562 if (state) {
563 ctx->Light._EnabledLights |= 1u << (cap - GL_LIGHT0);
564 }
565 else {
566 ctx->Light._EnabledLights &= ~(1u << (cap - GL_LIGHT0));
567 }
568 break;
569 case GL_LIGHTING:
570 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
571 goto invalid_enum_error;
572 if (ctx->Light.Enabled == state)
573 return;
574 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM |
575 _NEW_FF_FRAG_PROGRAM | _NEW_LIGHT_STATE,
576 GL_LIGHTING_BIT | GL_ENABLE_BIT);
577 ctx->Light.Enabled = state;
578 break;
579 case GL_LINE_SMOOTH:
580 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
581 goto invalid_enum_error;
582 if (ctx->Line.SmoothFlag == state)
583 return;
584 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE,
585 GL_LINE_BIT | GL_ENABLE_BIT);
586 ctx->NewDriverState |= ctx->DriverFlags.NewLineState;
587 ctx->Line.SmoothFlag = state;
588 break;
589 case GL_LINE_STIPPLE:
590 if (ctx->API != API_OPENGL_COMPAT)
591 goto invalid_enum_error;
592 if (ctx->Line.StippleFlag == state)
593 return;
594 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE,
595 GL_LINE_BIT | GL_ENABLE_BIT);
596 ctx->NewDriverState |= ctx->DriverFlags.NewLineState;
597 ctx->Line.StippleFlag = state;
598 break;
599 case GL_INDEX_LOGIC_OP:
600 if (ctx->API != API_OPENGL_COMPAT)
601 goto invalid_enum_error;
602 if (ctx->Color.IndexLogicOpEnabled == state)
603 return;
604 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR,
605 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
606 ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp;
607 ctx->Color.IndexLogicOpEnabled = state;
608 break;
609 case GL_CONSERVATIVE_RASTERIZATION_INTEL:
610 if (!_mesa_has_INTEL_conservative_rasterization(ctx))
611 goto invalid_enum_error;
612 if (ctx->IntelConservativeRasterization == state)
613 return;
614 FLUSH_VERTICES(ctx, 0, 0);
615 ctx->NewDriverState |=
616 ctx->DriverFlags.NewIntelConservativeRasterization;
617 ctx->IntelConservativeRasterization = state;
618 _mesa_update_valid_to_render_state(ctx);
619 break;
620 case GL_CONSERVATIVE_RASTERIZATION_NV:
621 if (!_mesa_has_NV_conservative_raster(ctx))
622 goto invalid_enum_error;
623 if (ctx->ConservativeRasterization == state)
624 return;
625 FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT);
626 ctx->NewDriverState |=
627 ctx->DriverFlags.NewNvConservativeRasterization;
628 ctx->ConservativeRasterization = state;
629 break;
630 case GL_COLOR_LOGIC_OP:
631 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
632 goto invalid_enum_error;
633 if (ctx->Color.ColorLogicOpEnabled == state)
634 return;
635 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR,
636 GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
637 ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp;
638 ctx->Color.ColorLogicOpEnabled = state;
639 _mesa_update_allow_draw_out_of_order(ctx);
640 break;
641 case GL_MAP1_COLOR_4:
642 if (ctx->API != API_OPENGL_COMPAT)
643 goto invalid_enum_error;
644 if (ctx->Eval.Map1Color4 == state)
645 return;
646 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
647 vbo_exec_update_eval_maps(ctx);
648 ctx->Eval.Map1Color4 = state;
649 break;
650 case GL_MAP1_INDEX:
651 if (ctx->API != API_OPENGL_COMPAT)
652 goto invalid_enum_error;
653 if (ctx->Eval.Map1Index == state)
654 return;
655 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
656 vbo_exec_update_eval_maps(ctx);
657 ctx->Eval.Map1Index = state;
658 break;
659 case GL_MAP1_NORMAL:
660 if (ctx->API != API_OPENGL_COMPAT)
661 goto invalid_enum_error;
662 if (ctx->Eval.Map1Normal == state)
663 return;
664 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
665 vbo_exec_update_eval_maps(ctx);
666 ctx->Eval.Map1Normal = state;
667 break;
668 case GL_MAP1_TEXTURE_COORD_1:
669 if (ctx->API != API_OPENGL_COMPAT)
670 goto invalid_enum_error;
671 if (ctx->Eval.Map1TextureCoord1 == state)
672 return;
673 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
674 vbo_exec_update_eval_maps(ctx);
675 ctx->Eval.Map1TextureCoord1 = state;
676 break;
677 case GL_MAP1_TEXTURE_COORD_2:
678 if (ctx->API != API_OPENGL_COMPAT)
679 goto invalid_enum_error;
680 if (ctx->Eval.Map1TextureCoord2 == state)
681 return;
682 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
683 vbo_exec_update_eval_maps(ctx);
684 ctx->Eval.Map1TextureCoord2 = state;
685 break;
686 case GL_MAP1_TEXTURE_COORD_3:
687 if (ctx->API != API_OPENGL_COMPAT)
688 goto invalid_enum_error;
689 if (ctx->Eval.Map1TextureCoord3 == state)
690 return;
691 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
692 vbo_exec_update_eval_maps(ctx);
693 ctx->Eval.Map1TextureCoord3 = state;
694 break;
695 case GL_MAP1_TEXTURE_COORD_4:
696 if (ctx->API != API_OPENGL_COMPAT)
697 goto invalid_enum_error;
698 if (ctx->Eval.Map1TextureCoord4 == state)
699 return;
700 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
701 vbo_exec_update_eval_maps(ctx);
702 ctx->Eval.Map1TextureCoord4 = state;
703 break;
704 case GL_MAP1_VERTEX_3:
705 if (ctx->API != API_OPENGL_COMPAT)
706 goto invalid_enum_error;
707 if (ctx->Eval.Map1Vertex3 == state)
708 return;
709 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
710 vbo_exec_update_eval_maps(ctx);
711 ctx->Eval.Map1Vertex3 = state;
712 break;
713 case GL_MAP1_VERTEX_4:
714 if (ctx->API != API_OPENGL_COMPAT)
715 goto invalid_enum_error;
716 if (ctx->Eval.Map1Vertex4 == state)
717 return;
718 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
719 vbo_exec_update_eval_maps(ctx);
720 ctx->Eval.Map1Vertex4 = state;
721 break;
722 case GL_MAP2_COLOR_4:
723 if (ctx->API != API_OPENGL_COMPAT)
724 goto invalid_enum_error;
725 if (ctx->Eval.Map2Color4 == state)
726 return;
727 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
728 vbo_exec_update_eval_maps(ctx);
729 ctx->Eval.Map2Color4 = state;
730 break;
731 case GL_MAP2_INDEX:
732 if (ctx->API != API_OPENGL_COMPAT)
733 goto invalid_enum_error;
734 if (ctx->Eval.Map2Index == state)
735 return;
736 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
737 vbo_exec_update_eval_maps(ctx);
738 ctx->Eval.Map2Index = state;
739 break;
740 case GL_MAP2_NORMAL:
741 if (ctx->API != API_OPENGL_COMPAT)
742 goto invalid_enum_error;
743 if (ctx->Eval.Map2Normal == state)
744 return;
745 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
746 vbo_exec_update_eval_maps(ctx);
747 ctx->Eval.Map2Normal = state;
748 break;
749 case GL_MAP2_TEXTURE_COORD_1:
750 if (ctx->API != API_OPENGL_COMPAT)
751 goto invalid_enum_error;
752 if (ctx->Eval.Map2TextureCoord1 == state)
753 return;
754 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
755 vbo_exec_update_eval_maps(ctx);
756 ctx->Eval.Map2TextureCoord1 = state;
757 break;
758 case GL_MAP2_TEXTURE_COORD_2:
759 if (ctx->API != API_OPENGL_COMPAT)
760 goto invalid_enum_error;
761 if (ctx->Eval.Map2TextureCoord2 == state)
762 return;
763 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
764 vbo_exec_update_eval_maps(ctx);
765 ctx->Eval.Map2TextureCoord2 = state;
766 break;
767 case GL_MAP2_TEXTURE_COORD_3:
768 if (ctx->API != API_OPENGL_COMPAT)
769 goto invalid_enum_error;
770 if (ctx->Eval.Map2TextureCoord3 == state)
771 return;
772 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
773 vbo_exec_update_eval_maps(ctx);
774 ctx->Eval.Map2TextureCoord3 = state;
775 break;
776 case GL_MAP2_TEXTURE_COORD_4:
777 if (ctx->API != API_OPENGL_COMPAT)
778 goto invalid_enum_error;
779 if (ctx->Eval.Map2TextureCoord4 == state)
780 return;
781 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
782 vbo_exec_update_eval_maps(ctx);
783 ctx->Eval.Map2TextureCoord4 = state;
784 break;
785 case GL_MAP2_VERTEX_3:
786 if (ctx->API != API_OPENGL_COMPAT)
787 goto invalid_enum_error;
788 if (ctx->Eval.Map2Vertex3 == state)
789 return;
790 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
791 vbo_exec_update_eval_maps(ctx);
792 ctx->Eval.Map2Vertex3 = state;
793 break;
794 case GL_MAP2_VERTEX_4:
795 if (ctx->API != API_OPENGL_COMPAT)
796 goto invalid_enum_error;
797 if (ctx->Eval.Map2Vertex4 == state)
798 return;
799 FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT | GL_ENABLE_BIT);
800 vbo_exec_update_eval_maps(ctx);
801 ctx->Eval.Map2Vertex4 = state;
802 break;
803 case GL_NORMALIZE:
804 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
805 goto invalid_enum_error;
806 if (ctx->Transform.Normalize == state)
807 return;
808 FLUSH_VERTICES(ctx, _NEW_TRANSFORM | _NEW_FF_VERT_PROGRAM,
809 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
810 ctx->Transform.Normalize = state;
811 break;
812 case GL_POINT_SMOOTH:
813 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
814 goto invalid_enum_error;
815 if (ctx->Point.SmoothFlag == state)
816 return;
817 FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT | GL_ENABLE_BIT);
818 ctx->Point.SmoothFlag = state;
819 break;
820 case GL_POLYGON_SMOOTH:
821 if (!_mesa_is_desktop_gl(ctx))
822 goto invalid_enum_error;
823 if (ctx->Polygon.SmoothFlag == state)
824 return;
825 FLUSH_VERTICES(ctx,
826 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
827 GL_POLYGON_BIT | GL_ENABLE_BIT);
828 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
829 ctx->Polygon.SmoothFlag = state;
830 break;
831 case GL_POLYGON_STIPPLE:
832 if (ctx->API != API_OPENGL_COMPAT)
833 goto invalid_enum_error;
834 if (ctx->Polygon.StippleFlag == state)
835 return;
836 FLUSH_VERTICES(ctx,
837 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
838 GL_POLYGON_BIT | GL_ENABLE_BIT);
839 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
840 ctx->Polygon.StippleFlag = state;
841 break;
842 case GL_POLYGON_OFFSET_POINT:
843 if (!_mesa_is_desktop_gl(ctx))
844 goto invalid_enum_error;
845 if (ctx->Polygon.OffsetPoint == state)
846 return;
847 FLUSH_VERTICES(ctx,
848 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
849 GL_POLYGON_BIT | GL_ENABLE_BIT);
850 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
851 ctx->Polygon.OffsetPoint = state;
852 break;
853 case GL_POLYGON_OFFSET_LINE:
854 if (!_mesa_is_desktop_gl(ctx))
855 goto invalid_enum_error;
856 if (ctx->Polygon.OffsetLine == state)
857 return;
858 FLUSH_VERTICES(ctx,
859 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
860 GL_POLYGON_BIT | GL_ENABLE_BIT);
861 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
862 ctx->Polygon.OffsetLine = state;
863 break;
864 case GL_POLYGON_OFFSET_FILL:
865 if (ctx->Polygon.OffsetFill == state)
866 return;
867 FLUSH_VERTICES(ctx,
868 ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON,
869 GL_POLYGON_BIT | GL_ENABLE_BIT);
870 ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
871 ctx->Polygon.OffsetFill = state;
872 break;
873 case GL_RESCALE_NORMAL_EXT:
874 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
875 goto invalid_enum_error;
876 if (ctx->Transform.RescaleNormals == state)
877 return;
878 FLUSH_VERTICES(ctx, _NEW_TRANSFORM | _NEW_FF_VERT_PROGRAM,
879 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
880 ctx->Transform.RescaleNormals = state;
881 break;
882 case GL_SCISSOR_TEST:
883 {
884 /* Must expand glEnable to all scissors */
885 GLbitfield newEnabled =
886 state * ((1 << ctx->Const.MaxViewports) - 1);
887 if (newEnabled != ctx->Scissor.EnableFlags) {
888 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorTest ? 0 :
889 _NEW_SCISSOR,
890 GL_SCISSOR_BIT | GL_ENABLE_BIT);
891 ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest;
892 ctx->Scissor.EnableFlags = newEnabled;
893 }
894 }
895 break;
896 case GL_STENCIL_TEST:
897 if (ctx->Stencil.Enabled == state)
898 return;
899 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL,
900 GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT);
901 ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
902 ctx->Stencil.Enabled = state;
903 _mesa_update_allow_draw_out_of_order(ctx);
904 break;
905 case GL_TEXTURE_1D:
906 if (ctx->API != API_OPENGL_COMPAT)
907 goto invalid_enum_error;
908 if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
909 return;
910 }
911 break;
912 case GL_TEXTURE_2D:
913 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
914 goto invalid_enum_error;
915 if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) {
916 return;
917 }
918 break;
919 case GL_TEXTURE_3D:
920 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
921 goto invalid_enum_error;
922 if (!enable_texture(ctx, state, TEXTURE_3D_BIT)) {
923 return;
924 }
925 break;
926 case GL_TEXTURE_GEN_S:
927 case GL_TEXTURE_GEN_T:
928 case GL_TEXTURE_GEN_R:
929 case GL_TEXTURE_GEN_Q:
930 {
931 struct gl_fixedfunc_texture_unit *texUnit = get_texcoord_unit(ctx);
932
933 if (ctx->API != API_OPENGL_COMPAT)
934 goto invalid_enum_error;
935
936 if (texUnit) {
937 GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
938 GLbitfield newenabled = texUnit->TexGenEnabled & ~coordBit;
939 if (state)
940 newenabled |= coordBit;
941 if (texUnit->TexGenEnabled == newenabled)
942 return;
943 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE | _NEW_FF_VERT_PROGRAM |
944 _NEW_FF_FRAG_PROGRAM,
945 GL_TEXTURE_BIT | GL_ENABLE_BIT);
946 texUnit->TexGenEnabled = newenabled;
947 }
948 }
949 break;
950
951 case GL_TEXTURE_GEN_STR_OES:
952 /* disable S, T, and R at the same time */
953 {
954 struct gl_fixedfunc_texture_unit *texUnit = get_texcoord_unit(ctx);
955
956 if (ctx->API != API_OPENGLES)
957 goto invalid_enum_error;
958
959 if (texUnit) {
960 GLuint newenabled =
961 texUnit->TexGenEnabled & ~STR_BITS;
962 if (state)
963 newenabled |= STR_BITS;
964 if (texUnit->TexGenEnabled == newenabled)
965 return;
966 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE | _NEW_FF_VERT_PROGRAM |
967 _NEW_FF_FRAG_PROGRAM, 0);
968 texUnit->TexGenEnabled = newenabled;
969 }
970 }
971 break;
972
973 /* client-side state */
974 case GL_VERTEX_ARRAY:
975 case GL_NORMAL_ARRAY:
976 case GL_COLOR_ARRAY:
977 case GL_TEXTURE_COORD_ARRAY:
978 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
979 goto invalid_enum_error;
980 client_state( ctx, ctx->Array.VAO, cap, state );
981 return;
982 case GL_INDEX_ARRAY:
983 case GL_EDGE_FLAG_ARRAY:
984 case GL_FOG_COORDINATE_ARRAY_EXT:
985 case GL_SECONDARY_COLOR_ARRAY_EXT:
986 if (ctx->API != API_OPENGL_COMPAT)
987 goto invalid_enum_error;
988 client_state( ctx, ctx->Array.VAO, cap, state );
989 return;
990 case GL_POINT_SIZE_ARRAY_OES:
991 if (ctx->API != API_OPENGLES)
992 goto invalid_enum_error;
993 client_state( ctx, ctx->Array.VAO, cap, state );
994 return;
995
996 /* GL_ARB_texture_cube_map */
997 case GL_TEXTURE_CUBE_MAP:
998 if (!_mesa_has_ARB_texture_cube_map(ctx) &&
999 !_mesa_has_OES_texture_cube_map(ctx))
1000 goto invalid_enum_error;
1001 if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) {
1002 return;
1003 }
1004 break;
1005
1006 /* GL_EXT_secondary_color */
1007 case GL_COLOR_SUM_EXT:
1008 if (ctx->API != API_OPENGL_COMPAT)
1009 goto invalid_enum_error;
1010 if (ctx->Fog.ColorSumEnabled == state)
1011 return;
1012 FLUSH_VERTICES(ctx, _NEW_FOG | _NEW_FF_FRAG_PROGRAM,
1013 GL_FOG_BIT | GL_ENABLE_BIT);
1014 ctx->Fog.ColorSumEnabled = state;
1015 break;
1016
1017 /* GL_ARB_multisample */
1018 case GL_MULTISAMPLE_ARB:
1019 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1020 goto invalid_enum_error;
1021 _mesa_set_multisample(ctx, state);
1022 return;
1023 case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
1024 if (ctx->Multisample.SampleAlphaToCoverage == state)
1025 return;
1026 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 :
1027 _NEW_MULTISAMPLE,
1028 GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
1029 ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable;
1030 ctx->Multisample.SampleAlphaToCoverage = state;
1031 break;
1032 case GL_SAMPLE_ALPHA_TO_ONE_ARB:
1033 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1034 goto invalid_enum_error;
1035 if (ctx->Multisample.SampleAlphaToOne == state)
1036 return;
1037 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 :
1038 _NEW_MULTISAMPLE,
1039 GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
1040 ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable;
1041 ctx->Multisample.SampleAlphaToOne = state;
1042 break;
1043 case GL_SAMPLE_COVERAGE_ARB:
1044 if (ctx->Multisample.SampleCoverage == state)
1045 return;
1046 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 :
1047 _NEW_MULTISAMPLE,
1048 GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
1049 ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask;
1050 ctx->Multisample.SampleCoverage = state;
1051 break;
1052 case GL_SAMPLE_COVERAGE_INVERT_ARB:
1053 if (!_mesa_is_desktop_gl(ctx))
1054 goto invalid_enum_error;
1055 if (ctx->Multisample.SampleCoverageInvert == state)
1056 return;
1057 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 :
1058 _NEW_MULTISAMPLE,
1059 GL_MULTISAMPLE_BIT);
1060 ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask;
1061 ctx->Multisample.SampleCoverageInvert = state;
1062 break;
1063
1064 /* GL_ARB_sample_shading */
1065 case GL_SAMPLE_SHADING:
1066 if (!_mesa_has_ARB_sample_shading(ctx) && !_mesa_is_gles3(ctx))
1067 goto invalid_enum_error;
1068 if (ctx->Multisample.SampleShading == state)
1069 return;
1070 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleShading ? 0 :
1071 _NEW_MULTISAMPLE,
1072 GL_MULTISAMPLE_BIT | GL_ENABLE_BIT);
1073 ctx->NewDriverState |= ctx->DriverFlags.NewSampleShading;
1074 ctx->Multisample.SampleShading = state;
1075 break;
1076
1077 /* GL_IBM_rasterpos_clip */
1078 case GL_RASTER_POSITION_UNCLIPPED_IBM:
1079 if (ctx->API != API_OPENGL_COMPAT)
1080 goto invalid_enum_error;
1081 if (ctx->Transform.RasterPositionUnclipped == state)
1082 return;
1083 FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1084 ctx->Transform.RasterPositionUnclipped = state;
1085 break;
1086
1087 /* GL_ARB_point_sprite */
1088 case GL_POINT_SPRITE:
1089 if (!(ctx->API == API_OPENGL_COMPAT &&
1090 _mesa_has_ARB_point_sprite(ctx)) &&
1091 !_mesa_has_OES_point_sprite(ctx))
1092 goto invalid_enum_error;
1093 if (ctx->Point.PointSprite == state)
1094 return;
1095 FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM |
1096 _NEW_FF_FRAG_PROGRAM, GL_POINT_BIT | GL_ENABLE_BIT);
1097 ctx->Point.PointSprite = state;
1098 break;
1099
1100 case GL_VERTEX_PROGRAM_ARB:
1101 if (!_mesa_has_ARB_vertex_program(ctx))
1102 goto invalid_enum_error;
1103 if (ctx->VertexProgram.Enabled == state)
1104 return;
1105 FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT);
1106 ctx->VertexProgram.Enabled = state;
1107 _mesa_update_vertex_processing_mode(ctx);
1108 _mesa_update_valid_to_render_state(ctx);
1109 break;
1110 case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1111 /* This was added with ARB_vertex_program, but it is also used with
1112 * GLSL vertex shaders on desktop.
1113 */
1114 if (!_mesa_has_ARB_vertex_program(ctx) &&
1115 ctx->API != API_OPENGL_CORE)
1116 goto invalid_enum_error;
1117 if (ctx->VertexProgram.PointSizeEnabled == state)
1118 return;
1119 FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT);
1120 ctx->VertexProgram.PointSizeEnabled = state;
1121 break;
1122 case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
1123 if (!_mesa_has_ARB_vertex_program(ctx))
1124 goto invalid_enum_error;
1125 if (ctx->VertexProgram.TwoSideEnabled == state)
1126 return;
1127 FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT);
1128 ctx->VertexProgram.TwoSideEnabled = state;
1129 break;
1130
1131 /* GL_NV_texture_rectangle */
1132 case GL_TEXTURE_RECTANGLE_NV:
1133 if (!_mesa_has_NV_texture_rectangle(ctx))
1134 goto invalid_enum_error;
1135 if (!enable_texture(ctx, state, TEXTURE_RECT_BIT)) {
1136 return;
1137 }
1138 break;
1139
1140 /* GL_EXT_stencil_two_side */
1141 case GL_STENCIL_TEST_TWO_SIDE_EXT:
1142 if (!_mesa_has_EXT_stencil_two_side(ctx))
1143 goto invalid_enum_error;
1144 if (ctx->Stencil.TestTwoSide == state)
1145 return;
1146 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL,
1147 GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT);
1148 ctx->NewDriverState |= ctx->DriverFlags.NewStencil;
1149 ctx->Stencil.TestTwoSide = state;
1150 if (state) {
1151 ctx->Stencil._BackFace = 2;
1152 } else {
1153 ctx->Stencil._BackFace = 1;
1154 }
1155 break;
1156
1157 case GL_FRAGMENT_PROGRAM_ARB:
1158 if (!_mesa_has_ARB_fragment_program(ctx))
1159 goto invalid_enum_error;
1160 if (ctx->FragmentProgram.Enabled == state)
1161 return;
1162 FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT);
1163 ctx->FragmentProgram.Enabled = state;
1164 _mesa_update_valid_to_render_state(ctx);
1165 break;
1166
1167 /* GL_EXT_depth_bounds_test */
1168 case GL_DEPTH_BOUNDS_TEST_EXT:
1169 if (!_mesa_has_EXT_depth_bounds_test(ctx))
1170 goto invalid_enum_error;
1171 if (ctx->Depth.BoundsTest == state)
1172 return;
1173 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH,
1174 GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT);
1175 ctx->NewDriverState |= ctx->DriverFlags.NewDepth;
1176 ctx->Depth.BoundsTest = state;
1177 break;
1178
1179 case GL_DEPTH_CLAMP:
1180 if (!_mesa_has_ARB_depth_clamp(ctx) &&
1181 !_mesa_has_EXT_depth_clamp(ctx))
1182 goto invalid_enum_error;
1183 if (ctx->Transform.DepthClampNear == state &&
1184 ctx->Transform.DepthClampFar == state)
1185 return;
1186 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 :
1187 _NEW_TRANSFORM,
1188 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1189 ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp;
1190 ctx->Transform.DepthClampNear = state;
1191 ctx->Transform.DepthClampFar = state;
1192 break;
1193
1194 case GL_DEPTH_CLAMP_NEAR_AMD:
1195 if (!_mesa_has_AMD_depth_clamp_separate(ctx))
1196 goto invalid_enum_error;
1197 if (ctx->Transform.DepthClampNear == state)
1198 return;
1199 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 :
1200 _NEW_TRANSFORM,
1201 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1202 ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp;
1203 ctx->Transform.DepthClampNear = state;
1204 break;
1205
1206 case GL_DEPTH_CLAMP_FAR_AMD:
1207 if (!_mesa_has_AMD_depth_clamp_separate(ctx))
1208 goto invalid_enum_error;
1209 if (ctx->Transform.DepthClampFar == state)
1210 return;
1211 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 :
1212 _NEW_TRANSFORM,
1213 GL_TRANSFORM_BIT | GL_ENABLE_BIT);
1214 ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp;
1215 ctx->Transform.DepthClampFar = state;
1216 break;
1217
1218 case GL_FRAGMENT_SHADER_ATI:
1219 if (!_mesa_has_ATI_fragment_shader(ctx))
1220 goto invalid_enum_error;
1221 if (ctx->ATIFragmentShader.Enabled == state)
1222 return;
1223 FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT);
1224 ctx->ATIFragmentShader.Enabled = state;
1225 break;
1226
1227 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1228 if (!_mesa_has_ARB_seamless_cube_map(ctx))
1229 goto invalid_enum_error;
1230 if (ctx->Texture.CubeMapSeamless != state) {
1231 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, 0);
1232 ctx->Texture.CubeMapSeamless = state;
1233 }
1234 break;
1235
1236 case GL_RASTERIZER_DISCARD:
1237 if (!(_mesa_has_EXT_transform_feedback(ctx) || _mesa_is_gles3(ctx)))
1238 goto invalid_enum_error;
1239 if (ctx->RasterDiscard != state) {
1240 FLUSH_VERTICES(ctx, 0, 0);
1241 ctx->NewDriverState |= ctx->DriverFlags.NewRasterizerDiscard;
1242 ctx->RasterDiscard = state;
1243 }
1244 break;
1245
1246 case GL_TILE_RASTER_ORDER_FIXED_MESA:
1247 if (!_mesa_has_MESA_tile_raster_order(ctx))
1248 goto invalid_enum_error;
1249 if (ctx->TileRasterOrderFixed != state) {
1250 FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT);
1251 ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder;
1252 ctx->TileRasterOrderFixed = state;
1253 }
1254 break;
1255
1256 case GL_TILE_RASTER_ORDER_INCREASING_X_MESA:
1257 if (!_mesa_has_MESA_tile_raster_order(ctx))
1258 goto invalid_enum_error;
1259 if (ctx->TileRasterOrderIncreasingX != state) {
1260 FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT);
1261 ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder;
1262 ctx->TileRasterOrderIncreasingX = state;
1263 }
1264 break;
1265
1266 case GL_TILE_RASTER_ORDER_INCREASING_Y_MESA:
1267 if (!_mesa_has_MESA_tile_raster_order(ctx))
1268 goto invalid_enum_error;
1269 if (ctx->TileRasterOrderIncreasingY != state) {
1270 FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT);
1271 ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder;
1272 ctx->TileRasterOrderIncreasingY = state;
1273 }
1274 break;
1275
1276 /* GL 3.1 primitive restart. Note: this enum is different from
1277 * GL_PRIMITIVE_RESTART_NV (which is client state).
1278 */
1279 case GL_PRIMITIVE_RESTART:
1280 if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 31) {
1281 goto invalid_enum_error;
1282 }
1283 if (ctx->Array.PrimitiveRestart != state) {
1284 ctx->Array.PrimitiveRestart = state;
1285 _mesa_update_derived_primitive_restart_state(ctx);
1286 }
1287 break;
1288
1289 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1290 if (!_mesa_is_gles3(ctx) && !_mesa_has_ARB_ES3_compatibility(ctx))
1291 goto invalid_enum_error;
1292 if (ctx->Array.PrimitiveRestartFixedIndex != state) {
1293 ctx->Array.PrimitiveRestartFixedIndex = state;
1294 _mesa_update_derived_primitive_restart_state(ctx);
1295 }
1296 break;
1297
1298 /* GL3.0 - GL_framebuffer_sRGB */
1299 case GL_FRAMEBUFFER_SRGB_EXT:
1300 if (!_mesa_has_EXT_framebuffer_sRGB(ctx) &&
1301 !_mesa_has_EXT_sRGB_write_control(ctx))
1302 goto invalid_enum_error;
1303 _mesa_set_framebuffer_srgb(ctx, state);
1304 return;
1305
1306 /* GL_OES_EGL_image_external */
1307 case GL_TEXTURE_EXTERNAL_OES:
1308 if (!_mesa_has_OES_EGL_image_external(ctx))
1309 goto invalid_enum_error;
1310 if (!enable_texture(ctx, state, TEXTURE_EXTERNAL_BIT)) {
1311 return;
1312 }
1313 break;
1314
1315 /* ARB_texture_multisample */
1316 case GL_SAMPLE_MASK:
1317 if (!_mesa_has_ARB_texture_multisample(ctx) && !_mesa_is_gles31(ctx))
1318 goto invalid_enum_error;
1319 if (ctx->Multisample.SampleMask == state)
1320 return;
1321 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 :
1322 _NEW_MULTISAMPLE, 0);
1323 ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask;
1324 ctx->Multisample.SampleMask = state;
1325 break;
1326
1327 case GL_BLEND_ADVANCED_COHERENT_KHR:
1328 if (!_mesa_has_KHR_blend_equation_advanced_coherent(ctx))
1329 goto invalid_enum_error;
1330 if (ctx->Color.BlendCoherent == state)
1331 return;
1332 FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR,
1333 GL_COLOR_BUFFER_BIT);
1334 ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
1335 ctx->Color.BlendCoherent = state;
1336 break;
1337
1338 case GL_BLACKHOLE_RENDER_INTEL:
1339 if (!_mesa_has_INTEL_blackhole_render(ctx))
1340 goto invalid_enum_error;
1341 if (ctx->IntelBlackholeRender == state)
1342 return;
1343 FLUSH_VERTICES(ctx, 0, 0);
1344 ctx->IntelBlackholeRender = state;
1345 break;
1346
1347 default:
1348 goto invalid_enum_error;
1349 }
1350
1351 if (ctx->Driver.Enable) {
1352 ctx->Driver.Enable( ctx, cap, state );
1353 }
1354
1355 return;
1356
1357 invalid_enum_error:
1358 _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(%s)",
1359 state ? "Enable" : "Disable", _mesa_enum_to_string(cap));
1360 }
1361
1362
1363 /**
1364 * Enable GL capability. Called by glEnable()
1365 * \param cap state to enable.
1366 */
1367 void GLAPIENTRY
_mesa_Enable(GLenum cap)1368 _mesa_Enable( GLenum cap )
1369 {
1370 GET_CURRENT_CONTEXT(ctx);
1371
1372 _mesa_set_enable( ctx, cap, GL_TRUE );
1373 }
1374
1375
1376 /**
1377 * Disable GL capability. Called by glDisable()
1378 * \param cap state to disable.
1379 */
1380 void GLAPIENTRY
_mesa_Disable(GLenum cap)1381 _mesa_Disable( GLenum cap )
1382 {
1383 GET_CURRENT_CONTEXT(ctx);
1384
1385 _mesa_set_enable( ctx, cap, GL_FALSE );
1386 }
1387
1388
1389
1390 /**
1391 * Enable/disable an indexed state var.
1392 */
1393 void
_mesa_set_enablei(struct gl_context * ctx,GLenum cap,GLuint index,GLboolean state)1394 _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
1395 GLuint index, GLboolean state)
1396 {
1397 assert(state == 0 || state == 1);
1398 switch (cap) {
1399 case GL_BLEND:
1400 if (!ctx->Extensions.EXT_draw_buffers2) {
1401 goto invalid_enum_error;
1402 }
1403 if (index >= ctx->Const.MaxDrawBuffers) {
1404 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1405 state ? "glEnableIndexed" : "glDisableIndexed", index);
1406 return;
1407 }
1408 if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
1409 GLbitfield enabled = ctx->Color.BlendEnabled;
1410
1411 if (state)
1412 enabled |= (1 << index);
1413 else
1414 enabled &= ~(1 << index);
1415
1416 _mesa_flush_vertices_for_blend_adv(ctx, enabled,
1417 ctx->Color._AdvancedBlendMode);
1418 ctx->PopAttribState |= GL_ENABLE_BIT;
1419 ctx->Color.BlendEnabled = enabled;
1420 _mesa_update_allow_draw_out_of_order(ctx);
1421 _mesa_update_valid_to_render_state(ctx);
1422 }
1423 break;
1424 case GL_SCISSOR_TEST:
1425 if (index >= ctx->Const.MaxViewports) {
1426 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1427 state ? "glEnablei" : "glDisablei", index);
1428 return;
1429 }
1430 if (((ctx->Scissor.EnableFlags >> index) & 1) != state) {
1431 FLUSH_VERTICES(ctx,
1432 ctx->DriverFlags.NewScissorTest ? 0 : _NEW_SCISSOR,
1433 GL_SCISSOR_BIT | GL_ENABLE_BIT);
1434 ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest;
1435 if (state)
1436 ctx->Scissor.EnableFlags |= (1 << index);
1437 else
1438 ctx->Scissor.EnableFlags &= ~(1 << index);
1439 }
1440 break;
1441 /* EXT_direct_state_access */
1442 case GL_TEXTURE_1D:
1443 case GL_TEXTURE_2D:
1444 case GL_TEXTURE_3D:
1445 case GL_TEXTURE_CUBE_MAP:
1446 case GL_TEXTURE_GEN_S:
1447 case GL_TEXTURE_GEN_T:
1448 case GL_TEXTURE_GEN_R:
1449 case GL_TEXTURE_GEN_Q:
1450 case GL_TEXTURE_RECTANGLE_ARB: {
1451 const GLuint curTexUnitSave = ctx->Texture.CurrentUnit;
1452 if (index >= MAX2(ctx->Const.MaxCombinedTextureImageUnits,
1453 ctx->Const.MaxTextureCoordUnits)) {
1454 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
1455 state ? "glEnablei" : "glDisablei", index);
1456 return;
1457 }
1458 _mesa_ActiveTexture(GL_TEXTURE0 + index);
1459 _mesa_set_enable( ctx, cap, state );
1460 _mesa_ActiveTexture(GL_TEXTURE0 + curTexUnitSave);
1461 break;
1462 }
1463 default:
1464 goto invalid_enum_error;
1465 }
1466 return;
1467
1468 invalid_enum_error:
1469 _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
1470 state ? "glEnablei" : "glDisablei",
1471 _mesa_enum_to_string(cap));
1472 }
1473
1474
1475 void GLAPIENTRY
_mesa_Disablei(GLenum cap,GLuint index)1476 _mesa_Disablei( GLenum cap, GLuint index )
1477 {
1478 GET_CURRENT_CONTEXT(ctx);
1479 _mesa_set_enablei(ctx, cap, index, GL_FALSE);
1480 }
1481
1482
1483 void GLAPIENTRY
_mesa_Enablei(GLenum cap,GLuint index)1484 _mesa_Enablei( GLenum cap, GLuint index )
1485 {
1486 GET_CURRENT_CONTEXT(ctx);
1487 _mesa_set_enablei(ctx, cap, index, GL_TRUE);
1488 }
1489
1490
1491 GLboolean GLAPIENTRY
_mesa_IsEnabledi(GLenum cap,GLuint index)1492 _mesa_IsEnabledi( GLenum cap, GLuint index )
1493 {
1494 GET_CURRENT_CONTEXT(ctx);
1495 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1496 switch (cap) {
1497 case GL_BLEND:
1498 if (index >= ctx->Const.MaxDrawBuffers) {
1499 _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1500 index);
1501 return GL_FALSE;
1502 }
1503 return (ctx->Color.BlendEnabled >> index) & 1;
1504 case GL_SCISSOR_TEST:
1505 if (index >= ctx->Const.MaxViewports) {
1506 _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1507 index);
1508 return GL_FALSE;
1509 }
1510 return (ctx->Scissor.EnableFlags >> index) & 1;
1511 /* EXT_direct_state_access */
1512 case GL_TEXTURE_1D:
1513 case GL_TEXTURE_2D:
1514 case GL_TEXTURE_3D:
1515 case GL_TEXTURE_CUBE_MAP:
1516 case GL_TEXTURE_GEN_S:
1517 case GL_TEXTURE_GEN_T:
1518 case GL_TEXTURE_GEN_R:
1519 case GL_TEXTURE_GEN_Q:
1520 case GL_TEXTURE_RECTANGLE_ARB: {
1521 GLboolean state;
1522 const GLuint curTexUnitSave = ctx->Texture.CurrentUnit;
1523 if (index >= MAX2(ctx->Const.MaxCombinedTextureImageUnits,
1524 ctx->Const.MaxTextureCoordUnits)) {
1525 _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
1526 index);
1527 return GL_FALSE;
1528 }
1529 _mesa_ActiveTexture(GL_TEXTURE0 + index);
1530 state = _mesa_IsEnabled(cap);
1531 _mesa_ActiveTexture(GL_TEXTURE0 + curTexUnitSave);
1532 return state;
1533 }
1534 default:
1535 _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
1536 _mesa_enum_to_string(cap));
1537 return GL_FALSE;
1538 }
1539 }
1540
1541
1542
1543 /**
1544 * Helper function to determine whether a texture target is enabled.
1545 */
1546 static GLboolean
is_texture_enabled(struct gl_context * ctx,GLbitfield bit)1547 is_texture_enabled(struct gl_context *ctx, GLbitfield bit)
1548 {
1549 const struct gl_fixedfunc_texture_unit *const texUnit =
1550 _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
1551
1552 if (!texUnit)
1553 return GL_FALSE;
1554
1555 return (texUnit->Enabled & bit) ? GL_TRUE : GL_FALSE;
1556 }
1557
1558
1559 /**
1560 * Return simple enable/disable state.
1561 *
1562 * \param cap state variable to query.
1563 *
1564 * Returns the state of the specified capability from the current GL context.
1565 * For the capabilities associated with extensions verifies that those
1566 * extensions are effectively present before reporting.
1567 */
1568 GLboolean GLAPIENTRY
_mesa_IsEnabled(GLenum cap)1569 _mesa_IsEnabled( GLenum cap )
1570 {
1571 GET_CURRENT_CONTEXT(ctx);
1572 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
1573
1574 switch (cap) {
1575 case GL_ALPHA_TEST:
1576 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1577 goto invalid_enum_error;
1578 return ctx->Color.AlphaEnabled;
1579 case GL_AUTO_NORMAL:
1580 if (ctx->API != API_OPENGL_COMPAT)
1581 goto invalid_enum_error;
1582 return ctx->Eval.AutoNormal;
1583 case GL_BLEND:
1584 return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */
1585 case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */
1586 case GL_CLIP_DISTANCE1:
1587 case GL_CLIP_DISTANCE2:
1588 case GL_CLIP_DISTANCE3:
1589 case GL_CLIP_DISTANCE4:
1590 case GL_CLIP_DISTANCE5:
1591 case GL_CLIP_DISTANCE6:
1592 case GL_CLIP_DISTANCE7: {
1593 const GLuint p = cap - GL_CLIP_DISTANCE0;
1594
1595 if (p >= ctx->Const.MaxClipPlanes)
1596 goto invalid_enum_error;
1597
1598 return (ctx->Transform.ClipPlanesEnabled >> p) & 1;
1599 }
1600 case GL_COLOR_MATERIAL:
1601 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1602 goto invalid_enum_error;
1603 return ctx->Light.ColorMaterialEnabled;
1604 case GL_CULL_FACE:
1605 return ctx->Polygon.CullFlag;
1606 case GL_DEBUG_OUTPUT:
1607 case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
1608 return (GLboolean) _mesa_get_debug_state_int(ctx, cap);
1609 case GL_DEPTH_TEST:
1610 return ctx->Depth.Test;
1611 case GL_DITHER:
1612 return ctx->Color.DitherFlag;
1613 case GL_FOG:
1614 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1615 goto invalid_enum_error;
1616 return ctx->Fog.Enabled;
1617 case GL_LIGHTING:
1618 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1619 goto invalid_enum_error;
1620 return ctx->Light.Enabled;
1621 case GL_LIGHT0:
1622 case GL_LIGHT1:
1623 case GL_LIGHT2:
1624 case GL_LIGHT3:
1625 case GL_LIGHT4:
1626 case GL_LIGHT5:
1627 case GL_LIGHT6:
1628 case GL_LIGHT7:
1629 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1630 goto invalid_enum_error;
1631 return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
1632 case GL_LINE_SMOOTH:
1633 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1634 goto invalid_enum_error;
1635 return ctx->Line.SmoothFlag;
1636 case GL_LINE_STIPPLE:
1637 if (ctx->API != API_OPENGL_COMPAT)
1638 goto invalid_enum_error;
1639 return ctx->Line.StippleFlag;
1640 case GL_INDEX_LOGIC_OP:
1641 if (ctx->API != API_OPENGL_COMPAT)
1642 goto invalid_enum_error;
1643 return ctx->Color.IndexLogicOpEnabled;
1644 case GL_COLOR_LOGIC_OP:
1645 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1646 goto invalid_enum_error;
1647 return ctx->Color.ColorLogicOpEnabled;
1648 case GL_MAP1_COLOR_4:
1649 if (ctx->API != API_OPENGL_COMPAT)
1650 goto invalid_enum_error;
1651 return ctx->Eval.Map1Color4;
1652 case GL_MAP1_INDEX:
1653 if (ctx->API != API_OPENGL_COMPAT)
1654 goto invalid_enum_error;
1655 return ctx->Eval.Map1Index;
1656 case GL_MAP1_NORMAL:
1657 if (ctx->API != API_OPENGL_COMPAT)
1658 goto invalid_enum_error;
1659 return ctx->Eval.Map1Normal;
1660 case GL_MAP1_TEXTURE_COORD_1:
1661 if (ctx->API != API_OPENGL_COMPAT)
1662 goto invalid_enum_error;
1663 return ctx->Eval.Map1TextureCoord1;
1664 case GL_MAP1_TEXTURE_COORD_2:
1665 if (ctx->API != API_OPENGL_COMPAT)
1666 goto invalid_enum_error;
1667 return ctx->Eval.Map1TextureCoord2;
1668 case GL_MAP1_TEXTURE_COORD_3:
1669 if (ctx->API != API_OPENGL_COMPAT)
1670 goto invalid_enum_error;
1671 return ctx->Eval.Map1TextureCoord3;
1672 case GL_MAP1_TEXTURE_COORD_4:
1673 if (ctx->API != API_OPENGL_COMPAT)
1674 goto invalid_enum_error;
1675 return ctx->Eval.Map1TextureCoord4;
1676 case GL_MAP1_VERTEX_3:
1677 if (ctx->API != API_OPENGL_COMPAT)
1678 goto invalid_enum_error;
1679 return ctx->Eval.Map1Vertex3;
1680 case GL_MAP1_VERTEX_4:
1681 if (ctx->API != API_OPENGL_COMPAT)
1682 goto invalid_enum_error;
1683 return ctx->Eval.Map1Vertex4;
1684 case GL_MAP2_COLOR_4:
1685 if (ctx->API != API_OPENGL_COMPAT)
1686 goto invalid_enum_error;
1687 return ctx->Eval.Map2Color4;
1688 case GL_MAP2_INDEX:
1689 if (ctx->API != API_OPENGL_COMPAT)
1690 goto invalid_enum_error;
1691 return ctx->Eval.Map2Index;
1692 case GL_MAP2_NORMAL:
1693 if (ctx->API != API_OPENGL_COMPAT)
1694 goto invalid_enum_error;
1695 return ctx->Eval.Map2Normal;
1696 case GL_MAP2_TEXTURE_COORD_1:
1697 if (ctx->API != API_OPENGL_COMPAT)
1698 goto invalid_enum_error;
1699 return ctx->Eval.Map2TextureCoord1;
1700 case GL_MAP2_TEXTURE_COORD_2:
1701 if (ctx->API != API_OPENGL_COMPAT)
1702 goto invalid_enum_error;
1703 return ctx->Eval.Map2TextureCoord2;
1704 case GL_MAP2_TEXTURE_COORD_3:
1705 if (ctx->API != API_OPENGL_COMPAT)
1706 goto invalid_enum_error;
1707 return ctx->Eval.Map2TextureCoord3;
1708 case GL_MAP2_TEXTURE_COORD_4:
1709 if (ctx->API != API_OPENGL_COMPAT)
1710 goto invalid_enum_error;
1711 return ctx->Eval.Map2TextureCoord4;
1712 case GL_MAP2_VERTEX_3:
1713 if (ctx->API != API_OPENGL_COMPAT)
1714 goto invalid_enum_error;
1715 return ctx->Eval.Map2Vertex3;
1716 case GL_MAP2_VERTEX_4:
1717 if (ctx->API != API_OPENGL_COMPAT)
1718 goto invalid_enum_error;
1719 return ctx->Eval.Map2Vertex4;
1720 case GL_NORMALIZE:
1721 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1722 goto invalid_enum_error;
1723 return ctx->Transform.Normalize;
1724 case GL_POINT_SMOOTH:
1725 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1726 goto invalid_enum_error;
1727 return ctx->Point.SmoothFlag;
1728 case GL_POLYGON_SMOOTH:
1729 if (!_mesa_is_desktop_gl(ctx))
1730 goto invalid_enum_error;
1731 return ctx->Polygon.SmoothFlag;
1732 case GL_POLYGON_STIPPLE:
1733 if (ctx->API != API_OPENGL_COMPAT)
1734 goto invalid_enum_error;
1735 return ctx->Polygon.StippleFlag;
1736 case GL_POLYGON_OFFSET_POINT:
1737 if (!_mesa_is_desktop_gl(ctx))
1738 goto invalid_enum_error;
1739 return ctx->Polygon.OffsetPoint;
1740 case GL_POLYGON_OFFSET_LINE:
1741 if (!_mesa_is_desktop_gl(ctx))
1742 goto invalid_enum_error;
1743 return ctx->Polygon.OffsetLine;
1744 case GL_POLYGON_OFFSET_FILL:
1745 return ctx->Polygon.OffsetFill;
1746 case GL_RESCALE_NORMAL_EXT:
1747 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1748 goto invalid_enum_error;
1749 return ctx->Transform.RescaleNormals;
1750 case GL_SCISSOR_TEST:
1751 return ctx->Scissor.EnableFlags & 1; /* return state for index 0 */
1752 case GL_STENCIL_TEST:
1753 return ctx->Stencil.Enabled;
1754 case GL_TEXTURE_1D:
1755 if (ctx->API != API_OPENGL_COMPAT)
1756 goto invalid_enum_error;
1757 return is_texture_enabled(ctx, TEXTURE_1D_BIT);
1758 case GL_TEXTURE_2D:
1759 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1760 goto invalid_enum_error;
1761 return is_texture_enabled(ctx, TEXTURE_2D_BIT);
1762 case GL_TEXTURE_3D:
1763 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1764 goto invalid_enum_error;
1765 return is_texture_enabled(ctx, TEXTURE_3D_BIT);
1766 case GL_TEXTURE_GEN_S:
1767 case GL_TEXTURE_GEN_T:
1768 case GL_TEXTURE_GEN_R:
1769 case GL_TEXTURE_GEN_Q:
1770 {
1771 const struct gl_fixedfunc_texture_unit *texUnit =
1772 get_texcoord_unit(ctx);
1773
1774 if (ctx->API != API_OPENGL_COMPAT)
1775 goto invalid_enum_error;
1776
1777 if (texUnit) {
1778 GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S);
1779 return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE;
1780 }
1781 }
1782 return GL_FALSE;
1783 case GL_TEXTURE_GEN_STR_OES:
1784 {
1785 const struct gl_fixedfunc_texture_unit *texUnit =
1786 get_texcoord_unit(ctx);
1787
1788 if (ctx->API != API_OPENGLES)
1789 goto invalid_enum_error;
1790
1791 if (texUnit) {
1792 return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS
1793 ? GL_TRUE : GL_FALSE;
1794 }
1795
1796 return GL_FALSE;
1797 }
1798
1799 /* client-side state */
1800 case GL_VERTEX_ARRAY:
1801 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1802 goto invalid_enum_error;
1803 return !!(ctx->Array.VAO->Enabled & VERT_BIT_POS);
1804 case GL_NORMAL_ARRAY:
1805 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1806 goto invalid_enum_error;
1807 return !!(ctx->Array.VAO->Enabled & VERT_BIT_NORMAL);
1808 case GL_COLOR_ARRAY:
1809 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1810 goto invalid_enum_error;
1811 return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR0);
1812 case GL_INDEX_ARRAY:
1813 if (ctx->API != API_OPENGL_COMPAT)
1814 goto invalid_enum_error;
1815 return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR_INDEX);
1816 case GL_TEXTURE_COORD_ARRAY:
1817 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1818 goto invalid_enum_error;
1819 return !!(ctx->Array.VAO->Enabled &
1820 VERT_BIT_TEX(ctx->Array.ActiveTexture));
1821 case GL_EDGE_FLAG_ARRAY:
1822 if (ctx->API != API_OPENGL_COMPAT)
1823 goto invalid_enum_error;
1824 return !!(ctx->Array.VAO->Enabled & VERT_BIT_EDGEFLAG);
1825 case GL_FOG_COORDINATE_ARRAY_EXT:
1826 if (ctx->API != API_OPENGL_COMPAT)
1827 goto invalid_enum_error;
1828 return !!(ctx->Array.VAO->Enabled & VERT_BIT_FOG);
1829 case GL_SECONDARY_COLOR_ARRAY_EXT:
1830 if (ctx->API != API_OPENGL_COMPAT)
1831 goto invalid_enum_error;
1832 return !!(ctx->Array.VAO->Enabled & VERT_BIT_COLOR1);
1833 case GL_POINT_SIZE_ARRAY_OES:
1834 if (ctx->API != API_OPENGLES)
1835 goto invalid_enum_error;
1836 return !!(ctx->Array.VAO->Enabled & VERT_BIT_POINT_SIZE);
1837
1838 /* GL_ARB_texture_cube_map */
1839 case GL_TEXTURE_CUBE_MAP:
1840 if (!_mesa_has_ARB_texture_cube_map(ctx) &&
1841 !_mesa_has_OES_texture_cube_map(ctx))
1842 goto invalid_enum_error;
1843 return is_texture_enabled(ctx, TEXTURE_CUBE_BIT);
1844
1845 /* GL_EXT_secondary_color */
1846 case GL_COLOR_SUM_EXT:
1847 if (ctx->API != API_OPENGL_COMPAT)
1848 goto invalid_enum_error;
1849 return ctx->Fog.ColorSumEnabled;
1850
1851 /* GL_ARB_multisample */
1852 case GL_MULTISAMPLE_ARB:
1853 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1854 goto invalid_enum_error;
1855 return ctx->Multisample.Enabled;
1856 case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
1857 return ctx->Multisample.SampleAlphaToCoverage;
1858 case GL_SAMPLE_ALPHA_TO_ONE_ARB:
1859 if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
1860 goto invalid_enum_error;
1861 return ctx->Multisample.SampleAlphaToOne;
1862 case GL_SAMPLE_COVERAGE_ARB:
1863 return ctx->Multisample.SampleCoverage;
1864 case GL_SAMPLE_COVERAGE_INVERT_ARB:
1865 if (!_mesa_is_desktop_gl(ctx))
1866 goto invalid_enum_error;
1867 return ctx->Multisample.SampleCoverageInvert;
1868
1869 /* GL_IBM_rasterpos_clip */
1870 case GL_RASTER_POSITION_UNCLIPPED_IBM:
1871 if (ctx->API != API_OPENGL_COMPAT)
1872 goto invalid_enum_error;
1873 return ctx->Transform.RasterPositionUnclipped;
1874
1875 /* GL_ARB_point_sprite */
1876 case GL_POINT_SPRITE:
1877 if (!(ctx->API == API_OPENGL_COMPAT &&
1878 _mesa_has_ARB_point_sprite(ctx)) &&
1879 !_mesa_has_OES_point_sprite(ctx))
1880 goto invalid_enum_error;
1881 return ctx->Point.PointSprite;
1882
1883 case GL_VERTEX_PROGRAM_ARB:
1884 if (!_mesa_has_ARB_vertex_program(ctx))
1885 goto invalid_enum_error;
1886 return ctx->VertexProgram.Enabled;
1887 case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
1888 /* This was added with ARB_vertex_program, but it is also used with
1889 * GLSL vertex shaders on desktop.
1890 */
1891 if (!_mesa_has_ARB_vertex_program(ctx) &&
1892 ctx->API != API_OPENGL_CORE)
1893 goto invalid_enum_error;
1894 return ctx->VertexProgram.PointSizeEnabled;
1895 case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
1896 if (!_mesa_has_ARB_vertex_program(ctx))
1897 goto invalid_enum_error;
1898 return ctx->VertexProgram.TwoSideEnabled;
1899
1900 /* GL_NV_texture_rectangle */
1901 case GL_TEXTURE_RECTANGLE_NV:
1902 if (!_mesa_has_NV_texture_rectangle(ctx))
1903 goto invalid_enum_error;
1904 return is_texture_enabled(ctx, TEXTURE_RECT_BIT);
1905
1906 /* GL_EXT_stencil_two_side */
1907 case GL_STENCIL_TEST_TWO_SIDE_EXT:
1908 if (!_mesa_has_EXT_stencil_two_side(ctx))
1909 goto invalid_enum_error;
1910 return ctx->Stencil.TestTwoSide;
1911
1912 case GL_FRAGMENT_PROGRAM_ARB:
1913 if (!_mesa_has_ARB_fragment_program(ctx))
1914 goto invalid_enum_error;
1915 return ctx->FragmentProgram.Enabled;
1916
1917 /* GL_EXT_depth_bounds_test */
1918 case GL_DEPTH_BOUNDS_TEST_EXT:
1919 if (!_mesa_has_EXT_depth_bounds_test(ctx))
1920 goto invalid_enum_error;
1921 return ctx->Depth.BoundsTest;
1922
1923 /* GL_ARB_depth_clamp */
1924 case GL_DEPTH_CLAMP:
1925 if (!_mesa_has_ARB_depth_clamp(ctx) &&
1926 !_mesa_has_EXT_depth_clamp(ctx))
1927 goto invalid_enum_error;
1928 return ctx->Transform.DepthClampNear ||
1929 ctx->Transform.DepthClampFar;
1930
1931 case GL_DEPTH_CLAMP_NEAR_AMD:
1932 if (!_mesa_has_AMD_depth_clamp_separate(ctx))
1933 goto invalid_enum_error;
1934 return ctx->Transform.DepthClampNear;
1935
1936 case GL_DEPTH_CLAMP_FAR_AMD:
1937 if (!_mesa_has_AMD_depth_clamp_separate(ctx))
1938 goto invalid_enum_error;
1939 return ctx->Transform.DepthClampFar;
1940
1941 case GL_FRAGMENT_SHADER_ATI:
1942 if (!_mesa_has_ATI_fragment_shader(ctx))
1943 goto invalid_enum_error;
1944 return ctx->ATIFragmentShader.Enabled;
1945
1946 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1947 if (!_mesa_has_ARB_seamless_cube_map(ctx))
1948 goto invalid_enum_error;
1949 return ctx->Texture.CubeMapSeamless;
1950
1951 case GL_RASTERIZER_DISCARD:
1952 if (!(_mesa_has_EXT_transform_feedback(ctx) || _mesa_is_gles3(ctx)))
1953 goto invalid_enum_error;
1954 return ctx->RasterDiscard;
1955
1956 /* GL_NV_primitive_restart */
1957 case GL_PRIMITIVE_RESTART_NV:
1958 if (!_mesa_has_NV_primitive_restart(ctx))
1959 goto invalid_enum_error;
1960 return ctx->Array.PrimitiveRestart;
1961
1962 /* GL 3.1 primitive restart */
1963 case GL_PRIMITIVE_RESTART:
1964 if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 31) {
1965 goto invalid_enum_error;
1966 }
1967 return ctx->Array.PrimitiveRestart;
1968
1969 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1970 if (!_mesa_is_gles3(ctx) && !_mesa_has_ARB_ES3_compatibility(ctx))
1971 goto invalid_enum_error;
1972 return ctx->Array.PrimitiveRestartFixedIndex;
1973
1974 /* GL3.0 - GL_framebuffer_sRGB */
1975 case GL_FRAMEBUFFER_SRGB_EXT:
1976 if (!_mesa_has_EXT_framebuffer_sRGB(ctx) &&
1977 !_mesa_has_EXT_sRGB_write_control(ctx))
1978 goto invalid_enum_error;
1979 return ctx->Color.sRGBEnabled;
1980
1981 /* GL_OES_EGL_image_external */
1982 case GL_TEXTURE_EXTERNAL_OES:
1983 if (!_mesa_has_OES_EGL_image_external(ctx))
1984 goto invalid_enum_error;
1985 return is_texture_enabled(ctx, TEXTURE_EXTERNAL_BIT);
1986
1987 /* ARB_texture_multisample */
1988 case GL_SAMPLE_MASK:
1989 if (!_mesa_has_ARB_texture_multisample(ctx) && !_mesa_is_gles31(ctx))
1990 goto invalid_enum_error;
1991 return ctx->Multisample.SampleMask;
1992
1993 /* ARB_sample_shading */
1994 case GL_SAMPLE_SHADING:
1995 if (!_mesa_has_ARB_sample_shading(ctx) && !_mesa_is_gles3(ctx))
1996 goto invalid_enum_error;
1997 return ctx->Multisample.SampleShading;
1998
1999 case GL_BLEND_ADVANCED_COHERENT_KHR:
2000 if (!_mesa_has_KHR_blend_equation_advanced_coherent(ctx))
2001 goto invalid_enum_error;
2002 return ctx->Color.BlendCoherent;
2003
2004 case GL_CONSERVATIVE_RASTERIZATION_INTEL:
2005 if (!_mesa_has_INTEL_conservative_rasterization(ctx))
2006 goto invalid_enum_error;
2007 return ctx->IntelConservativeRasterization;
2008
2009 case GL_CONSERVATIVE_RASTERIZATION_NV:
2010 if (!_mesa_has_NV_conservative_raster(ctx))
2011 goto invalid_enum_error;
2012 return ctx->ConservativeRasterization;
2013
2014 case GL_TILE_RASTER_ORDER_FIXED_MESA:
2015 if (!_mesa_has_MESA_tile_raster_order(ctx))
2016 goto invalid_enum_error;
2017 return ctx->TileRasterOrderFixed;
2018
2019 case GL_TILE_RASTER_ORDER_INCREASING_X_MESA:
2020 if (!_mesa_has_MESA_tile_raster_order(ctx))
2021 goto invalid_enum_error;
2022 return ctx->TileRasterOrderIncreasingX;
2023
2024 case GL_TILE_RASTER_ORDER_INCREASING_Y_MESA:
2025 if (!_mesa_has_MESA_tile_raster_order(ctx))
2026 goto invalid_enum_error;
2027 return ctx->TileRasterOrderIncreasingY;
2028
2029 case GL_BLACKHOLE_RENDER_INTEL:
2030 if (!_mesa_has_INTEL_blackhole_render(ctx))
2031 goto invalid_enum_error;
2032 return ctx->IntelBlackholeRender;
2033
2034 default:
2035 goto invalid_enum_error;
2036 }
2037
2038 return GL_FALSE;
2039
2040 invalid_enum_error:
2041 _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(%s)",
2042 _mesa_enum_to_string(cap));
2043 return GL_FALSE;
2044 }
2045