Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2022-07-17 17:44:03 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2022-07-17 17:44:03 +0300
commit88fcb60b010fc4a587a35932553efd4050c73255 (patch)
tree318b4034ccad060f51b9ec1d9afe43246f7724af
parenta3c5ff4cdc3632298e47576ebfb467e6653c9937 (diff)
[dxvk] Fix blending with A8 render targetsrt-output-swizzle
-rw-r--r--src/dxvk/dxvk_graphics.cpp10
-rw-r--r--src/dxvk/dxvk_util.cpp42
-rw-r--r--src/dxvk/dxvk_util.h12
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);