[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.
This commit is contained in:
Philip Rebohle 2022-07-15 23:51:04 +02:00
parent 9e7b93b55b
commit e2340d7224
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
1 changed files with 16 additions and 9 deletions

View File

@ -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;
}
}
}