From 0745e039a2a9d6763f9a1a241fba18bdbd74ad85 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 28 Jun 2016 08:17:57 -0700 Subject: [PATCH] mesa: Track the current advanced blending mode. 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 Reviewed-by: Francisco Jerez --- src/mesa/main/blend.c | 54 ++++++++++++++++++++++++++++++++---------- src/mesa/main/mtypes.h | 9 +++++++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index fe83e59f827..de6d3c48e05 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -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; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3d9e26032d9..3e12555e390 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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; /*@}*/ /** -- 2.30.2