[Mesa-dev] [PATCH 1/4] mesa: don't flag _NEW_COLOR for KHR adv.blend if prog constant doesn't change

Marek Olšák maraeo at gmail.com
Tue Jan 30 15:48:39 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

This only affects drivers that set DriverFlags.NewBlend.
---
 src/mesa/main/blend.c             |  6 ++++--
 src/mesa/main/blend.h             | 41 +++++++++++++++++++++++++++++++--------
 src/mesa/main/enable.c            | 14 +++++++++----
 src/mesa/program/prog_statevars.c |  3 ++-
 4 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index 6b379f2..ec8e27e 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -528,21 +528,22 @@ _mesa_BlendEquation( GLenum mode )
 
    if (!changed)
       return;
 
 
    if (!legal_simple_blend_equation(ctx, mode) && !advanced_mode) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
       return;
    }
 
-   _mesa_flush_vertices_for_blend_state(ctx);
+   _mesa_flush_vertices_for_blend_adv(ctx, ctx->Color.BlendEnabled,
+                                      advanced_mode);
 
    for (buf = 0; buf < numBuffers; buf++) {
       ctx->Color.Blend[buf].EquationRGB = 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);
@@ -553,21 +554,22 @@ _mesa_BlendEquation( GLenum mode )
  * Set blend equation for one color buffer/target.
  */
 static void
 blend_equationi(struct gl_context *ctx, GLuint buf, GLenum mode,
                 enum gl_advanced_blend_mode advanced_mode)
 {
    if (ctx->Color.Blend[buf].EquationRGB == mode &&
        ctx->Color.Blend[buf].EquationA == mode)
       return;  /* no change */
 
-   _mesa_flush_vertices_for_blend_state(ctx);
+   _mesa_flush_vertices_for_blend_adv(ctx, ctx->Color.BlendEnabled,
+                                      advanced_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;
 }
 
 
 void GLAPIENTRY
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
index 2454e0c..cba5a98 100644
--- a/src/mesa/main/blend.h
+++ b/src/mesa/main/blend.h
@@ -147,28 +147,53 @@ extern void
 _mesa_update_clamp_vertex_color(struct gl_context *ctx,
                                 const struct gl_framebuffer *drawFb);
 
 extern mesa_format
 _mesa_get_render_format(const struct gl_context *ctx, mesa_format format);
 
 extern void  
 _mesa_init_color( struct gl_context * ctx );
 
 
+static inline unsigned
+_mesa_get_advanded_blend_sh_constant(GLbitfield blend_enabled,
+                                     enum gl_advanced_blend_mode mode)
+{
+   return blend_enabled ? mode : 0;
+}
+
+static inline bool
+_mesa_advanded_blend_sh_constant_changed(struct gl_context *ctx,
+                                         GLbitfield new_blend_enabled,
+                                         enum gl_advanced_blend_mode new_mode)
+{
+   return _mesa_get_advanded_blend_sh_constant(new_blend_enabled, new_mode) !=
+          _mesa_get_advanded_blend_sh_constant(ctx->Color.BlendEnabled,
+                                               ctx->Color._AdvancedBlendMode);
+}
+
 static inline void
 _mesa_flush_vertices_for_blend_state(struct gl_context *ctx)
 {
-   /* The advanced blend mode needs _NEW_COLOR to update the state constant,
-    * so we have to set it. This is inefficient.
-    * This should only be done for states that affect the state constant.
-    * It shouldn't be done for other blend states.
-    */
-   if (_mesa_has_KHR_blend_equation_advanced(ctx) ||
-       !ctx->DriverFlags.NewBlend) {
+   if (!ctx->DriverFlags.NewBlend) {
       FLUSH_VERTICES(ctx, _NEW_COLOR);
    } else {
       FLUSH_VERTICES(ctx, 0);
+      ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
+   }
+}
+
+static inline void
+_mesa_flush_vertices_for_blend_adv(struct gl_context *ctx,
+                                   GLbitfield new_blend_enabled,
+                                   enum gl_advanced_blend_mode new_mode)
+{
+   /* The advanced blend mode needs _NEW_COLOR to update the state constant. */
+   if (_mesa_has_KHR_blend_equation_advanced(ctx) &&
+       _mesa_advanded_blend_sh_constant_changed(ctx, new_blend_enabled,
+                                                new_mode)) {
+      FLUSH_VERTICES(ctx, _NEW_COLOR);
    }
-   ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
+   _mesa_flush_vertices_for_blend_state(ctx);
 }
 
 #endif
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index c859a7a..b09aca3 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -317,21 +317,22 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
          if (ctx->Eval.AutoNormal == state)
             return;
          FLUSH_VERTICES(ctx, _NEW_EVAL);
          ctx->Eval.AutoNormal = state;
          break;
       case GL_BLEND:
          {
             GLbitfield newEnabled =
                state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
             if (newEnabled != ctx->Color.BlendEnabled) {
-               _mesa_flush_vertices_for_blend_state(ctx);
+               _mesa_flush_vertices_for_blend_adv(ctx, newEnabled,
+                                               ctx->Color._AdvancedBlendMode);
                ctx->Color.BlendEnabled = newEnabled;
             }
          }
          break;
       case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */
       case GL_CLIP_DISTANCE1:
       case GL_CLIP_DISTANCE2:
       case GL_CLIP_DISTANCE3:
       case GL_CLIP_DISTANCE4:
       case GL_CLIP_DISTANCE5:
@@ -1186,25 +1187,30 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
    case GL_BLEND:
       if (!ctx->Extensions.EXT_draw_buffers2) {
          goto invalid_enum_error;
       }
       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) {
-         _mesa_flush_vertices_for_blend_state(ctx);
+         GLbitfield enabled = ctx->Color.BlendEnabled;
+
          if (state)
-            ctx->Color.BlendEnabled |= (1 << index);
+            enabled |= (1 << index);
          else
-            ctx->Color.BlendEnabled &= ~(1 << index);
+            enabled &= ~(1 << index);
+
+         _mesa_flush_vertices_for_blend_adv(ctx, enabled,
+                                            ctx->Color._AdvancedBlendMode);
+         ctx->Color.BlendEnabled = enabled;
       }
       break;
    case GL_SCISSOR_TEST:
       if (index >= ctx->Const.MaxViewports) {
          _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
                      state ? "glEnablei" : "glDisablei", index);
          return;
       }
       if (((ctx->Scissor.EnableFlags >> index) & 1) != state) {
          FLUSH_VERTICES(ctx,
diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c
index b69895c..9705071 100644
--- a/src/mesa/program/prog_statevars.c
+++ b/src/mesa/program/prog_statevars.c
@@ -591,21 +591,22 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
          return;
 
       case STATE_TES_PATCH_VERTICES_IN:
          if (ctx->TessCtrlProgram._Current)
             val[0].i = ctx->TessCtrlProgram._Current->info.tess.tcs_vertices_out;
          else
             val[0].i = ctx->TessCtrlProgram.patch_vertices;
          return;
 
       case STATE_ADVANCED_BLENDING_MODE:
-         val[0].i = ctx->Color.BlendEnabled ? ctx->Color._AdvancedBlendMode : 0;
+         val[0].i = _mesa_get_advanded_blend_sh_constant(
+                      ctx->Color.BlendEnabled, ctx->Color._AdvancedBlendMode);
          return;
 
       /* XXX: make sure new tokens added here are also handled in the 
        * _mesa_program_state_flags() switch, below.
        */
       default:
          /* Unknown state indexes are silently ignored here.
           * Drivers may do something special.
           */
          return;
-- 
2.7.4



More information about the mesa-dev mailing list