From 5ff5d0a89531474ad181f5b1f5bd018e2e354999 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 2 May 2019 21:14:49 -0700 Subject: [PATCH] iris: Disable dual source blending when shader doesn't handle it This is a port of Danylo's eca4a6548d07bbbb02a7768edb397bad7b72cfc2 which fixed the hang on i965. It fixes GPU hangs in his new Piglit test, arb_blend_func_extended-dual-src-blending-discard-without-src1. I avoided my own review feedback here, and decided to simply adjust 3DSTATE_PS_BLEND rather than BLEND_STATE_ENTRY[0]. It has never been clear to me which the hardware uses in every case. However, whacking the enable in 3DSTATE_PS_BLEND seems to be sufficient to fix the hang, and that packet is already dynamic, so it's easy to handle. I'd rather avoid making BLEND_STATE_ENTRY[0] dynamic unless I have to. --- src/gallium/drivers/iris/iris_state.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 60d409b5301..677fa5aba53 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -984,13 +984,16 @@ iris_create_blend_state(struct pipe_context *ctx, } iris_pack_command(GENX(3DSTATE_PS_BLEND), cso->ps_blend, pb) { - /* pb.HasWriteableRT is filled in at draw time. */ - /* pb.AlphaTestEnable is filled in at draw time. */ + /* pb.HasWriteableRT is filled in at draw time. + * pb.AlphaTestEnable is filled in at draw time. + * + * pb.ColorBufferBlendEnable is filled in at draw time so we can avoid + * setting it when dual color blending without an appropriate shader. + */ + pb.AlphaToCoverageEnable = state->alpha_to_coverage; pb.IndependentAlphaBlendEnable = indep_alpha_blend; - pb.ColorBufferBlendEnable = state->rt[0].blend_enable; - pb.SourceBlendFactor = fix_blendfactor(state->rt[0].rgb_src_factor, state->alpha_to_one); pb.SourceAlphaBlendFactor = @@ -4851,6 +4854,14 @@ iris_upload_dirty_render_state(struct iris_context *ice, iris_pack_command(GENX(3DSTATE_PS_BLEND), &dynamic_pb, pb) { pb.HasWriteableRT = has_writeable_rt(cso_blend, fs_info); pb.AlphaTestEnable = cso_zsa->alpha.enabled; + + /* The dual source blending docs caution against using SRC1 factors + * when the shader doesn't use a dual source render target write. + * Empirically, this can lead to GPU hangs, and the results are + * undefined anyway, so simply disable blending to avoid the hang. + */ + pb.ColorBufferBlendEnable = (cso_blend->blend_enables & 1) && + (!cso_blend->dual_color_blending || wm_prog_data->dual_src_blend); } iris_emit_merge(batch, cso_blend->ps_blend, dynamic_pb, -- 2.30.2