Merge remote branch 'origin/7.8'
[mesa.git] / src / mesa / main / enable.c
index 4c1f46102d1c86592f982d2202eaeb89723790d5..f9decc31ab75e3b3ffa36d4413e623ef38d64054 100644 (file)
 #include "context.h"
 #include "enable.h"
 #include "light.h"
-#include "macros.h"
 #include "simple_list.h"
 #include "mtypes.h"
 #include "enums.h"
 #include "api_arrayelt.h"
+#include "texstate.h"
 
 
 
 static void
 client_state(GLcontext *ctx, GLenum cap, GLboolean state)
 {
+   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
    GLuint flag;
    GLboolean *var;
 
    switch (cap) {
       case GL_VERTEX_ARRAY:
-         var = &ctx->Array.ArrayObj->Vertex.Enabled;
+         var = &arrayObj->Vertex.Enabled;
          flag = _NEW_ARRAY_VERTEX;
          break;
       case GL_NORMAL_ARRAY:
-         var = &ctx->Array.ArrayObj->Normal.Enabled;
+         var = &arrayObj->Normal.Enabled;
          flag = _NEW_ARRAY_NORMAL;
          break;
       case GL_COLOR_ARRAY:
-         var = &ctx->Array.ArrayObj->Color.Enabled;
+         var = &arrayObj->Color.Enabled;
          flag = _NEW_ARRAY_COLOR0;
          break;
       case GL_INDEX_ARRAY:
-         var = &ctx->Array.ArrayObj->Index.Enabled;
+         var = &arrayObj->Index.Enabled;
          flag = _NEW_ARRAY_INDEX;
          break;
       case GL_TEXTURE_COORD_ARRAY:
-         var = &ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled;
+         var = &arrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled;
          flag = _NEW_ARRAY_TEXCOORD(ctx->Array.ActiveTexture);
          break;
       case GL_EDGE_FLAG_ARRAY:
-         var = &ctx->Array.ArrayObj->EdgeFlag.Enabled;
+         var = &arrayObj->EdgeFlag.Enabled;
          flag = _NEW_ARRAY_EDGEFLAG;
          break;
       case GL_FOG_COORDINATE_ARRAY_EXT:
-         var = &ctx->Array.ArrayObj->FogCoord.Enabled;
+         var = &arrayObj->FogCoord.Enabled;
          flag = _NEW_ARRAY_FOGCOORD;
          break;
       case GL_SECONDARY_COLOR_ARRAY_EXT:
-         var = &ctx->Array.ArrayObj->SecondaryColor.Enabled;
+         var = &arrayObj->SecondaryColor.Enabled;
          flag = _NEW_ARRAY_COLOR1;
          break;
 
 #if FEATURE_point_size_array
       case GL_POINT_SIZE_ARRAY_OES:
-         var = &ctx->Array.ArrayObj->PointSize.Enabled;
+         var = &arrayObj->PointSize.Enabled;
          flag = _NEW_ARRAY_POINT_SIZE;
          break;
 #endif
@@ -119,7 +120,7 @@ client_state(GLcontext *ctx, GLenum cap, GLboolean state)
          {
             GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
             ASSERT(n < Elements(ctx->Array.ArrayObj->VertexAttrib));
-            var = &ctx->Array.ArrayObj->VertexAttrib[n].Enabled;
+            var = &arrayObj->VertexAttrib[n].Enabled;
             flag = _NEW_ARRAY_ATTRIB(n);
          }
          break;
@@ -228,12 +229,11 @@ get_texcoord_unit(GLcontext *ctx)
 static GLboolean
 enable_texture(GLcontext *ctx, GLboolean state, GLbitfield texBit)
 {
-   const GLuint curr = ctx->Texture.CurrentUnit;
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
    const GLbitfield newenabled = state
       ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
 
-   if (!ctx->DrawBuffer->Visual.rgbMode || texUnit->Enabled == newenabled)
+   if (texUnit->Enabled == newenabled)
        return GL_FALSE;
 
    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -277,10 +277,13 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
          ctx->Eval.AutoNormal = state;
          break;
       case GL_BLEND:
-         if (ctx->Color.BlendEnabled == state)
-            return;
-         FLUSH_VERTICES(ctx, _NEW_COLOR);
-         ctx->Color.BlendEnabled = state;
+         {
+            GLbitfield newEnabled = state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
+            if (newEnabled != ctx->Color.BlendEnabled) {
+               FLUSH_VERTICES(ctx, _NEW_COLOR);
+               ctx->Color.BlendEnabled = newEnabled;
+            }
+         }
          break;
 #if FEATURE_userclip
       case GL_CLIP_PLANE0:
@@ -935,11 +938,6 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
       /* GL_EXT_depth_bounds_test */
       case GL_DEPTH_BOUNDS_TEST_EXT:
          CHECK_EXTENSION(EXT_depth_bounds_test, cap);
-         if (state && ctx->DrawBuffer->Visual.depthBits == 0) {
-            _mesa_warning(ctx,
-                   "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer");
-            return;
-         }
          if (ctx->Depth.BoundsTest == state)
             return;
          FLUSH_VERTICES(ctx, _NEW_DEPTH);
@@ -984,6 +982,16 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
         ctx->Texture.CubeMapSeamless = state;
         break;
 
+#if FEATURE_EXT_transform_feedback
+      case GL_RASTERIZER_DISCARD:
+        CHECK_EXTENSION(EXT_transform_feedback, cap);
+         if (ctx->TransformFeedback.RasterDiscard != state) {
+            ctx->TransformFeedback.RasterDiscard = state;
+            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+         }
+         break;
+#endif
+
       default:
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "%s(0x%x)", state ? "glEnable" : "glDisable", cap);
@@ -1024,6 +1032,84 @@ _mesa_Disable( GLenum cap )
 }
 
 
+
+/**
+ * Enable/disable an indexed state var.
+ */
+void
+_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state)
+{
+   ASSERT(state == 0 || state == 1);
+   switch (cap) {
+   case GL_BLEND:
+      if (!ctx->Extensions.EXT_draw_buffers2) {
+         goto bad_cap_error;
+      }
+      if (index >= ctx->Const.MaxDrawBuffers) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
+                     state ? "glEnableIndexed" : "glDisableIndexed", index);
+         return;
+      }
+      if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
+         FLUSH_VERTICES(ctx, _NEW_COLOR);
+         if (state)
+            ctx->Color.BlendEnabled |= (1 << index);
+         else
+            ctx->Color.BlendEnabled &= ~(1 << index);
+      }
+      break;
+   default:
+      goto bad_cap_error;
+   }
+   return;
+
+bad_cap_error:
+    _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
+                state ? "glEnablei" : "glDisablei",
+                _mesa_lookup_enum_by_nr(cap));
+}
+
+
+void GLAPIENTRY
+_mesa_DisableIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+   _mesa_set_enablei(ctx, cap, index, GL_FALSE);
+}
+
+
+void GLAPIENTRY
+_mesa_EnableIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+   _mesa_set_enablei(ctx, cap, index, GL_TRUE);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsEnabledIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   switch (cap) {
+   case GL_BLEND:
+      if (index >= ctx->Const.MaxDrawBuffers) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
+                     index);
+         return GL_FALSE;
+      }
+      return (ctx->Color.BlendEnabled >> index) & 1;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
+                  _mesa_lookup_enum_by_nr(cap));
+      return GL_FALSE;
+   }
+}
+
+
+
+
 #undef CHECK_EXTENSION
 #define CHECK_EXTENSION(EXTNAME)                       \
    if (!ctx->Extensions.EXTNAME) {                     \
@@ -1070,7 +1156,7 @@ _mesa_IsEnabled( GLenum cap )
       case GL_AUTO_NORMAL:
         return ctx->Eval.AutoNormal;
       case GL_BLEND:
-         return ctx->Color.BlendEnabled;
+         return ctx->Color.BlendEnabled & 1;  /* return state for buffer[0] */
       case GL_CLIP_PLANE0:
       case GL_CLIP_PLANE1:
       case GL_CLIP_PLANE2:
@@ -1417,6 +1503,12 @@ _mesa_IsEnabled( GLenum cap )
         CHECK_EXTENSION(ARB_seamless_cube_map);
         return ctx->Texture.CubeMapSeamless;
 
+#if FEATURE_EXT_transform_feedback
+      case GL_RASTERIZER_DISCARD:
+        CHECK_EXTENSION(EXT_transform_feedback);
+         return ctx->TransformFeedback.RasterDiscard;
+#endif
+
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap);
         return GL_FALSE;