[Mesa-dev] [PATCH] i965: Fix alpha to one with dual color blending.
Anuj Phogat
anuj.phogat at gmail.com
Mon Jun 5 18:43:10 UTC 2017
On Mon, May 29, 2017 at 10:49 PM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> 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.
> ---
> 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 76d2ea887b1..145173c2fc1 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) = {
>
> /* ---------------------------------------------------------------------- */
>
> +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
> @@ -4049,11 +4066,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;
> }
> @@ -4098,6 +4119,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);
> --
> 2.13.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
I think it'll be useful to create a h/w spec bug and get it fixed for future.
Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>
More information about the mesa-dev
mailing list