Mesa (master): i965: Fix alpha to one with dual color blending.

Kenneth Graunke kwg at kemper.freedesktop.org
Wed Jun 7 09:14:10 UTC 2017


Module: Mesa
Branch: master
Commit: 09c3a00f10861269f2187b5033f754b770a09b16
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=09c3a00f10861269f2187b5033f754b770a09b16

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Mon May 29 22:07:07 2017 -0700

i965: Fix alpha to one with dual color blending.

The BLEND_STATE documentation says that alpha to one must be disabled
when dual color blending is enabled.  However, it appears that it simply
fails to override src1 alpha to one.

We can work around this by leaving alpha to one enabled, but overriding
SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO.  This appears to be
what the other driver does, and it looks like it works despite the
documentation saying not to do it.

Fixes spec/ext_framebuffer_multisample/alpha-to-one-dual-src-blend *
Piglit tests.

v2: Add UNUSED to shut up warning on generations which don't use this.

Reviewed-by: Chris Forbes <chrisforbes at google.com>
Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>

---

 src/mesa/drivers/dri/i965/genX_state_upload.c | 57 +++++++++++++++++++++------
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
index 23358c4551..041bcd2a8c 100644
--- a/src/mesa/drivers/dri/i965/genX_state_upload.c
+++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
@@ -2435,6 +2435,20 @@ static const struct brw_tracked_state genX(gs_state) = {
 
 /* ---------------------------------------------------------------------- */
 
+UNUSED static GLenum
+fix_dual_blend_alpha_to_one(GLenum function)
+{
+   switch (function) {
+   case GL_SRC1_ALPHA:
+      return GL_ONE;
+
+   case GL_ONE_MINUS_SRC1_ALPHA:
+      return GL_ZERO;
+   }
+
+   return function;
+}
+
 #define blend_factor(x) brw_translate_blend_factor(x)
 #define blend_eqn(x) brw_translate_blend_equation(x)
 
@@ -2562,6 +2576,19 @@ genX(upload_blend_state)(struct brw_context *brw)
                dstA = brw_fix_xRGB_alpha(dstA);
             }
 
+            /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):
+             * "If Dual Source Blending is enabled, this bit must be disabled."
+             *
+             * We override SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO,
+             * and leave it enabled anyway.
+             */
+            if (ctx->Color.Blend[i]._UsesDualSrc && blend.AlphaToOneEnable) {
+               srcRGB = fix_dual_blend_alpha_to_one(srcRGB);
+               srcA = fix_dual_blend_alpha_to_one(srcA);
+               dstRGB = fix_dual_blend_alpha_to_one(dstRGB);
+               dstA = fix_dual_blend_alpha_to_one(dstA);
+            }
+
             entry.ColorBufferBlendEnable = true;
             entry.DestinationBlendFactor = blend_factor(dstRGB);
             entry.SourceBlendFactor = blend_factor(srcRGB);
@@ -2600,16 +2627,6 @@ genX(upload_blend_state)(struct brw_context *brw)
          entry.WriteDisableBlue  = !ctx->Color.ColorMask[i][2];
          entry.WriteDisableAlpha = !ctx->Color.ColorMask[i][3];
 
-         /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):
-          * "If Dual Source Blending is enabled, this bit must be disabled."
-          */
-         WARN_ONCE(ctx->Color.Blend[i]._UsesDualSrc &&
-                   _mesa_is_multisample_enabled(ctx) &&
-                   ctx->Multisample.SampleAlphaToOne,
-                   "HW workaround: disabling alpha to one with dual src "
-                   "blending\n");
-         if (ctx->Color.Blend[i]._UsesDualSrc)
-            blend.AlphaToOneEnable = false;
 #if GEN_GEN >= 8
          GENX(BLEND_STATE_ENTRY_pack)(NULL, &blend_map[1 + i * 2], &entry);
 #else
@@ -4015,11 +4032,15 @@ genX(upload_ps_blend)(struct brw_context *brw)
       /* BRW_NEW_FRAGMENT_PROGRAM | _NEW_BUFFERS | _NEW_COLOR */
       pb.HasWriteableRT = brw_color_buffer_write_enabled(brw);
 
+      bool alpha_to_one = false;
+
       if (!buffer0_is_integer) {
          /* _NEW_MULTISAMPLE */
-         pb.AlphaToCoverageEnable =
-            _mesa_is_multisample_enabled(ctx) &&
-            ctx->Multisample.SampleAlphaToCoverage;
+
+         if (_mesa_is_multisample_enabled(ctx)) {
+            pb.AlphaToCoverageEnable = ctx->Multisample.SampleAlphaToCoverage;
+            alpha_to_one = ctx->Multisample.SampleAlphaToOne;
+         }
 
          pb.AlphaTestEnable = color->AlphaEnabled;
       }
@@ -4064,6 +4085,16 @@ genX(upload_ps_blend)(struct brw_context *brw)
             dstA = brw_fix_xRGB_alpha(dstA);
          }
 
+         /* Alpha to One doesn't work with Dual Color Blending.  Override
+          * SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO.
+          */
+         if (alpha_to_one && color->Blend[0]._UsesDualSrc) {
+            srcRGB = fix_dual_blend_alpha_to_one(srcRGB);
+            srcA = fix_dual_blend_alpha_to_one(srcA);
+            dstRGB = fix_dual_blend_alpha_to_one(dstRGB);
+            dstA = fix_dual_blend_alpha_to_one(dstA);
+         }
+
          pb.ColorBufferBlendEnable = true;
          pb.SourceAlphaBlendFactor = brw_translate_blend_factor(srcA);
          pb.DestinationAlphaBlendFactor = brw_translate_blend_factor(dstA);




More information about the mesa-commit mailing list