diff options
author | Philip Rebohle <philip.rebohle@tu-dortmund.de> | 2022-07-17 17:44:03 +0300 |
---|---|---|
committer | Philip Rebohle <philip.rebohle@tu-dortmund.de> | 2022-07-17 17:44:03 +0300 |
commit | 88fcb60b010fc4a587a35932553efd4050c73255 (patch) | |
tree | 318b4034ccad060f51b9ec1d9afe43246f7724af | |
parent | a3c5ff4cdc3632298e47576ebfb467e6653c9937 (diff) |
[dxvk] Fix blending with A8 render targetsrt-output-swizzle
-rw-r--r-- | src/dxvk/dxvk_graphics.cpp | 10 | ||||
-rw-r--r-- | src/dxvk/dxvk_util.cpp | 42 | ||||
-rw-r--r-- | src/dxvk/dxvk_util.h | 12 |
3 files changed, 63 insertions, 1 deletions
diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 948cee55..bffb9bce 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -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); + } } } } diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index ba689c5c..1c229698 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -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) diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index cf26e9c5..a9a4b7ee 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -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); |