From 5d48710981feeaa1b4919195f97a00c4daa9c992 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Thu, 1 Jun 2017 12:28:41 -0700 Subject: [PATCH] i965: Convert CC state on gen4-5 to genxml. Use set_blend_entry_bits and set_depth_stencil_bits to fill most of the color calc struct, and then manually update the rest. v2: - Always check for depth_irb (Ken) - Always set Backface Stencil Ref (Ken) - Always set alpha reference value (Ken) Signed-off-by: Rafael Antognolli Reviewed-by: Kenneth Graunke --- 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 | 84 +++++++-- 5 files changed, 68 insertions(+), 284 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c index 676edaff121..503ec8303a8 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 (brw->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 (brw->stencil_two_sided) { - 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] || - (brw->stencil_two_sided && 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 0a7ff574eb7..748fabaf6be 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 6d3f80dab19..12f3024bfbb 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 814286007de..095c43a88df 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 a5d6f34d3e9..46e7799228d 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -1217,7 +1217,7 @@ 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); #endif @@ -2530,6 +2530,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 @@ -2555,6 +2577,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; + /* _NEW_COLOR */ if (ctx->Color.ColorLogicOpEnabled) { GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format) @@ -2570,8 +2595,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)) { GLenum eqRGB = ctx->Color.Blend[i].EquationRGB; GLenum eqA = ctx->Color.Blend[i].EquationA; GLenum srcRGB = ctx->Color.Blend[i].SrcRGB; @@ -2997,53 +3022,80 @@ 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); + } + + cc.ColorDitherEnable = ctx->Color.DitherFlag; + + 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 */ cc.StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0); cc.BackfaceStencilReferenceValue = _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]; + 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 } +#else + brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE; +#endif } 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 /* ---------------------------------------------------------------------- */ @@ -4924,7 +4976,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. -- 2.30.2