From 37089065ba1292ad4e60f53b5c54437ee28af7ac Mon Sep 17 00:00:00 2001 From: lightningterror <18107717+lightningterror@users.noreply.github.com> Date: Thu, 4 Feb 2021 02:39:20 +0100 Subject: [PATCH] gsdx-hw: Implement per pixel alpha blending (PABE). Fixes Strawberry Shortcake character lighting/face shadow. Fixes Cartoon Network Racing shadows. Credits to Kojin. --- plugins/GSdx/Renderers/DX11/GSDevice11.h | 4 ++-- plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp | 4 +++- plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp | 1 + plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp | 2 +- plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h | 4 ++-- plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp | 11 +++-------- plugins/GSdx/res/glsl/tfx_fs.glsl | 6 ++++++ plugins/GSdx/res/tfx.fx | 5 +++++ 8 files changed, 23 insertions(+), 14 deletions(-) diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.h b/plugins/GSdx/Renderers/DX11/GSDevice11.h index fb309f85d0..7231ffc788 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.h +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.h @@ -233,8 +233,8 @@ public: uint32 blend_c:2; // bit0 uint32 blend_d:2; uint32 clr1:1; - uint32 colclip:1; + uint32 pabe:1; // Others ways to fetch the texture uint32 channel:3; @@ -252,7 +252,7 @@ public: uint32 point_sampler:1; uint32 invalid_tex0:1; // Lupin the 3rd - uint32 _free:15; + uint32 _free:14; }; uint64 key; diff --git a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp index 13a022bc14..4142459e8d 100644 --- a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp @@ -470,7 +470,9 @@ void GSRendererDX11::EmulateBlending() m_om_bsel.abe = 0; } - // Breath of Fire Dragon Quarter, Strawberry Shortcake, Super Robot Wars. + // Breath of Fire Dragon Quarter, Strawberry Shortcake, Super Robot Wars, Cartoon Network Racing. + // fprintf(stderr, "%d: PABE mode ENABLED\n", s_n); + m_ps_sel.pabe = 1; } m_om_bsel.blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D); diff --git a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp index fdf5b51c83..9176081c5c 100644 --- a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp @@ -219,6 +219,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe sm.AddMacro("PS_BLEND_B", sel.blend_b); sm.AddMacro("PS_BLEND_C", sel.blend_c); sm.AddMacro("PS_BLEND_D", sel.blend_d); + sm.AddMacro("PS_PABE", sel.pabe); sm.AddMacro("PS_DITHER", sel.dither); sm.AddMacro("PS_ZCLAMP", sel.zclamp); diff --git a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp index e172808418..a805dd9edb 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp @@ -984,7 +984,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel) + format("#define PS_HDR %d\n", sel.hdr) + format("#define PS_DITHER %d\n", sel.dither) + format("#define PS_ZCLAMP %d\n", sel.zclamp) - // + format("#define PS_PABE %d\n", sel.pabe) + + format("#define PS_PABE %d\n", sel.pabe) ; if (GLLoader::buggy_sso_dual_src) diff --git a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h index 999d95a6f8..028dbc9f33 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h +++ b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h @@ -300,7 +300,7 @@ public: uint32 clr1:1; // useful? uint32 hdr:1; uint32 colclip:1; - // uint32 pabe:1; + uint32 pabe:1; // Others ways to fetch the texture uint32 channel:3; @@ -321,7 +321,7 @@ public: uint32 point_sampler:1; uint32 invalid_tex0:1; // Lupin the 3rd - uint32 _free2:7; + uint32 _free2:6; }; uint64 key; diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index 22c04afd5e..799fe66648 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -420,14 +420,9 @@ void GSRendererOGL::EmulateBlending(bool& DATE_GL42, bool& DATE_GL45) } if (m_env.PABE.PABE) { - GL_INS("ERROR: ENV PABE not supported!"); - if (m_sw_blending >= ACC_BLEND_MEDIUM) { - // m_ps_sel.pabe = 1; - m_require_full_barrier |= (ALPHA.C == 1); - sw_blending = true; - } - // Breath of Fire Dragon Quarter, Strawberry Shortcake, Super Robot Wars. - //ASSERT(0); + // Breath of Fire Dragon Quarter, Strawberry Shortcake, Super Robot Wars, Cartoon Network Racing. + GL_INS("PABE mode ENABLED"); + m_ps_sel.pabe = 1; } // Compute the blending equation to detect special case diff --git a/plugins/GSdx/res/glsl/tfx_fs.glsl b/plugins/GSdx/res/glsl/tfx_fs.glsl index 57266774ff..9419492c17 100644 --- a/plugins/GSdx/res/glsl/tfx_fs.glsl +++ b/plugins/GSdx/res/glsl/tfx_fs.glsl @@ -627,6 +627,7 @@ void ps_blend(inout vec4 Color, float As) { #if SW_BLEND vec4 RT = trunc(texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0) * 255.0f + 0.1f); + vec4 Color_pabe = Color; #if PS_DFMT == FMT_24 float Ad = 1.0f; @@ -678,6 +679,11 @@ void ps_blend(inout vec4 Color, float As) Color.rgb = trunc((A - B) * C + D); #endif + // PABE +#if PS_PABE + Color.rgb = (Color_pabe.a >= 128.0f) ? Color.rgb : Color_pabe.rgb; +#endif + // Dithering ps_dither(Color); diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index a6303524ed..e4495f90a2 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -48,6 +48,7 @@ #define PS_BLEND_B 0 #define PS_BLEND_C 0 #define PS_BLEND_D 0 +#define PS_PABE 0 #define PS_DITHER 0 #define PS_ZCLAMP 0 #endif @@ -685,6 +686,10 @@ void ps_blend(inout float4 Color, float As, float2 pos_xy) Cv = (PS_BLEND_A == PS_BLEND_B) ? D : trunc(((A - B) * C) + D); + // PABE + if (PS_PABE) + Cv = (Color.a >= 128.0f) ? Cv : Color.rgb; + // Dithering ps_dither(Cv, pos_xy);