aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/genX_state_upload.c57
1 files 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 23358c4551b..041bcd2a8c6 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);