summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanylo Piliaiev <[email protected]>2018-07-20 12:54:42 +0300
committerKenneth Graunke <[email protected]>2018-10-30 12:59:53 -0700
commit00fc56a68d21d7aa91b95f0eaacba59a96c466f5 (patch)
tree9eb37e00be0650684b871ac6a80dc53cda03ae97
parenteca4a6548d07bbbb02a7768edb397bad7b72cfc2 (diff)
anv: Disable dual source blending when shader doesn't support it on gen8+
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. v2 (Jason Ekstrand): - Apply the workaround to each individual entry - Emit a warning through debug_report Signed-off-by: Danylo Piliaiev <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/intel/vulkan/genX_pipeline.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index e34dea431ec..cc485541763 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -882,13 +882,22 @@ 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,
const VkPipelineMultisampleStateCreateInfo *ms_info)
{
struct anv_device *device = pipeline->device;
-
+ const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
struct GENX(BLEND_STATE) blend_state = {
#if GEN_GEN >= 8
@@ -975,6 +984,32 @@ emit_cb_state(struct anv_pipeline *pipeline,
#endif
}
+ /* 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.
+ */
+ if (!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))) {
+ vk_debug_report(&device->instance->debug_report_callbacks,
+ VK_DEBUG_REPORT_WARNING_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+ (uint64_t)(uintptr_t)device,
+ 0, 0, "anv",
+ "Enabled dual-src blend factors without writing both targets "
+ "in the shader. Disabling blending to avoid GPU hangs.");
+ entry.ColorBufferBlendEnable = false;
+ }
+
if (a->colorWriteMask != 0)
has_writeable_rt = true;
@@ -1508,15 +1543,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,