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 <kenneth@whitecape.org>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
Kenneth Graunke 2016-06-28 08:17:57 -07:00
parent 74837e3e91
commit 0745e039a2
2 changed files with 50 additions and 13 deletions

View 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;
}

View 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;
/*@}*/
/**