From 1b769b61b1f2f16fd4fce83e0caaeb627c64bf59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 25 Oct 2024 21:50:03 +0200 Subject: [PATCH] Fragment shader: Don't error on bad blend eqs, instead use default eq (add) --- GPU/Common/FragmentShaderGenerator.cpp | 2 +- GPU/Common/GPUStateUtils.cpp | 7 +++++-- GPU/Common/ShaderId.cpp | 9 ++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 0a182f675a..757cb4d291 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -1118,7 +1118,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " v.rgb = abs(v.rgb - destColor.rgb);\n"); break; default: - *errorString = "Bad replace blend eq"; + *errorString = StringFromFormat("Bad replace blend eq: %d", (int)replaceBlendEq); return false; } } diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 4097d5cce7..f4a7abba97 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -293,11 +293,10 @@ ReplaceBlendType ReplaceBlendWithShader(GEBufferFormat bufferFormat) { case GE_BLENDMODE_MUL_AND_ADD: case GE_BLENDMODE_MUL_AND_SUBTRACT: case GE_BLENDMODE_MUL_AND_SUBTRACT_REVERSE: - // Handled below. + // Other blend equations simply don't blend on hardware. break; default: - // Other blend equations simply don't blend on hardware. return REPLACE_BLEND_NO; } @@ -849,6 +848,8 @@ static const BlendEq eqLookupNoMinMax[] = { BlendEq::ADD, // GE_BLENDMODE_MIN BlendEq::ADD, // GE_BLENDMODE_MAX BlendEq::ADD, // GE_BLENDMODE_ABSDIFF + BlendEq::ADD, + BlendEq::ADD, }; static const BlendEq eqLookup[] = { @@ -858,6 +859,8 @@ static const BlendEq eqLookup[] = { BlendEq::MIN, // GE_BLENDMODE_MIN BlendEq::MAX, // GE_BLENDMODE_MAX BlendEq::MAX, // GE_BLENDMODE_ABSDIFF + BlendEq::ADD, + BlendEq::ADD, }; static BlendFactor toDualSource(BlendFactor blendfunc) { diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 71efcfa683..67f6a687c7 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -277,6 +277,13 @@ bool FragmentIdNeedsFramebufferRead(const FShaderID &id) { (ReplaceBlendType)id.Bits(FS_BIT_REPLACE_BLEND, 3) == REPLACE_BLEND_READ_FRAMEBUFFER; } +inline u32 SanitizeBlendMode(GEBlendMode mode) { + if (mode > GE_BLENDMODE_ABSDIFF) + return GE_BLENDMODE_MUL_AND_ADD; // Not sure what the undefined modes are. + else + return mode; +} + // Here we must take all the bits of the gstate that determine what the fragment shader will // look like, and concatenate them together into an ID. void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pipelineState, const Draw::Bugs &bugs) { @@ -371,7 +378,7 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip // 3 bits. id.SetBits(FS_BIT_REPLACE_BLEND, 3, replaceBlend); // 11 bits total. - id.SetBits(FS_BIT_BLENDEQ, 3, gstate.getBlendEq()); + id.SetBits(FS_BIT_BLENDEQ, 3, SanitizeBlendMode(gstate.getBlendEq())); id.SetBits(FS_BIT_BLENDFUNC_A, 4, gstate.getBlendFuncA()); id.SetBits(FS_BIT_BLENDFUNC_B, 4, gstate.getBlendFuncB()); }