From e2340d722434619214c6651e95a7ab987db50896 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 23:51:04 +0200 Subject: [PATCH] [dxvk] Fix dual-source blending with multiple bound render targets We can't write to more than one render target, so zero out the write mask. Also, normalize blend state for disabled render targets for good measure. --- src/dxvk/dxvk_graphics.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b29d52bda..5a57b1ba5 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -215,6 +215,10 @@ namespace dxvk { // mask for any attachment that the fragment shader does not write to. uint32_t fsOutputMask = fs ? fs->info().outputMask : 0u; + // Dual-source blending can only write to one render target + if (state.useDualSourceBlending()) + fsOutputMask &= 0x1; + const VkColorComponentFlags rgbaWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -229,20 +233,23 @@ namespace dxvk { rtInfo.colorAttachmentCount = i + 1; auto formatInfo = lookupFormatInfo(rtColorFormats[i]); - cbAttachments[i] = state.omBlend[i].state(); - if (!(fsOutputMask & (1 << i)) || !formatInfo) { - cbAttachments[i].colorWriteMask = 0; - } else { - if (cbAttachments[i].colorWriteMask != rgbaWriteMask) { - cbAttachments[i].colorWriteMask = util::remapComponentMask( + if ((fsOutputMask & (1 << i)) && formatInfo) { + VkColorComponentFlags writeMask = state.omBlend[i].colorWriteMask(); + + if (writeMask != rgbaWriteMask) { + writeMask = util::remapComponentMask( state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); } - cbAttachments[i].colorWriteMask &= formatInfo->componentMask; + writeMask &= formatInfo->componentMask; - if (cbAttachments[i].colorWriteMask == formatInfo->componentMask) { - cbAttachments[i].colorWriteMask = rgbaWriteMask; + if (writeMask == formatInfo->componentMask) + writeMask = rgbaWriteMask; + + if (writeMask) { + cbAttachments[i] = state.omBlend[i].state(); + cbAttachments[i].colorWriteMask = writeMask; } } }