On Friday, June 16, 2017 4:31:25 PM PDT Rafael Antognolli wrote: > Use set_blend_entry_bits and set_depth_stencil_bits to fill most of the > color calc struct, and then manually update the rest. > > Signed-off-by: Rafael Antognolli <[email protected]> > --- > src/mesa/drivers/dri/i965/brw_cc.c | 174 > -------------------------- > src/mesa/drivers/dri/i965/brw_state.h | 1 - > src/mesa/drivers/dri/i965/brw_structs.h | 92 -------------- > src/mesa/drivers/dri/i965/brw_util.h | 1 - > src/mesa/drivers/dri/i965/genX_state_upload.c | 99 ++++++++++++--- > 5 files changed, 81 insertions(+), 286 deletions(-) > > diff --git a/src/mesa/drivers/dri/i965/brw_cc.c > b/src/mesa/drivers/dri/i965/brw_cc.c > index cdaa696..503ec83 100644 > --- a/src/mesa/drivers/dri/i965/brw_cc.c > +++ b/src/mesa/drivers/dri/i965/brw_cc.c > @@ -39,180 +39,6 @@ > #include "main/stencil.h" > #include "intel_batchbuffer.h" > > -/** > - * Modify blend function to force destination alpha to 1.0 > - * > - * If \c function specifies a blend function that uses destination alpha, > - * replace it with a function that hard-wires destination alpha to 1.0. This > - * is used when rendering to xRGB targets. > - */ > -GLenum > -brw_fix_xRGB_alpha(GLenum function) > -{ > - switch (function) { > - case GL_DST_ALPHA: > - return GL_ONE; > - > - case GL_ONE_MINUS_DST_ALPHA: > - case GL_SRC_ALPHA_SATURATE: > - return GL_ZERO; > - } > - > - return function; > -} > - > -/** > - * Creates a CC unit packet from the current blend state. > - */ > -static void upload_cc_unit(struct brw_context *brw) > -{ > - struct gl_context *ctx = &brw->ctx; > - struct brw_cc_unit_state *cc; > - > - cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset); > - memset(cc, 0, sizeof(*cc)); > - > - /* _NEW_STENCIL | _NEW_BUFFERS */ > - if (ctx->Stencil._Enabled) { > - const unsigned back = ctx->Stencil._BackFace; > - > - cc->cc0.stencil_enable = 1; > - cc->cc0.stencil_func = > - intel_translate_compare_func(ctx->Stencil.Function[0]); > - cc->cc0.stencil_fail_op = > - intel_translate_stencil_op(ctx->Stencil.FailFunc[0]); > - cc->cc0.stencil_pass_depth_fail_op = > - intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]); > - cc->cc0.stencil_pass_depth_pass_op = > - intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]); > - cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0); > - cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0]; > - cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0]; > - > - if (ctx->Stencil._TestTwoSide) { > - cc->cc0.bf_stencil_enable = 1; > - cc->cc0.bf_stencil_func = > - intel_translate_compare_func(ctx->Stencil.Function[back]); > - cc->cc0.bf_stencil_fail_op = > - intel_translate_stencil_op(ctx->Stencil.FailFunc[back]); > - cc->cc0.bf_stencil_pass_depth_fail_op = > - intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]); > - cc->cc0.bf_stencil_pass_depth_pass_op = > - intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]); > - cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back); > - cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back]; > - cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back]; > - } > - > - /* Not really sure about this: > - */ > - if (ctx->Stencil.WriteMask[0] || > - (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[back])) > - cc->cc0.stencil_write_enable = 1; > - } > - > - /* _NEW_COLOR */ > - if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) { > - cc->cc2.logicop_enable = 1; > - cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp); > - } else if (ctx->Color.BlendEnabled && !ctx->Color._AdvancedBlendMode) { > - GLenum eqRGB = ctx->Color.Blend[0].EquationRGB; > - GLenum eqA = ctx->Color.Blend[0].EquationA; > - GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; > - GLenum dstRGB = ctx->Color.Blend[0].DstRGB; > - GLenum srcA = ctx->Color.Blend[0].SrcA; > - GLenum dstA = ctx->Color.Blend[0].DstA; > - > - if (eqRGB == GL_MIN || eqRGB == GL_MAX) { > - srcRGB = dstRGB = GL_ONE; > - } > - > - if (eqA == GL_MIN || eqA == GL_MAX) { > - srcA = dstA = GL_ONE; > - } > - > - /* If the renderbuffer is XRGB, we have to frob the blend function to > - * force the destination alpha to 1.0. This means replacing > GL_DST_ALPHA > - * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO. > - */ > - const struct gl_renderbuffer *rb = > ctx->DrawBuffer->_ColorDrawBuffers[0]; > - 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); > - } > - > - cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB); > - cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB); > - cc->cc6.blend_function = brw_translate_blend_equation(eqRGB); > - > - cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA); > - cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA); > - cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA); > - > - cc->cc3.blend_enable = 1; > - cc->cc3.ia_blend_enable = (srcA != srcRGB || > - dstA != dstRGB || > - eqA != eqRGB); > - } > - > - /* _NEW_BUFFERS */ > - if (ctx->Color.AlphaEnabled && ctx->DrawBuffer->_NumColorDrawBuffers <= > 1) { > - cc->cc3.alpha_test = 1; > - cc->cc3.alpha_test_func = > - intel_translate_compare_func(ctx->Color.AlphaFunc); > - cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; > - > - UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef); > - } > - > - if (ctx->Color.DitherFlag) { > - cc->cc5.dither_enable = 1; > - cc->cc6.y_dither_offset = 0; > - cc->cc6.x_dither_offset = 0; > - } > - > - /* _NEW_DEPTH */ > - if (ctx->Depth.Test) { > - cc->cc2.depth_test = 1; > - cc->cc2.depth_test_function = > - intel_translate_compare_func(ctx->Depth.Func); > - cc->cc2.depth_write_enable = brw_depth_writes_enabled(brw); > - } > - > - if (brw->stats_wm) > - cc->cc5.statistics_enable = 1; > - > - /* BRW_NEW_CC_VP */ > - cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset64 + > - brw->cc.vp_offset) >> 5; /* reloc */ > - > - brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE; > - > - /* Emit CC viewport relocation */ > - brw_emit_reloc(&brw->batch, > - (brw->cc.state_offset + > - offsetof(struct brw_cc_unit_state, cc4)), > - brw->batch.bo, brw->cc.vp_offset, > - I915_GEM_DOMAIN_INSTRUCTION, 0); > -} > - > -const struct brw_tracked_state brw_cc_unit = { > - .dirty = { > - .mesa = _NEW_BUFFERS | > - _NEW_COLOR | > - _NEW_DEPTH | > - _NEW_STENCIL, > - .brw = BRW_NEW_BATCH | > - BRW_NEW_BLORP | > - BRW_NEW_CC_VP | > - BRW_NEW_STATS_WM, > - }, > - .emit = upload_cc_unit, > -}; > - > static void upload_blend_constant_color(struct brw_context *brw) > { > struct gl_context *ctx = &brw->ctx; > diff --git a/src/mesa/drivers/dri/i965/brw_state.h > b/src/mesa/drivers/dri/i965/brw_state.h > index 5f5ba64..ead0078 100644 > --- a/src/mesa/drivers/dri/i965/brw_state.h > +++ b/src/mesa/drivers/dri/i965/brw_state.h > @@ -42,7 +42,6 @@ extern "C" { > enum intel_msaa_layout; > > extern const struct brw_tracked_state brw_blend_constant_color; > -extern const struct brw_tracked_state brw_cc_unit; > extern const struct brw_tracked_state brw_clip_unit; > extern const struct brw_tracked_state brw_vs_pull_constants; > extern const struct brw_tracked_state brw_tcs_pull_constants; > diff --git a/src/mesa/drivers/dri/i965/brw_structs.h > b/src/mesa/drivers/dri/i965/brw_structs.h > index 6d3f80d..12f3024 100644 > --- a/src/mesa/drivers/dri/i965/brw_structs.h > +++ b/src/mesa/drivers/dri/i965/brw_structs.h > @@ -180,98 +180,6 @@ struct brw_clip_unit_state > float viewport_ymax; > }; > > -struct brw_cc_unit_state > -{ > - struct > - { > - unsigned pad0:3; > - unsigned bf_stencil_pass_depth_pass_op:3; > - unsigned bf_stencil_pass_depth_fail_op:3; > - unsigned bf_stencil_fail_op:3; > - unsigned bf_stencil_func:3; > - unsigned bf_stencil_enable:1; > - unsigned pad1:2; > - unsigned stencil_write_enable:1; > - unsigned stencil_pass_depth_pass_op:3; > - unsigned stencil_pass_depth_fail_op:3; > - unsigned stencil_fail_op:3; > - unsigned stencil_func:3; > - unsigned stencil_enable:1; > - } cc0; > - > - > - struct > - { > - unsigned bf_stencil_ref:8; > - unsigned stencil_write_mask:8; > - unsigned stencil_test_mask:8; > - unsigned stencil_ref:8; > - } cc1; > - > - > - struct > - { > - unsigned logicop_enable:1; > - unsigned pad0:10; > - unsigned depth_write_enable:1; > - unsigned depth_test_function:3; > - unsigned depth_test:1; > - unsigned bf_stencil_write_mask:8; > - unsigned bf_stencil_test_mask:8; > - } cc2; > - > - > - struct > - { > - unsigned pad0:8; > - unsigned alpha_test_func:3; > - unsigned alpha_test:1; > - unsigned blend_enable:1; > - unsigned ia_blend_enable:1; > - unsigned pad1:1; > - unsigned alpha_test_format:1; > - unsigned pad2:16; > - } cc3; > - > - struct > - { > - unsigned pad0:5; > - unsigned cc_viewport_state_offset:27; /* Offset from > GENERAL_STATE_BASE */ > - } cc4; > - > - struct > - { > - unsigned pad0:2; > - unsigned ia_dest_blend_factor:5; > - unsigned ia_src_blend_factor:5; > - unsigned ia_blend_function:3; > - unsigned statistics_enable:1; > - unsigned logicop_func:4; > - unsigned pad1:11; > - unsigned dither_enable:1; > - } cc5; > - > - struct > - { > - unsigned clamp_post_alpha_blend:1; > - unsigned clamp_pre_alpha_blend:1; > - unsigned clamp_range:2; > - unsigned pad0:11; > - unsigned y_dither_offset:2; > - unsigned x_dither_offset:2; > - unsigned dest_blend_factor:5; > - unsigned src_blend_factor:5; > - unsigned blend_function:3; > - } cc6; > - > - struct { > - union { > - float f; > - uint8_t ub[4]; > - } alpha_ref; > - } cc7; > -}; > - > struct brw_gs_unit_state > { > struct thread0 thread0; > diff --git a/src/mesa/drivers/dri/i965/brw_util.h > b/src/mesa/drivers/dri/i965/brw_util.h > index 8142860..095c43a 100644 > --- a/src/mesa/drivers/dri/i965/brw_util.h > +++ b/src/mesa/drivers/dri/i965/brw_util.h > @@ -38,7 +38,6 @@ > > extern GLuint brw_translate_blend_factor( GLenum factor ); > extern GLuint brw_translate_blend_equation( GLenum mode ); > -extern GLenum brw_fix_xRGB_alpha(GLenum function); > > static inline float > brw_get_line_width(struct brw_context *brw) > diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c > b/src/mesa/drivers/dri/i965/genX_state_upload.c > index 8e99c89..d8dcaf4 100644 > --- a/src/mesa/drivers/dri/i965/genX_state_upload.c > +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c > @@ -1177,7 +1177,7 @@ set_depth_stencil_bits(struct brw_context *brw, > DEPTH_STENCIL_GENXML *ds) > struct gl_stencil_attrib *stencil = &ctx->Stencil; > const int b = stencil->_BackFace; > > - if (depth->Test && depth_irb) { > + if (depth->Test && (GEN_GEN <= 5 || depth_irb)) {
We should just always do the depth_irb check.
> ds->DepthTestEnable = true;
> ds->DepthBufferWriteEnable = brw_depth_writes_enabled(brw);
> ds->DepthTestFunction = intel_translate_compare_func(depth->Func);
> @@ -1214,9 +1214,11 @@ set_depth_stencil_bits(struct brw_context *brw,
> DEPTH_STENCIL_GENXML *ds)
> intel_translate_stencil_op(stencil->ZFailFunc[b]);
> }
>
> -#if GEN_GEN >= 9
> +#if GEN_GEN <= 5 || GEN_GEN >= 9
> ds->StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
> - ds->BackfaceStencilReferenceValue = _mesa_get_stencil_ref(ctx, b);
> + ds->BackfaceStencilReferenceValue =
> + GEN_GEN >= 9 || stencil->_TestTwoSide ?
> + _mesa_get_stencil_ref(ctx, b) : 0;
It should be harmless to program the backface ref value - it should
be ignored/unused if _TestTwoSide isn't set. So we could leave this as is.
> #endif
> }
> }
> @@ -2527,6 +2529,28 @@ fix_dual_blend_alpha_to_one(GLenum function)
> #define blend_factor(x) brw_translate_blend_factor(x)
> #define blend_eqn(x) brw_translate_blend_equation(x)
>
> +/**
> + * Modify blend function to force destination alpha to 1.0
> + *
> + * If \c function specifies a blend function that uses destination alpha,
> + * replace it with a function that hard-wires destination alpha to 1.0. This
> + * is used when rendering to xRGB targets.
> + */
> +static GLenum
> +brw_fix_xRGB_alpha(GLenum function)
> +{
> + switch (function) {
> + case GL_DST_ALPHA:
> + return GL_ONE;
> +
> + case GL_ONE_MINUS_DST_ALPHA:
> + case GL_SRC_ALPHA_SATURATE:
> + return GL_ZERO;
> + }
> +
> + return function;
> +}
> +
> #if GEN_GEN >= 6
> typedef struct GENX(BLEND_STATE_ENTRY) BLEND_ENTRY_GENXML;
> #else
> @@ -2552,6 +2576,9 @@ set_blend_entry_bits(struct brw_context *brw,
> BLEND_ENTRY_GENXML *entry, int i,
> */
> const bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
>
> + const unsigned blend_enabled = GEN_GEN >= 6 ?
> + ctx->Color.BlendEnabled & (1 << i) : ctx->Color.BlendEnabled;
> +
I think always using ctx->Color.BlendEnabled & (1 << i) should be fine.
That corresponds to the enable bit for blend entry 0, which is the
only one we're handling here. (Gen4-5 only support a single entry.)
> /* _NEW_COLOR */
> if (ctx->Color.ColorLogicOpEnabled) {
> GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
> @@ -2567,8 +2594,8 @@ set_blend_entry_bits(struct brw_context *brw,
> BLEND_ENTRY_GENXML *entry, int i,
> entry->LogicOpFunction =
> intel_translate_logic_op(ctx->Color.LogicOp);
> }
> - } else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
> - !ctx->Color._AdvancedBlendMode) {
> + } else if (blend_enabled && !ctx->Color._AdvancedBlendMode
> + && (GEN_GEN <= 5 || !integer)) {
The GEN_GEN <= 5 || !integer seems bizarre, and I wonder whether it's
correct. However, you're just preserving the existing behavior, so
that's fine - we may want to revisit it in the future.
> GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
> GLenum eqA = ctx->Color.Blend[i].EquationA;
> GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
> @@ -2994,17 +3021,40 @@ static const struct brw_tracked_state
> genX(multisample_state) = {
>
> /* ---------------------------------------------------------------------- */
>
> -#if GEN_GEN >= 6
> static void
> genX(upload_color_calc_state)(struct brw_context *brw)
> {
> struct gl_context *ctx = &brw->ctx;
>
> brw_state_emit(brw, GENX(COLOR_CALC_STATE), 64, &brw->cc.state_offset,
> cc) {
> +#if GEN_GEN <= 5
> + cc.IndependentAlphaBlendEnable =
> + set_blend_entry_bits(brw, &cc, 0, false);
> + set_depth_stencil_bits(brw, &cc);
> +
> + if (ctx->Color.AlphaEnabled &&
> + ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
> + cc.AlphaTestEnable = true;
> + cc.AlphaTestFunction =
> + intel_translate_compare_func(ctx->Color.AlphaFunc);
> + }
We should probably make this consistent across generations:
if (ctx->Color.AlphaEnabled &&
(GEN_GEN >= 6 || ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
cc.AlphaTestEnable = true;
cc.AlphaTestFunction =
intel_translate_compare_func(ctx->Color.AlphaFunc);
cc.AlphaTestFormat = ALPHATEST_UNORM8;
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
ctx->Color.AlphaRef);
}
Alternatively, it should be harmless to set AlphaTestFormat,
AlphaReferenceValueAsUNORM8, and AlphaTestFunction even if alpha testing
is disabled, so we could also do:
cc.AlphaTestEnable = ctx->Color.AlphaEnabled &&
(GEN_GEN >= 6 || ctx->DrawBuffer->_NumColorDrawBuffers <= 1);
cc.AlphaTestFormat = ALPHATEST_UNORM8;
cc.AlphaTestFunction =
intel_translate_compare_func(ctx->Color.AlphaFunc);
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
ctx->Color.AlphaRef);1
I suppose that does a bit of extra work when alpha testing is disabled.
> +
> + if (ctx->Color.DitherFlag) {
> + cc.ColorDitherEnable = true;
> + cc.XDitherOffset = 0;
> + cc.YDitherOffset = 0;
> + }
I'd probably write this as:
cc.ColorDitherEnable = ctx->Color.DitherFlag;
(the offset values will be zero-initialized by default).
> +
> + cc.StatisticsEnable = brw->stats_wm;
> +
> + cc.CCViewportStatePointer =
> + instruction_ro_bo(brw->batch.bo, brw->cc.vp_offset);
> +#else
> /* _NEW_COLOR */
> - cc.AlphaTestFormat = ALPHATEST_UNORM8;
> - UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
> - ctx->Color.AlphaRef);
> + cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
> + cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
> + cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
> + cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
>
> #if GEN_GEN < 9
> /* _NEW_STENCIL */
> @@ -3013,34 +3063,47 @@ genX(upload_color_calc_state)(struct brw_context *brw)
> _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
> #endif
>
> +#endif
> +
> /* _NEW_COLOR */
> - cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
> - cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
> - cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
> - cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
> + if (GEN_GEN >= 6 ||
> + (ctx->Color.AlphaEnabled &&
> + ctx->DrawBuffer->_NumColorDrawBuffers <= 1)) {
> + cc.AlphaTestFormat = ALPHATEST_UNORM8;
> + UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
> + ctx->Color.AlphaRef);
> + }
> }
>
> +#if GEN_GEN >= 6
> brw_batch_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), ptr) {
> ptr.ColorCalcStatePointer = brw->cc.state_offset;
> #if GEN_GEN != 7
> ptr.ColorCalcStatePointerValid = true;
> #endif
> }
> +#endif
> +
> + brw->ctx.NewDriverState |= GEN_GEN <= 5 ? BRW_NEW_GEN4_UNIT_STATE : 0;
Perhaps just do:
#if GEN_GEN >= 6
...
#else
ctx->NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
#endif
since we've already got generation-specific code blocks here.
> }
>
> static const struct brw_tracked_state genX(color_calc_state) = {
> .dirty = {
> .mesa = _NEW_COLOR |
> - _NEW_STENCIL,
> + _NEW_STENCIL |
> + (GEN_GEN <= 5 ? _NEW_BUFFERS |
> + _NEW_DEPTH
> + : 0),
> .brw = BRW_NEW_BATCH |
> BRW_NEW_BLORP |
> - BRW_NEW_CC_STATE |
> - BRW_NEW_STATE_BASE_ADDRESS,
> + (GEN_GEN <= 5 ? BRW_NEW_CC_VP |
> + BRW_NEW_STATS_WM
> + : BRW_NEW_CC_STATE |
> + BRW_NEW_STATE_BASE_ADDRESS),
> },
> .emit = genX(upload_color_calc_state),
> };
>
> -#endif
>
> /* ---------------------------------------------------------------------- */
>
> @@ -4252,7 +4315,7 @@ genX(init_atoms)(struct brw_context *brw)
> &brw_recalculate_urb_fence,
>
> &genX(cc_vp),
> - &brw_cc_unit,
> + &genX(color_calc_state),
>
> /* Surface state setup. Must come before the VS/WM unit. The binding
> * table upload must be last.
>
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
