diff options
author | Danylo Piliaiev <[email protected]> | 2018-07-20 12:54:42 +0300 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2018-10-30 12:59:53 -0700 |
commit | 00fc56a68d21d7aa91b95f0eaacba59a96c466f5 (patch) | |
tree | 9eb37e00be0650684b871ac6a80dc53cda03ae97 | |
parent | eca4a6548d07bbbb02a7768edb397bad7b72cfc2 (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.c | 46 |
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, |