diff options
author | Danylo Piliaiev <[email protected]> | 2018-07-02 17:04:23 +0300 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2018-10-30 12:59:53 -0700 |
commit | eca4a6548d07bbbb02a7768edb397bad7b72cfc2 (patch) | |
tree | b41b5e10d281c07f20549d15ab0d9d84b55540ca /src/mesa | |
parent | 337a808062c756b474ee80a9ac04b5a3dbbeb67e (diff) |
i965: 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, 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 (Kenneth Graunke):
- Listen to BRW_NEW_FS_PROG_DATA in 3DSTATE_PS_BLEND
- Also whack BLEND_STATE[] to keep the two in sync, since we're not
sure exactly which copy of the redundant info the hardware will use.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107088
Signed-off-by: Danylo Piliaiev <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/genX_state_upload.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index 740cb0c4d2e..9cd017a5cff 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -3051,7 +3051,26 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i, dstA = fix_dual_blend_alpha_to_one(dstA); } - entry->ColorBufferBlendEnable = true; + /* BRW_NEW_FS_PROG_DATA */ + const struct brw_wm_prog_data *wm_prog_data = + brw_wm_prog_data(brw->wm.base.prog_data); + + /* 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). + * If SRC1 is not included in a src/dst blend factor, + * dual source blending must be disabled." + * + * There is no way to gracefully fix this undefined situation + * so we just disable the blending to prevent possible issues. + */ + entry->ColorBufferBlendEnable = + !ctx->Color.Blend[0]._UsesDualSrc || wm_prog_data->dual_src_blend; + entry->DestinationBlendFactor = blend_factor(dstRGB); entry->SourceBlendFactor = blend_factor(srcRGB); entry->DestinationAlphaBlendFactor = blend_factor(dstA); @@ -3197,6 +3216,7 @@ static const struct brw_tracked_state genX(blend_state) = { _NEW_MULTISAMPLE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FS_PROG_DATA | BRW_NEW_STATE_BASE_ADDRESS, }, .emit = genX(upload_blend_state), @@ -4829,7 +4849,25 @@ genX(upload_ps_blend)(struct brw_context *brw) dstA = fix_dual_blend_alpha_to_one(dstA); } - pb.ColorBufferBlendEnable = true; + /* BRW_NEW_FS_PROG_DATA */ + const struct brw_wm_prog_data *wm_prog_data = + brw_wm_prog_data(brw->wm.base.prog_data); + + /* 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). + * If SRC1 is not included in a src/dst blend factor, + * dual source blending must be disabled." + * + * There is no way to gracefully fix this undefined situation + * so we just disable the blending to prevent possible issues. + */ + pb.ColorBufferBlendEnable = + !color->Blend[0]._UsesDualSrc || wm_prog_data->dual_src_blend; pb.SourceAlphaBlendFactor = brw_translate_blend_factor(srcA); pb.DestinationAlphaBlendFactor = brw_translate_blend_factor(dstA); pb.SourceBlendFactor = brw_translate_blend_factor(srcRGB); @@ -4848,7 +4886,8 @@ static const struct brw_tracked_state genX(ps_blend) = { _NEW_MULTISAMPLE, .brw = BRW_NEW_BLORP | BRW_NEW_CONTEXT | - BRW_NEW_FRAGMENT_PROGRAM, + BRW_NEW_FRAGMENT_PROGRAM | + BRW_NEW_FS_PROG_DATA, }, .emit = genX(upload_ps_blend) }; |