anv/gen7: only enable dual-source blending when there are dual-source factors
authorIlia Mirkin <imirkin@alum.mit.edu>
Thu, 24 Nov 2016 02:43:38 +0000 (21:43 -0500)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 24 Nov 2016 03:40:00 +0000 (19:40 -0800)
Apparently the hw wedges otherwise, as mentioned in i965 comments.

Reported-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/vulkan/genX_pipeline.c

index 9d985752f8cab9d533cc43684392ae157befeb5f..cb164addfbdf40d2a85223660fe8457e3e13c385 100644 (file)
@@ -1100,8 +1100,18 @@ emit_3dstate_wm(struct anv_pipeline *pipeline, struct anv_subpass *subpass,
    }
 }
 
+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)
+emit_3dstate_ps(struct anv_pipeline *pipeline,
+                const VkPipelineColorBlendStateCreateInfo *blend)
 {
    MAYBE_UNUSED const struct gen_device_info *devinfo = &pipeline->device->info;
    const struct anv_shader_bin *fs_bin =
@@ -1121,6 +1131,26 @@ emit_3dstate_ps(struct anv_pipeline *pipeline)
 
    const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
 
+#if GEN_GEN < 8
+   /* The hardware wedges if you have this bit set but don't turn on any dual
+    * source blend factors.
+    */
+   bool dual_src_blend = false;
+   if (wm_prog_data->dual_src_blend) {
+      for (uint32_t i = 0; i < blend->attachmentCount; i++) {
+         VkPipelineColorBlendAttachmentState *bstate = &blend->pAttachments[i];
+         if (bstate->blendEnable &&
+             (is_dual_src_blend_factor(bstate->srcColorBlendFactor) ||
+              is_dual_src_blend_factor(bstate->dstColorBlendFactor) ||
+              is_dual_src_blend_factor(bstate->srcAlphaBlendFactor) ||
+              is_dual_src_blend_factor(bstate->dstAlphaBlendFactor))) {
+            dual_src_blend = true;
+            break;
+         }
+      }
+   }
+#endif
+
    anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS), ps) {
       ps.KernelStartPointer0        = fs_bin->kernel.offset;
       ps.KernelStartPointer1        = 0;
@@ -1140,7 +1170,7 @@ emit_3dstate_ps(struct anv_pipeline *pipeline)
 #if GEN_GEN < 8
       ps.AttributeEnable            = wm_prog_data->num_varying_inputs > 0;
       ps.oMaskPresenttoRenderTarget = wm_prog_data->uses_omask;
-      ps.DualSourceBlendEnable      = wm_prog_data->dual_src_blend;
+      ps.DualSourceBlendEnable      = dual_src_blend;
 #endif
 
 #if GEN_IS_HASWELL
@@ -1286,7 +1316,7 @@ genX(graphics_pipeline_create)(
    emit_3dstate_gs(pipeline);
    emit_3dstate_sbe(pipeline);
    emit_3dstate_wm(pipeline, subpass, pCreateInfo->pMultisampleState);
-   emit_3dstate_ps(pipeline);
+   emit_3dstate_ps(pipeline, pCreateInfo->pColorBlendState);
 #if GEN_GEN >= 8
    emit_3dstate_ps_extra(pipeline, subpass);
    emit_3dstate_vf_topology(pipeline);