[Mesa-dev] [PATCH 10/18] i965: Make a helper function for blend entry related state.
Rafael Antognolli
rafael.antognolli at intel.com
Mon Jun 19 16:23:41 UTC 2017
On Sat, Jun 17, 2017 at 10:32:44AM -0700, Kenneth Graunke wrote:
> On Friday, June 16, 2017 4:31:23 PM PDT Rafael Antognolli wrote:
> > Add a helper function to reuse code that fills blend entry related
> > state, and make genX(upload_blend_state) use it. This function can later
> > be used by gen4-5 color calc state to set the blend related bits.
> >
> > Signed-off-by: Rafael Antognolli <rafael.antognolli at intel.com>
> > ---
> > src/mesa/drivers/dri/i965/genX_state_upload.c | 182 ++++++++++++++------------
> > 1 file changed, 101 insertions(+), 81 deletions(-)
> >
> > diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
> > index 5e5dc48..8e99c89 100644
> > --- a/src/mesa/drivers/dri/i965/genX_state_upload.c
> > +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
> > @@ -2528,6 +2528,104 @@ fix_dual_blend_alpha_to_one(GLenum function)
> > #define blend_eqn(x) brw_translate_blend_equation(x)
> >
> > #if GEN_GEN >= 6
> > +typedef struct GENX(BLEND_STATE_ENTRY) BLEND_ENTRY_GENXML;
> > +#else
> > +typedef struct GENX(COLOR_CALC_STATE) BLEND_ENTRY_GENXML;
> > +#endif
> > +
> > +UNUSED static bool
> > +set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
> > + bool alpha_to_one)
> > +{
> > + struct gl_context *ctx = &brw->ctx;
> > +
> > + /* _NEW_BUFFERS */
> > + const struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
> > +
> > + bool independent_alpha_blend = false;
> > +
> > + /* Used for implementing the following bit of GL_EXT_texture_integer:
> > + * "Per-fragment operations that require floating-point color
> > + * components, including multisample alpha operations, alpha test,
> > + * blending, and dithering, have no effect when the corresponding
> > + * colors are written to an integer color buffer."
> > + */
> > + const bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
> > +
> > + /* _NEW_COLOR */
> > + if (ctx->Color.ColorLogicOpEnabled) {
> > + GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
> > + : GL_UNSIGNED_NORMALIZED;
> > + WARN_ONCE(ctx->Color.LogicOp != GL_COPY &&
> > + rb_type != GL_UNSIGNED_NORMALIZED &&
> > + rb_type != GL_FLOAT, "Ignoring %s logic op on %s "
> > + "renderbuffer\n",
> > + _mesa_enum_to_string(ctx->Color.LogicOp),
> > + _mesa_enum_to_string(rb_type));
> > + if (GEN_GEN >= 8 || rb_type == GL_UNSIGNED_NORMALIZED) {
> > + entry->LogicOpEnable = true;
> > + entry->LogicOpFunction =
> > + intel_translate_logic_op(ctx->Color.LogicOp);
> > + }
> > + } else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
> > + !ctx->Color._AdvancedBlendMode) {
> > + GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
> > + GLenum eqA = ctx->Color.Blend[i].EquationA;
> > + GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
> > + GLenum dstRGB = ctx->Color.Blend[i].DstRGB;
> > + GLenum srcA = ctx->Color.Blend[i].SrcA;
> > + GLenum dstA = ctx->Color.Blend[i].DstA;
> > +
> > + if (eqRGB == GL_MIN || eqRGB == GL_MAX)
> > + srcRGB = dstRGB = GL_ONE;
> > +
> > + if (eqA == GL_MIN || eqA == GL_MAX)
> > + srcA = dstA = GL_ONE;
> > +
> > + /* Due to hardware limitations, the destination may have information
> > + * in an alpha channel even when the format specifies no alpha
> > + * channel. In order to avoid getting any incorrect blending due to
> > + * that alpha channel, coerce the blend factors to values that will
> > + * not read the alpha channel, but will instead use the correct
> > + * implicit value for alpha.
> > + */
> > + if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat,
> > + GL_TEXTURE_ALPHA_TYPE)) {
> > + srcRGB = brw_fix_xRGB_alpha(srcRGB);
> > + srcA = brw_fix_xRGB_alpha(srcA);
> > + dstRGB = brw_fix_xRGB_alpha(dstRGB);
> > + 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 (GEN_GEN >= 6 && ctx->Color.Blend[i]._UsesDualSrc && alpha_to_one) {
> > + 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);
> > + entry->DestinationAlphaBlendFactor = blend_factor(dstA);
> > + entry->SourceAlphaBlendFactor = blend_factor(srcA);
> > + entry->ColorBlendFunction = blend_eqn(eqRGB);
> > + entry->AlphaBlendFunction = blend_eqn(eqA);
> > +
> > + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB)
> > + independent_alpha_blend = true;
> > + }
> > +
> > + return independent_alpha_blend;
> > +}
> > +
> > +#if GEN_GEN >= 6
> > static void
> > genX(upload_blend_state)(struct brw_context *brw)
> > {
> > @@ -2594,87 +2692,9 @@ genX(upload_blend_state)(struct brw_context *brw)
> > #else
> > {
> > #endif
> > -
> > - /* _NEW_BUFFERS */
> > - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
> > -
> > - /* Used for implementing the following bit of GL_EXT_texture_integer:
> > - * "Per-fragment operations that require floating-point color
> > - * components, including multisample alpha operations, alpha test,
> > - * blending, and dithering, have no effect when the corresponding
> > - * colors are written to an integer color buffer."
> > - */
> > - bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
> > -
> > - /* _NEW_COLOR */
> > - if (ctx->Color.ColorLogicOpEnabled) {
> > - GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
> > - : GL_UNSIGNED_NORMALIZED;
> > - WARN_ONCE(ctx->Color.LogicOp != GL_COPY &&
> > - rb_type != GL_UNSIGNED_NORMALIZED &&
> > - rb_type != GL_FLOAT, "Ignoring %s logic op on %s "
> > - "renderbuffer\n",
> > - _mesa_enum_to_string(ctx->Color.LogicOp),
> > - _mesa_enum_to_string(rb_type));
> > - if (GEN_GEN >= 8 || rb_type == GL_UNSIGNED_NORMALIZED) {
> > - entry.LogicOpEnable = true;
> > - entry.LogicOpFunction =
> > - intel_translate_logic_op(ctx->Color.LogicOp);
> > - }
> > - } else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
> > - !ctx->Color._AdvancedBlendMode) {
> > - GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
> > - GLenum eqA = ctx->Color.Blend[i].EquationA;
> > - GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
> > - GLenum dstRGB = ctx->Color.Blend[i].DstRGB;
> > - GLenum srcA = ctx->Color.Blend[i].SrcA;
> > - GLenum dstA = ctx->Color.Blend[i].DstA;
> > -
> > - if (eqRGB == GL_MIN || eqRGB == GL_MAX)
> > - srcRGB = dstRGB = GL_ONE;
> > -
> > - if (eqA == GL_MIN || eqA == GL_MAX)
> > - srcA = dstA = GL_ONE;
> > -
> > - /* Due to hardware limitations, the destination may have information
> > - * in an alpha channel even when the format specifies no alpha
> > - * channel. In order to avoid getting any incorrect blending due to
> > - * that alpha channel, coerce the blend factors to values that will
> > - * not read the alpha channel, but will instead use the correct
> > - * implicit value for alpha.
> > - */
> > - if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat,
> > - GL_TEXTURE_ALPHA_TYPE)) {
> > - srcRGB = brw_fix_xRGB_alpha(srcRGB);
> > - srcA = brw_fix_xRGB_alpha(srcA);
> > - dstRGB = brw_fix_xRGB_alpha(dstRGB);
> > - 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);
> > - entry.DestinationAlphaBlendFactor = blend_factor(dstA);
> > - entry.SourceAlphaBlendFactor = blend_factor(srcA);
> > - entry.ColorBlendFunction = blend_eqn(eqRGB);
> > - entry.AlphaBlendFunction = blend_eqn(eqA);
> > -
> > - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB)
> > - blend.IndependentAlphaBlendEnable = true;
> > - }
> > + blend.IndependentAlphaBlendEnable =
> > + set_blend_entry_bits(brw, &entry, i, blend.AlphaToOneEnable) ||
> > + blend.IndependentAlphaBlendEnable;
>
> It looks like this is the only place blend.IndependentAlphaBlendEnable
> is set, so OR'ing in the existing value (of false / 0) should be a no-op.
>
> blend.IndependentAlphaBlendEnable =
> set_blend_entry_bits(brw, &entry, i, blend.AlphaToOneEnable);
It is the only place where it is set, but it's a loop. So if we set it on one
iteration of the loop, we could later unset on the next iteration. And that's
not the original behavior, as far as I understood.
>
> Patches 1-10 are:
> Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
>
> >
> > /* See section 8.1.6 "Pre-Blend Color Clamping" of the
> > * SandyBridge PRM Volume 2 Part 1 for HW requirements.
> >
>
More information about the mesa-dev
mailing list