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 <rafael.antogno...@intel.com> > --- > 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 mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev