From bf9d61a3d40c9a95cff9a25a16d62eeb1e9b5577 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 24 Jan 2021 16:48:13 -0500 Subject: [PATCH] mesa: move blending validation from draws to state changes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is a step towards removing _mesa_valid_to_render. Reviewed-by: Zoltán Böszörményi Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mesa/main/blend.c | 26 ++++++-- src/mesa/main/draw_validate.c | 134 +++++++++++++++++------------------------- 2 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index ebc4ae0..5bf1e42 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -32,6 +32,7 @@ #include "glheader.h" #include "blend.h" #include "context.h" +#include "draw_validate.h" #include "enums.h" #include "macros.h" #include "mtypes.h" @@ -170,11 +171,16 @@ blend_factor_is_dual_src(GLenum factor) static void update_uses_dual_src(struct gl_context *ctx, int buf) { - ctx->Color.Blend[buf]._UsesDualSrc = + bool uses_dual_src = (blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcRGB) || blend_factor_is_dual_src(ctx->Color.Blend[buf].DstRGB) || blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) || blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA)); + + if (ctx->Color.Blend[buf]._UsesDualSrc != uses_dual_src) { + ctx->Color.Blend[buf]._UsesDualSrc = uses_dual_src; + _mesa_update_valid_to_render_state(ctx); + } } @@ -497,6 +503,16 @@ advanced_blend_mode(const struct gl_context *ctx, GLenum mode) advanced_blend_mode_from_gl_enum(mode) : BLEND_NONE; } +static void +set_advanced_blend_mode(struct gl_context *ctx, + enum gl_advanced_blend_mode advanced_mode) +{ + if (ctx->Color._AdvancedBlendMode != advanced_mode) { + ctx->Color._AdvancedBlendMode = advanced_mode; + _mesa_update_valid_to_render_state(ctx); + } +} + /* This is really an extension function! */ void GLAPIENTRY _mesa_BlendEquation( GLenum mode ) @@ -546,7 +562,7 @@ _mesa_BlendEquation( GLenum mode ) ctx->Color.Blend[buf].EquationA = mode; } ctx->Color._BlendEquationPerBuffer = GL_FALSE; - ctx->Color._AdvancedBlendMode = advanced_mode; + set_advanced_blend_mode(ctx, advanced_mode); if (ctx->Driver.BlendEquationSeparate) ctx->Driver.BlendEquationSeparate(ctx, mode, mode); @@ -571,7 +587,7 @@ blend_equationi(struct gl_context *ctx, GLuint buf, GLenum mode, ctx->Color._BlendEquationPerBuffer = GL_TRUE; if (buf == 0) - ctx->Color._AdvancedBlendMode = advanced_mode; + set_advanced_blend_mode(ctx, advanced_mode); } @@ -670,7 +686,7 @@ blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA, ctx->Color.Blend[buf].EquationA = modeA; } ctx->Color._BlendEquationPerBuffer = GL_FALSE; - ctx->Color._AdvancedBlendMode = BLEND_NONE; + set_advanced_blend_mode(ctx, BLEND_NONE); if (ctx->Driver.BlendEquationSeparate) ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA); @@ -729,7 +745,7 @@ blend_equation_separatei(struct gl_context *ctx, GLuint buf, GLenum modeRGB, ctx->Color.Blend[buf].EquationRGB = modeRGB; ctx->Color.Blend[buf].EquationA = modeA; ctx->Color._BlendEquationPerBuffer = GL_TRUE; - ctx->Color._AdvancedBlendMode = BLEND_NONE; + set_advanced_blend_mode(ctx, BLEND_NONE); } diff --git a/src/mesa/main/draw_validate.c b/src/mesa/main/draw_validate.c index 7f73d49..e1dceb5 100644 --- a/src/mesa/main/draw_validate.c +++ b/src/mesa/main/draw_validate.c @@ -38,82 +38,6 @@ #include "program/prog_print.h" -static bool -check_blend_func_error(struct gl_context *ctx) -{ - /* The ARB_blend_func_extended spec's ERRORS section says: - * - * "The error INVALID_OPERATION is generated by Begin or any procedure - * that implicitly calls Begin if any draw buffer has a blend function - * requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, - * SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that - * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active - * color attachements." - */ - for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers; - i < ctx->DrawBuffer->_NumColorDrawBuffers; - i++) { - if (ctx->Color.Blend[i]._UsesDualSrc) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "dual source blend on illegal attachment"); - return false; - } - } - - if (ctx->Color.BlendEnabled && - ctx->Color._AdvancedBlendMode != BLEND_NONE) { - /* The KHR_blend_equation_advanced spec says: - * - * "If any non-NONE draw buffer uses a blend equation found in table - * X.1 or X.2, the error INVALID_OPERATION is generated by Begin or - * any operation that implicitly calls Begin (such as DrawElements) - * if: - * - * * the draw buffer for color output zero selects multiple color - * buffers (e.g., FRONT_AND_BACK in the default framebuffer); or - * - * * the draw buffer for any other color output is not NONE." - */ - if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "advanced blending is active and draw buffer for color " - "output zero selects multiple color buffers"); - return false; - } - - for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "advanced blending is active with multiple color " - "draw buffers"); - return false; - } - } - - /* The KHR_blend_equation_advanced spec says: - * - * "Advanced blending equations require the use of a fragment shader - * with a matching "blend_support" layout qualifier. If the current - * blend equation is found in table X.1 or X.2, and the active - * fragment shader does not include the layout qualifier matching - * the blend equation or "blend_support_all_equations", the error - * INVALID_OPERATION is generated [...]" - */ - const struct gl_program *prog = ctx->FragmentProgram._Current; - const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport; - - if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "fragment shader does not allow advanced blending mode " - "(%s)", - _mesa_enum_to_string(ctx->Color.Blend[0].EquationRGB)); - } - } - - return true; -} - - /** * Prior to drawing anything with glBegin, glDrawArrays, etc. this function * is called to see if it's valid to render. This involves checking that @@ -129,10 +53,6 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) if (ctx->NewState) _mesa_update_state(ctx); - if (!check_blend_func_error(ctx)) { - return GL_FALSE; - } - return GL_TRUE; } @@ -186,6 +106,60 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) !_mesa_sampler_uniforms_are_valid(shader->ActiveProgram, NULL, 0)) return; + /* The ARB_blend_func_extended spec's ERRORS section says: + * + * "The error INVALID_OPERATION is generated by Begin or any procedure + * that implicitly calls Begin if any draw buffer has a blend function + * requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, + * SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that + * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active + * color attachements." + */ + for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers; + i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + if (ctx->Color.Blend[i]._UsesDualSrc) + return; + } + + if (ctx->Color.BlendEnabled && + ctx->Color._AdvancedBlendMode != BLEND_NONE) { + /* The KHR_blend_equation_advanced spec says: + * + * "If any non-NONE draw buffer uses a blend equation found in table + * X.1 or X.2, the error INVALID_OPERATION is generated by Begin or + * any operation that implicitly calls Begin (such as DrawElements) + * if: + * + * * the draw buffer for color output zero selects multiple color + * buffers (e.g., FRONT_AND_BACK in the default framebuffer); or + * + * * the draw buffer for any other color output is not NONE." + */ + if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) + return; + + for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) + return; + } + + /* The KHR_blend_equation_advanced spec says: + * + * "Advanced blending equations require the use of a fragment shader + * with a matching "blend_support" layout qualifier. If the current + * blend equation is found in table X.1 or X.2, and the active + * fragment shader does not include the layout qualifier matching + * the blend equation or "blend_support_all_equations", the error + * INVALID_OPERATION is generated [...]" + */ + const struct gl_program *prog = + ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; + const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport; + + if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0) + return; + } + if (ctx->API == API_OPENGL_COMPAT) { if (!shader->CurrentProgram[MESA_SHADER_FRAGMENT]) { if (ctx->FragmentProgram.Enabled && -- 2.7.4