[dxvk] Fix blending with A8 render targets

This commit is contained in:
Philip Rebohle 2022-07-17 16:44:03 +02:00
parent f15466a2c5
commit 8d1b9eca5d
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 63 additions and 1 deletions

View File

@ -250,6 +250,16 @@ namespace dxvk {
if (writeMask) {
cbAttachments[i] = state.omBlend[i].state();
cbAttachments[i].colorWriteMask = writeMask;
// If we're rendering to an emulated alpha-only render target, fix up blending
if (cbAttachments[i].blendEnable && formatInfo->componentMask == VK_COLOR_COMPONENT_R_BIT && state.omSwizzle[i].rIndex() == 3) {
cbAttachments[i].srcColorBlendFactor = util::remapAlphaToColorBlendFactor(
std::exchange(cbAttachments[i].srcAlphaBlendFactor, VK_BLEND_FACTOR_ONE));
cbAttachments[i].dstColorBlendFactor = util::remapAlphaToColorBlendFactor(
std::exchange(cbAttachments[i].dstAlphaBlendFactor, VK_BLEND_FACTOR_ZERO));
cbAttachments[i].colorBlendOp =
std::exchange(cbAttachments[i].alphaBlendOp, VK_BLEND_OP_ADD);
}
}
}
}

View File

@ -272,6 +272,48 @@ namespace dxvk::util {
}
VkBlendFactor remapAlphaToColorBlendFactor(VkBlendFactor factor) {
switch (factor) {
// Make sure we use the red component from the
// fragment shader since alpha may be undefined
case VK_BLEND_FACTOR_SRC_ALPHA:
return VK_BLEND_FACTOR_SRC_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case VK_BLEND_FACTOR_SRC1_ALPHA:
return VK_BLEND_FACTOR_SRC1_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
// This is defined to always be 1 for alpha
case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE:
return VK_BLEND_FACTOR_ONE;
// Make sure we use the red component from the
// attachment since there is no alpha component
case VK_BLEND_FACTOR_DST_ALPHA:
return VK_BLEND_FACTOR_DST_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
// For blend constants we actually need to do the
// opposite and make sure we always use alpha
case VK_BLEND_FACTOR_CONSTANT_COLOR:
return VK_BLEND_FACTOR_CONSTANT_ALPHA;
case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
default:
return factor;
}
}
bool isIdentityMapping(
VkComponentMapping mapping) {
return (mapping.r == VK_COMPONENT_SWIZZLE_R || mapping.r == VK_COMPONENT_SWIZZLE_IDENTITY)

View File

@ -339,7 +339,17 @@ namespace dxvk::util {
VkComponentMapping resolveSrcComponentMapping(
VkComponentMapping dstMapping,
VkComponentMapping srcMapping);
/**
* \brief Remaps alpha blend factor to a color one
*
* Needed when rendering to alpha-only render targets
* which we only support through single-channel formats.
* \param [in] factor Alpha blend factor
* \returns Corresponding color blend factor
*/
VkBlendFactor remapAlphaToColorBlendFactor(VkBlendFactor factor);
bool isIdentityMapping(
VkComponentMapping mapping);