mesa: Track the current advanced blending mode.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 28 Jun 2016 15:17:57 +0000 (08:17 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 26 Aug 2016 02:22:09 +0000 (19:22 -0700)
This will be useful for a number of things:
- Checking the current advanced blending mode against the shader's
  blend_support_* qualifiers.
- Disabling hardware blending when emulating advanced blending.
- Uploading the current advanced blending mode as a state var.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/mesa/main/blend.c
src/mesa/main/mtypes.h

index fe83e59f8276b48907ec73c34feaed5b8a13ac3a..de6d3c48e05fd452e5e9811cf3f4d17cd6670317 100644 (file)
@@ -355,36 +355,57 @@ legal_simple_blend_equation(const struct gl_context *ctx, GLenum mode)
    }
 }
 
-
-/**
- * Return true if \p mode is one of the advanced blending equations
- * defined by GL_KHR_blend_equation_advanced.
- */
-static bool
-legal_advanced_blend_equation(const struct gl_context *ctx, GLenum mode)
+static enum gl_advanced_blend_mode
+advanced_blend_mode_from_gl_enum(GLenum mode)
 {
    switch (mode) {
    case GL_MULTIPLY_KHR:
+      return BLEND_MULTIPLY;
    case GL_SCREEN_KHR:
+      return BLEND_SCREEN;
    case GL_OVERLAY_KHR:
+      return BLEND_OVERLAY;
    case GL_DARKEN_KHR:
+      return BLEND_DARKEN;
    case GL_LIGHTEN_KHR:
+      return BLEND_LIGHTEN;
    case GL_COLORDODGE_KHR:
+      return BLEND_COLORDODGE;
    case GL_COLORBURN_KHR:
+      return BLEND_COLORBURN;
    case GL_HARDLIGHT_KHR:
+      return BLEND_HARDLIGHT;
    case GL_SOFTLIGHT_KHR:
+      return BLEND_SOFTLIGHT;
    case GL_DIFFERENCE_KHR:
+      return BLEND_DIFFERENCE;
    case GL_EXCLUSION_KHR:
+      return BLEND_EXCLUSION;
    case GL_HSL_HUE_KHR:
+      return BLEND_HSL_HUE;
    case GL_HSL_SATURATION_KHR:
+      return BLEND_HSL_SATURATION;
    case GL_HSL_COLOR_KHR:
+      return BLEND_HSL_COLOR;
    case GL_HSL_LUMINOSITY_KHR:
-      return _mesa_has_KHR_blend_equation_advanced(ctx);
+      return BLEND_HSL_LUMINOSITY;
    default:
-      return false;
+      return BLEND_NONE;
    }
 }
 
+/**
+ * If \p mode is one of the advanced blending equations defined by
+ * GL_KHR_blend_equation_advanced (and the extension is supported),
+ * return the corresponding BLEND_* enum.  Otherwise, return BLEND_NONE
+ * (which can also be treated as false).
+ */
+static enum gl_advanced_blend_mode
+advanced_blend_mode(const struct gl_context *ctx, GLenum mode)
+{
+   return _mesa_has_KHR_blend_equation_advanced(ctx) ?
+          advanced_blend_mode_from_gl_enum(mode) : BLEND_NONE;
+}
 
 /* This is really an extension function! */
 void GLAPIENTRY
@@ -394,6 +415,7 @@ _mesa_BlendEquation( GLenum mode )
    const unsigned numBuffers = num_buffers(ctx);
    unsigned buf;
    bool changed = false;
+   enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glBlendEquation(%s)\n",
@@ -420,8 +442,8 @@ _mesa_BlendEquation( GLenum mode )
    if (!changed)
       return;
 
-   if (!legal_simple_blend_equation(ctx, mode) &&
-       !legal_advanced_blend_equation(ctx, mode)) {
+
+   if (!legal_simple_blend_equation(ctx, mode) && !advanced_mode) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
       return;
    }
@@ -433,6 +455,7 @@ _mesa_BlendEquation( GLenum mode )
       ctx->Color.Blend[buf].EquationA = mode;
    }
    ctx->Color._BlendEquationPerBuffer = GL_FALSE;
+   ctx->Color._AdvancedBlendMode = advanced_mode;
 
    if (ctx->Driver.BlendEquationSeparate)
       ctx->Driver.BlendEquationSeparate(ctx, mode, mode);
@@ -446,6 +469,7 @@ void GLAPIENTRY
 _mesa_BlendEquationiARB(GLuint buf, GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
+   enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
@@ -457,8 +481,7 @@ _mesa_BlendEquationiARB(GLuint buf, GLenum mode)
       return;
    }
 
-   if (!legal_simple_blend_equation(ctx, mode) &&
-       !legal_advanced_blend_equation(ctx, mode)) {
+   if (!legal_simple_blend_equation(ctx, mode) && !advanced_mode) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi");
       return;
    }
@@ -471,6 +494,9 @@ _mesa_BlendEquationiARB(GLuint buf, GLenum mode)
    ctx->Color.Blend[buf].EquationRGB = mode;
    ctx->Color.Blend[buf].EquationA = mode;
    ctx->Color._BlendEquationPerBuffer = GL_TRUE;
+
+   if (buf == 0)
+      ctx->Color._AdvancedBlendMode = advanced_mode;
 }
 
 
@@ -537,6 +563,7 @@ _mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA )
       ctx->Color.Blend[buf].EquationA = modeA;
    }
    ctx->Color._BlendEquationPerBuffer = GL_FALSE;
+   ctx->Color._AdvancedBlendMode = BLEND_NONE;
 
    if (ctx->Driver.BlendEquationSeparate)
       ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
@@ -586,6 +613,7 @@ _mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA)
    ctx->Color.Blend[buf].EquationRGB = modeRGB;
    ctx->Color.Blend[buf].EquationA = modeA;
    ctx->Color._BlendEquationPerBuffer = GL_TRUE;
+   ctx->Color._AdvancedBlendMode = BLEND_NONE;
 }
 
 
index 3d9e26032d994b596566e6e39412306fda79833d..3e12555e390c6ce3ecf87187c215ea647a135032 100644 (file)
@@ -452,6 +452,15 @@ struct gl_colorbuffer_attrib
    GLboolean _BlendFuncPerBuffer;
    /** Are the blend equations currently different for each buffer/target? */
    GLboolean _BlendEquationPerBuffer;
+
+   /**
+    * Which advanced blending mode is in use (or BLEND_NONE).
+    *
+    * KHR_blend_equation_advanced only allows advanced blending with a single
+    * draw buffer, and NVX_blend_equation_advanced_multi_draw_buffer still
+    * requires all draw buffers to match, so we only need a single value.
+    */
+   enum gl_advanced_blend_mode _AdvancedBlendMode;
    /*@}*/
 
    /**