mesa: don't flag _NEW_COLOR for KHR adv.blend if prog constant doesn't change
authorMarek Olšák <marek.olsak@amd.com>
Sun, 7 Jan 2018 17:27:40 +0000 (18:27 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 2 Feb 2018 14:06:47 +0000 (15:06 +0100)
This only affects drivers that set DriverFlags.NewBlend.

v2: - fix typo advanded -> advanced
    - return "enum gl_advanced_blend_mode" from
      _mesa_get_advanced_blend_sh_constant
    - don't call FLUSH_VERTICES twice

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/main/blend.c
src/mesa/main/blend.h
src/mesa/main/enable.c
src/mesa/program/prog_statevars.c

index 6b379f24992aaf2af130f4be4bd720cc00ac068a..ec8e27e1d4d64baeb9d9081c364e83302088dca2 100644 (file)
@@ -535,7 +535,8 @@ _mesa_BlendEquation( GLenum mode )
       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;
@@ -560,7 +561,8 @@ blend_equationi(struct gl_context *ctx, GLuint buf, GLenum 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;
index 2454e0c744e1c7b2e96fa1dcbd4dcc04401a0d52..c95bc5789615055dc86b847437596e947751e321 100644 (file)
@@ -154,21 +154,48 @@ extern void
 _mesa_init_color( struct gl_context * ctx );
 
 
+static inline enum gl_advanced_blend_mode
+_mesa_get_advanced_blend_sh_constant(GLbitfield blend_enabled,
+                                     enum gl_advanced_blend_mode mode)
+{
+   return blend_enabled ? mode : BLEND_NONE;
+}
+
+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_advanced_blend_sh_constant(new_blend_enabled, new_mode) !=
+          _mesa_get_advanced_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;
+      return;
    }
-   ctx->NewDriverState |= ctx->DriverFlags.NewBlend;
+   _mesa_flush_vertices_for_blend_state(ctx);
 }
 
 #endif
index 451a9c918f41eafdefd51f36a225c7405c2deb4d..bc22410bda4cb121d7a134dd876d6beb6f67cd39 100644 (file)
@@ -329,7 +329,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
             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;
             }
          }
@@ -1198,11 +1199,16 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
          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:
index b69895c47fcfa9618938bd71378f2f1d9a73fea5..481123a7dc27b1e265bec97b99032322ea8baba7 100644 (file)
@@ -598,7 +598,8 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
          return;
 
       case STATE_ADVANCED_BLENDING_MODE:
-         val[0].i = ctx->Color.BlendEnabled ? ctx->Color._AdvancedBlendMode : 0;
+         val[0].i = _mesa_get_advanced_blend_sh_constant(
+                      ctx->Color.BlendEnabled, ctx->Color._AdvancedBlendMode);
          return;
 
       /* XXX: make sure new tokens added here are also handled in the