<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>