<div dir="ltr"><div>Sigh, I should have just ignored the docs when I was poking at this years ago.</div><div><br></div><div>Reviewed-by: Chris Forbes <<a href="mailto:chrisforbes@google.com">chrisforbes@google.com</a>><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 29, 2017 at 10:49 PM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The BLEND_STATE documentation says that alpha to one must be disabled<br>
when dual color blending is enabled.  However, it appears that it simply<br>
fails to override src1 alpha to one.<br>
<br>
We can work around this by leaving alpha to one enabled, but overriding<br>
SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO.  This appears to be<br>
what the other driver does, and it looks like it works despite the<br>
documentation saying not to do it.<br>
<br>
Fixes spec/ext_framebuffer_<wbr>multisample/alpha-to-one-dual-<wbr>src-blend *<br>
Piglit tests.<br>
---<br>
 src/mesa/drivers/dri/i965/<wbr>genX_state_upload.c | 57 +++++++++++++++++++++------<br>
 1 file changed, 44 insertions(+), 13 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>genX_state_upload.c b/src/mesa/drivers/dri/i965/<wbr>genX_state_upload.c<br>
index 76d2ea887b1..145173c2fc1 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>genX_state_upload.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>genX_state_upload.c<br>
@@ -2435,6 +2435,20 @@ static const struct brw_tracked_state genX(gs_state) = {<br>
<br>
 /* ------------------------------<wbr>------------------------------<wbr>---------- */<br>
<br>
+static GLenum<br>
+fix_dual_blend_alpha_to_one(<wbr>GLenum function)<br>
+{<br>
+   switch (function) {<br>
+   case GL_SRC1_ALPHA:<br>
+      return GL_ONE;<br>
+<br>
+   case GL_ONE_MINUS_SRC1_ALPHA:<br>
+      return GL_ZERO;<br>
+   }<br>
+<br>
+   return function;<br>
+}<br>
+<br>
 #define blend_factor(x) brw_translate_blend_factor(x)<br>
 #define blend_eqn(x) brw_translate_blend_equation(<wbr>x)<br>
<br>
@@ -2562,6 +2576,19 @@ genX(upload_blend_state)(<wbr>struct brw_context *brw)<br>
                dstA = brw_fix_xRGB_alpha(dstA);<br>
             }<br>
<br>
+            /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):<br>
+             * "If Dual Source Blending is enabled, this bit must be disabled."<br>
+             *<br>
+             * We override SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO,<br>
+             * and leave it enabled anyway.<br>
+             */<br>
+            if (ctx->Color.Blend[i]._<wbr>UsesDualSrc && blend.AlphaToOneEnable) {<br>
+               srcRGB = fix_dual_blend_alpha_to_one(<wbr>srcRGB);<br>
+               srcA = fix_dual_blend_alpha_to_one(<wbr>srcA);<br>
+               dstRGB = fix_dual_blend_alpha_to_one(<wbr>dstRGB);<br>
+               dstA = fix_dual_blend_alpha_to_one(<wbr>dstA);<br>
+            }<br>
+<br>
             entry.ColorBufferBlendEnable = true;<br>
             entry.DestinationBlendFactor = blend_factor(dstRGB);<br>
             entry.SourceBlendFactor = blend_factor(srcRGB);<br>
@@ -2600,16 +2627,6 @@ genX(upload_blend_state)(<wbr>struct brw_context *brw)<br>
          entry.WriteDisableBlue  = !ctx->Color.ColorMask[i][2];<br>
          entry.WriteDisableAlpha = !ctx->Color.ColorMask[i][3];<br>
<br>
-         /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):<br>
-          * "If Dual Source Blending is enabled, this bit must be disabled."<br>
-          */<br>
-         WARN_ONCE(ctx->Color.Blend[i].<wbr>_UsesDualSrc &&<br>
-                   _mesa_is_multisample_enabled(<wbr>ctx) &&<br>
-                   ctx->Multisample.<wbr>SampleAlphaToOne,<br>
-                   "HW workaround: disabling alpha to one with dual src "<br>
-                   "blending\n");<br>
-         if (ctx->Color.Blend[i]._<wbr>UsesDualSrc)<br>
-            blend.AlphaToOneEnable = false;<br>
 #if GEN_GEN >= 8<br>
          GENX(BLEND_STATE_ENTRY_pack)(<wbr>NULL, &blend_map[1 + i * 2], &entry);<br>
 #else<br>
@@ -4049,11 +4066,15 @@ genX(upload_ps_blend)(struct brw_context *brw)<br>
       /* BRW_NEW_FRAGMENT_PROGRAM | _NEW_BUFFERS | _NEW_COLOR */<br>
       pb.HasWriteableRT = brw_color_buffer_write_<wbr>enabled(brw);<br>
<br>
+      bool alpha_to_one = false;<br>
+<br>
       if (!buffer0_is_integer) {<br>
          /* _NEW_MULTISAMPLE */<br>
-         pb.AlphaToCoverageEnable =<br>
-            _mesa_is_multisample_enabled(<wbr>ctx) &&<br>
-            ctx->Multisample.<wbr>SampleAlphaToCoverage;<br>
+<br>
+         if (_mesa_is_multisample_enabled(<wbr>ctx)) {<br>
+            pb.AlphaToCoverageEnable = ctx->Multisample.<wbr>SampleAlphaToCoverage;<br>
+            alpha_to_one = ctx->Multisample.<wbr>SampleAlphaToOne;<br>
+         }<br>
<br>
          pb.AlphaTestEnable = color->AlphaEnabled;<br>
       }<br>
@@ -4098,6 +4119,16 @@ genX(upload_ps_blend)(struct brw_context *brw)<br>
             dstA = brw_fix_xRGB_alpha(dstA);<br>
          }<br>
<br>
+         /* Alpha to One doesn't work with Dual Color Blending.  Override<br>
+          * SRC1_ALPHA to ONE and ONE_MINUS_SRC1_ALPHA to ZERO.<br>
+          */<br>
+         if (alpha_to_one && color->Blend[0]._UsesDualSrc) {<br>
+            srcRGB = fix_dual_blend_alpha_to_one(<wbr>srcRGB);<br>
+            srcA = fix_dual_blend_alpha_to_one(<wbr>srcA);<br>
+            dstRGB = fix_dual_blend_alpha_to_one(<wbr>dstRGB);<br>
+            dstA = fix_dual_blend_alpha_to_one(<wbr>dstA);<br>
+         }<br>
+<br>
          pb.ColorBufferBlendEnable = true;<br>
          pb.SourceAlphaBlendFactor = brw_translate_blend_factor(<wbr>srcA);<br>
          pb.DestinationAlphaBlendFactor = brw_translate_blend_factor(<wbr>dstA);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>