mesa: per-buffer blend enabled flags
authorBrian Paul <brianp@vmware.com>
Tue, 29 Dec 2009 22:04:03 +0000 (15:04 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 29 Dec 2009 22:04:03 +0000 (15:04 -0700)
ctx->Color.BlendEnabled is now a GLbitfield instead of a GLboolean to
indicate blend on/off status for each color/draw buffer.

This is infrastructure for GL_EXT_draw_buffers2 and OpenGL 3.x

New functions include _mesa_EnableIndexed(), _mesa_DisableIndexed(), and
_mesa_IsEnabledIndexed().  The enable function corresponds to
glEnableIndexedEXT() for GL_EXT_draw_buffers2 or glEnablei() for GL3.

Note that there's quite a few tests for ctx->Color.BlendEnabled != 0 in
drivers, etc.  Those tests can remain as-is since the mask will be 0 or ~0
unless GL_EXT_draw_buffers2 is enabled.

src/mesa/drivers/common/meta.c
src/mesa/main/attrib.c
src/mesa/main/blend.c
src/mesa/main/enable.c
src/mesa/main/enable.h
src/mesa/main/get.c
src/mesa/main/get_gen.py
src/mesa/main/mtypes.h
src/mesa/swrast/s_span.c

index cd9075b39367d75655109e5c15ab0ce8fa6a10ab..da2c06677a6fd4df3f4ef756eb9266342ba16a6e 100644 (file)
@@ -107,7 +107,7 @@ struct save_state
    GLboolean AlphaEnabled;
 
    /** META_BLEND */
-   GLboolean BlendEnabled;
+   GLbitfield BlendEnabled;
    GLboolean ColorLogicOpEnabled;
 
    /** META_COLOR_MASK */
@@ -335,8 +335,12 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
 
    if (state & META_BLEND) {
       save->BlendEnabled = ctx->Color.BlendEnabled;
-      if (ctx->Color.BlendEnabled)
-         _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
+      if (ctx->Color.BlendEnabled) {
+         GLuint i;
+         for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+            _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
+         }
+      }
       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
       if (ctx->Color.ColorLogicOpEnabled)
          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
@@ -566,8 +570,12 @@ _mesa_meta_end(GLcontext *ctx)
    }
 
    if (state & META_BLEND) {
-      if (ctx->Color.BlendEnabled != save->BlendEnabled)
-         _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
+      if (ctx->Color.BlendEnabled != save->BlendEnabled) {
+         GLuint i;
+         for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+            _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
+         }
+      }
       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
    }
index 246c5521b7d9c83b8278deaa25a06223058049a4..88ce0a4281b85e4c81efbb5b1aaa26ef452760d2 100644 (file)
@@ -499,7 +499,12 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
        }
 
    TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
