From 4f6ce51d69612ae448bcfed7b7e27fa9ace5b756 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 4 Jan 2023 16:51:08 -0800 Subject: [PATCH] VideoCommon: Clear blend configuration if color/alpha update disabled This works around an Intel driver bug where, on D3D12 only, dual-source blending behaves incorrectly if the second source is unused on. This bug is visible in skyboxes in Super Mario Sunshine, which first draw clouds and sun flare in greyscale and then draw the sky afterwards with a source factor of 1 and a dest factor of 1-src_color (this results in the clouds being tinted blue). This process is done on an RGB888 framebuffer, so alpha update is disabled. (Color update is enabled; note that if you look at this in Dolphin's fifo analyzer, it won't be enabled because they use the BP mask functionality to only change the blending functions and not alpha/color update, for whatever reason.) --- Source/Core/VideoCommon/RenderState.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp index 93359e13df..0860488b8a 100644 --- a/Source/Core/VideoCommon/RenderState.cpp +++ b/Source/Core/VideoCommon/RenderState.cpp @@ -180,6 +180,22 @@ void BlendingState::Generate(const BPMemory& bp) } } } + + // If we aren't writing color or alpha, don't blend it. + // Intel GPUs on D3D12 seem to have issues with dual-source blend if the second source is used in + // the blend state but not actually written (i.e. the alpha src or dst factor is src alpha, but + // alpha update is disabled). So, change the blending configuration to not use a dual-source + // factor. Note that in theory, disabling writing should render these irrelevant. + if (!colorupdate) + { + srcfactor = SrcBlendFactor::Zero; + dstfactor = DstBlendFactor::One; + } + if (!alphaupdate) + { + srcfactoralpha = SrcBlendFactor::Zero; + dstfactoralpha = DstBlendFactor::One; + } } void BlendingState::ApproximateLogicOpWithBlending()