iris: Disable dual source blending when shader doesn't handle it
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 3 May 2019 04:14:49 +0000 (21:14 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 3 May 2019 04:14:49 +0000 (21:14 -0700)
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

index 60d409b5301f5fbd56bb02285252c85116711aac..677fa5aba53a4e6f81e3eef66af244363ecb473e 100644 (file)
@@ -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,