-   TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
+   if (ctx->Color.BlendEnabled != enable->Blend) {
+      GLuint i;
+      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+         _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1);
+      }
+   }
 
    for (i=0;i<MAX_CLIP_PLANES;i++) {
       const GLuint mask = 1 << i;
@@ -906,6 +911,7 @@ _mesa_PopAttrib(void)
          case GL_COLOR_BUFFER_BIT:
             {
                const struct gl_colorbuffer_attrib *color;
+
                color = (const struct gl_colorbuffer_attrib *) attr->data;
                _mesa_ClearIndex((GLfloat) color->ClearIndex);
                _mesa_ClearColor(color->ClearColor[0],
@@ -948,7 +954,13 @@ _mesa_PopAttrib(void)
                }
                _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
                _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
-               _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
+               if (ctx->Color.BlendEnabled != color->BlendEnabled) {
+                  GLuint i;
+                  for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+                     _mesa_set_enablei(ctx, GL_BLEND, i,
+                                       (color->BlendEnabled >> i) & 1);
+                  }
+               }
                _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
                                           color->BlendDstRGB,
                                           color->BlendSrcA,
index 830e3b2e517c0c27e352e4a653a1cbf0cfeefaad..5a9d94e12d01d7a6f8fe725119a25040e47b20a0 100644 (file)
@@ -564,7 +564,7 @@ void _mesa_init_color( GLcontext * ctx )
    ctx->Color.AlphaEnabled = GL_FALSE;
    ctx->Color.AlphaFunc = GL_ALWAYS;
    ctx->Color.AlphaRef = 0;
-   ctx->Color.BlendEnabled = GL_FALSE;
+   ctx->Color.BlendEnabled = 0x0;
    ctx->Color.BlendSrcRGB = GL_ONE;
    ctx->Color.BlendDstRGB = GL_ZERO;
    ctx->Color.BlendSrcA = GL_ONE;
index 12ce14c5d04e2b6ac5eb6f89e585a2e04ef05c55..6f9f57f5cb88a75d7445a714daa5f3e7a050fb39 100644 (file)
@@ -278,10 +278,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:
@@ -1020,6 +1023,77 @@ _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 (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:
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
+                  state ? "glEnableIndexed" : "glDisableIndexed",
+                  _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) {                     \
@@ -1066,7 +1140,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:
index 25c90b0275ad750f74c20d46a3195c01a577dc0d..24e3181a8bae8cb6b1480e21639ba519ed8fc68d 100644 (file)
@@ -47,6 +47,18 @@ _mesa_Enable( GLenum cap );
 extern GLboolean GLAPIENTRY
 _mesa_IsEnabled( GLenum cap );
 
+extern void
+_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state);
+
+extern void GLAPIENTRY
+_mesa_DisableIndexed( GLenum cap, GLuint index );
+
+extern void GLAPIENTRY
+_mesa_EnableIndexed( GLenum cap, GLuint index );
+
+extern GLboolean GLAPIENTRY
+_mesa_IsEnabledIndexed( GLenum cap, GLuint index );
+
 extern void GLAPIENTRY
 _mesa_EnableClientState( GLenum cap );
 
index 3d32649bade8ad52bf9e845ca55208e5ddfd2d09..07507414d7049581a213509f0d9e9a00017e4e07 100644 (file)
@@ -132,7 +132,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = ctx->Color.BlendEnabled;
+         params[0] = (ctx->Color.BlendEnabled & 1);
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB);
@@ -1967,7 +1967,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_FLOAT((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
@@ -3802,7 +3802,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          params[0] = ctx->DrawBuffer->Visual.numAuxBuffers;
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_INT((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB);
@@ -5638,7 +5638,7 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_INT64(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_INT64((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_INT64(ctx->Color.BlendDstRGB);
index 01170a42a72d0782b14395ee937cb1b08ad202d5..5aff9d3544e39220d3e437c590876750b83c6c6e 100644 (file)
@@ -82,7 +82,7 @@ StateVars = [
        ( "GL_AUTO_NORMAL", GLboolean, ["ctx->Eval.AutoNormal"], "", None ),
        ( "GL_AUX_BUFFERS", GLint, ["ctx->DrawBuffer->Visual.numAuxBuffers"],
          "", None ),
-       ( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ),
+       ( "GL_BLEND", GLboolean, ["(ctx->Color.BlendEnabled & 1)"], "", None ),
        ( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ),
        ( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ),
        ( "GL_BLEND_SRC_RGB_EXT", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ),
index b52c84b491a11e772027c344c32b58d4909d51a7..170c35b11c615c212351e487e9d787d265f068e1 100644 (file)
@@ -581,7 +581,7 @@ struct gl_colorbuffer_attrib
     * \name Blending
     */
    /*@{*/
-   GLboolean BlendEnabled;             /**< Blending enabled flag */
+   GLbitfield BlendEnabled;            /**< Per-buffer blend enable flags */
    GLenum BlendSrcRGB;                 /**< Blending source operator */
    GLenum BlendDstRGB;                 /**< Blending destination operator */
    GLenum BlendSrcA;                   /**< GL_INGR_blend_func_separate */
index d36c8132f639066da3c3cabb92644a785aa43e23..00de13d4954855d49b91aad21b7d3de04b5ba8b3 100644 (file)
@@ -1479,7 +1479,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
             if (ctx->Color._LogicOpEnabled) {
                _swrast_logicop_rgba_span(ctx, rb, span);
             }
-            else if (ctx->Color.BlendEnabled) {
+            else if ((ctx->Color.BlendEnabled >> buf) & 1) {
                _swrast_blend_span(ctx, rb, span);
             }