bump. I can add test to Crucible if it will help.

On 20.07.18 12:54, Danylo Piliaiev wrote:
Dual source blending behaviour is undefined when shader doesn't
have second color output.

  "If SRC1 is included in a src/dst blend factor and
   a DualSource RT Write message is not used, results
   are UNDEFINED. (This reflects the same restriction in DX APIs,
   where undefined results are produced if “o1” is not written
   by a PS – there are no default values defined)."

Dismissing fragment in such situation leads to a hang on gen8+
if depth test in enabled.

Since blending cannot be gracefully fixed in such case and the result
is undefined - blending is simply disabled.

Signed-off-by: Danylo Piliaiev <danylo.pilia...@globallogic.com>
---

Also there is a similar patch which fixes the same issue
for OpenGL https://patchwork.freedesktop.org/patch/235939

  src/intel/vulkan/genX_pipeline.c | 43 ++++++++++++++++++++++++--------
  1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 0821d71c9f..d7c532a22d 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -854,6 +854,15 @@ emit_ds_state(struct anv_pipeline *pipeline,
  #endif
  }
+MAYBE_UNUSED static bool
+is_dual_src_blend_factor(VkBlendFactor factor)
+{
+   return factor == VK_BLEND_FACTOR_SRC1_COLOR ||
+          factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR ||
+          factor == VK_BLEND_FACTOR_SRC1_ALPHA ||
+          factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
+}
+
  static void
  emit_cb_state(struct anv_pipeline *pipeline,
                const VkPipelineColorBlendStateCreateInfo *info,
@@ -886,6 +895,7 @@ emit_cb_state(struct anv_pipeline *pipeline,
     state_pos += GENX(BLEND_STATE_length);
  #if GEN_GEN >= 8
     struct GENX(BLEND_STATE_ENTRY) bs0 = { 0 };
+   bool force_disable_color_blend = false;
  #endif
     for (unsigned i = 0; i < surface_count; i++) {
        struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i];
@@ -969,8 +979,27 @@ emit_cb_state(struct anv_pipeline *pipeline,
        GENX(BLEND_STATE_ENTRY_pack)(NULL, state_pos, &entry);
        state_pos += GENX(BLEND_STATE_ENTRY_length);
  #if GEN_GEN >= 8
-      if (i == 0)
+      if (i == 0) {
           bs0 = entry;
+
+         /* The Dual Source Blending documentation says:
+          *
+          * "If SRC1 is included in a src/dst blend factor and
+          * a DualSource RT Write message is not used, results
+          * are UNDEFINED. (This reflects the same restriction in DX APIs,
+          * where undefined results are produced if “o1” is not written
+          * by a PS – there are no default values defined)."
+          *
+          * There is no way to gracefully fix this undefined situation
+          * so we just disable the blending to prevent possible issues.
+          */
+         const struct brw_wm_prog_data *wm_prog_data = 
get_wm_prog_data(pipeline);
+         force_disable_color_blend = !wm_prog_data->dual_src_blend &&
+            (is_dual_src_blend_factor(a->srcColorBlendFactor) ||
+            is_dual_src_blend_factor(a->dstColorBlendFactor) ||
+            is_dual_src_blend_factor(a->srcAlphaBlendFactor) ||
+            is_dual_src_blend_factor(a->dstAlphaBlendFactor));
+      }
  #endif
     }
@@ -978,7 +1007,8 @@ emit_cb_state(struct anv_pipeline *pipeline,
     anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) {
        blend.AlphaToCoverageEnable         = blend_state.AlphaToCoverageEnable;
        blend.HasWriteableRT                = has_writeable_rt;
-      blend.ColorBufferBlendEnable        = bs0.ColorBufferBlendEnable;
+      blend.ColorBufferBlendEnable        =
+         bs0.ColorBufferBlendEnable && !force_disable_color_blend;
        blend.SourceAlphaBlendFactor        = bs0.SourceAlphaBlendFactor;
        blend.DestinationAlphaBlendFactor   = bs0.DestinationAlphaBlendFactor;
        blend.SourceBlendFactor             = bs0.SourceBlendFactor;
@@ -1430,15 +1460,6 @@ emit_3dstate_wm(struct anv_pipeline *pipeline, struct 
anv_subpass *subpass,
     }
  }
-UNUSED static bool
-is_dual_src_blend_factor(VkBlendFactor factor)
-{
-   return factor == VK_BLEND_FACTOR_SRC1_COLOR ||
-          factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR ||
-          factor == VK_BLEND_FACTOR_SRC1_ALPHA ||
-          factor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
-}
-
  static void
  emit_3dstate_ps(struct anv_pipeline *pipeline,
                  const VkPipelineColorBlendStateCreateInfo *blend,

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to