From 6b2dec91b531dc96d2fe386bccdd4cadbb71ddd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Apr 2022 22:54:08 +0200 Subject: [PATCH] Finish BlueToAlpha functionality --- GPU/Common/FragmentShaderGenerator.cpp | 4 +++- GPU/Common/GPUStateUtils.cpp | 2 +- GPU/Common/ShaderId.cpp | 3 ++- assets/compat.ini | 1 - 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 896fb9f439..cb965bf782 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -858,7 +858,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " v.rgb = v.rgb * 2.0;\n"); } - if (replaceBlend == REPLACE_BLEND_PRE_SRC || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) { + // In some cases we need to replicate the first half of the blend equation here. + // In case of blue-to-alpha, it's since we overwrite alpha with blue before the actual blend equation runs. + if (replaceBlend == REPLACE_BLEND_PRE_SRC || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA || replaceBlend == REPLACE_BLEND_BLUE_TO_ALPHA) { const char *srcFactor = "ERROR"; switch (replaceBlendFuncA) { case GE_SRCBLEND_DSTCOLOR: srcFactor = "ERROR"; break; diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 8a8b7c70ba..8b27be2d34 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -1332,7 +1332,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead, break; } } else if (blueToAlpha) { - blendState.setFactors(BlendFactor::ZERO, BlendFactor::ZERO, glBlendFuncA, glBlendFuncB); + blendState.setFactors(BlendFactor::ZERO, BlendFactor::ZERO, BlendFactor::ONE, glBlendFuncB); blendState.setEquation(BlendEq::ADD, colorEq); return; } else { diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index dfaac9a675..e879cec1b9 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -190,7 +190,7 @@ std::string FragmentShaderDesc(const FShaderID &id) { if (blendBits) { switch (blendBits) { case ReplaceBlendType::REPLACE_BLEND_BLUE_TO_ALPHA: - desc << "BlueToAlpha"; + desc << "BlueToAlpha_" << "A:" << id.Bits(FS_BIT_BLENDFUNC_A, 4); break; default: desc << "ReplaceBlend_" << id.Bits(FS_BIT_REPLACE_BLEND, 3) @@ -325,6 +325,7 @@ void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) { // If replaceBlend == REPLACE_BLEND_STANDARD (or REPLACE_BLEND_NO) nothing is done, so we kill these bits. if (replaceBlend == REPLACE_BLEND_BLUE_TO_ALPHA) { id.SetBits(FS_BIT_REPLACE_BLEND, 3, replaceBlend); + id.SetBits(FS_BIT_BLENDFUNC_A, 4, gstate.getBlendFuncA()); } else if (replaceBlend > REPLACE_BLEND_STANDARD) { // 3 bits. id.SetBits(FS_BIT_REPLACE_BLEND, 3, replaceBlend); diff --git a/assets/compat.ini b/assets/compat.ini index 214a470e8a..fc17e3e9b1 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -995,7 +995,6 @@ ULES01402 = true ULUS10513 = true ULJM05812 = true NPJH50371 = true - # Some games render first to RGB of a 4444 texture, then they switch to 565 and render masked to blue, # just to be able to render to the alpha channel of the 4444. We can detect that and reroute rendering # to avoid problems.