gsdx-hw: Implement per pixel alpha blending (PABE).

Fixes Strawberry Shortcake character lighting/face shadow.
Fixes Cartoon Network Racing shadows.

Credits to Kojin.
This commit is contained in:
lightningterror 2021-02-04 02:39:20 +01:00
parent d993e4ebc8
commit 37089065ba
8 changed files with 23 additions and 14 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);