Skip to content

Commit 387cb2f

Browse files
committed
GS/HW: Refactor alpha test method selection.
1 parent 36d587d commit 387cb2f

File tree

7 files changed

+578
-355
lines changed

7 files changed

+578
-355
lines changed

bin/resources/shaders/dx11/tfx.fx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
#define AFAIL_FB_ONLY 1
3232
#define AFAIL_ZB_ONLY 2
3333
#define AFAIL_RGB_ONLY 3
34+
#define AFAIL_RGB_ONLY_DSB 4
35+
#endif
36+
37+
#ifndef PS_ATST_NONE
38+
#define PS_ATST_NONE 0
39+
#define PS_ATST_LEQUAL 1
40+
#define PS_ATST_GEQUAL 2
41+
#define PS_ATST_EQUAL 3
42+
#define PS_ATST_NOTEQUAL 4
3443
#endif
3544

3645
#ifndef PS_FST
@@ -98,7 +107,7 @@
98107
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
99108
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
100109
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
101-
#define AFAIL_NEEDS_RT (PS_AFAIL == AFAIL_ZB_ONLY || (PS_AFAIL == AFAIL_RGB_ONLY && PS_NO_COLOR1))
110+
#define AFAIL_NEEDS_RT (PS_AFAIL == AFAIL_ZB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
102111
#define AFAIL_NEEDS_DEPTH (PS_AFAIL == AFAIL_FB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
103112

104113
struct VS_INPUT
@@ -154,7 +163,7 @@ struct PS_OUTPUT
154163
#endif
155164
#endif
156165
#endif
157-
#if PS_ZCLAMP || (PS_DEPTH_FEEDBACK && AFAIL_NEEDS_DEPTH)
166+
#if PS_ZCLAMP
158167
float depth : SV_Depth;
159168
#endif
160169
};
@@ -729,27 +738,27 @@ bool atst(float4 C)
729738
{
730739
float a = C.a;
731740

732-
if(PS_ATST == 1)
733-
{
734-
return (a <= AREF);
735-
}
736-
else if(PS_ATST == 2)
737-
{
738-
return (a >= AREF);
739-
}
740-
else if(PS_ATST == 3)
741-
{
742-
return (abs(a - AREF) <= 0.5f);
743-
}
744-
else if(PS_ATST == 4)
745-
{
746-
return (abs(a - AREF) >= 0.5f);
747-
}
748-
else
749-
{
750-
// nothing to do
751-
return true;
752-
}
741+
#if PS_ATST == PS_ATST_LEQUAL
742+
743+
return (a <= AREF);
744+
745+
#elif PS_ATST == PS_ATST_GEQUAL
746+
747+
return (a >= AREF);
748+
749+
#elif PS_ATST == PS_ATST_EQUAL
750+
751+
return (abs(a - AREF) <= 0.5f);
752+
753+
#elif PS_ATST == PS_ATST_NOTEQUAL
754+
755+
return (abs(a - AREF) >= 0.5f);
756+
757+
#else
758+
759+
return true;
760+
761+
#endif
753762
}
754763

755764
float4 fog(float4 c, float f)
@@ -1212,7 +1221,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
12121221

12131222
ps_fbmask(C, input.p.xy);
12141223

1215-
#if (PS_AFAIL == AFAIL_RGB_ONLY) && !PS_NO_COLOR1
1224+
#if (PS_AFAIL == AFAIL_RGB_ONLY_DSB) && !PS_NO_COLOR1
12161225
// Use alpha blend factor to determine whether to update A.
12171226
alpha_blend.a = float(atst_pass);
12181227
#endif
@@ -1225,7 +1234,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
12251234
#endif
12261235

12271236
// Alpha test with feedback
1228-
#if (PS_AFAIL == AFAIL_FB_ONLY) && PS_DEPTH_FEEDBACK
1237+
#if (PS_AFAIL == AFAIL_FB_ONLY) && PS_DEPTH_FEEDBACK && PS_ZCLAMP
12291238
if (!atst_pass)
12301239
input.p.z = DepthTexture.Load(int3(input.p.xy, 0)).r;
12311240
#elif (PS_AFAIL == AFAIL_ZB_ONLY) && PS_COLOR_FEEDBACK
@@ -1234,10 +1243,10 @@ PS_OUTPUT ps_main(PS_INPUT input)
12341243
#elif (PS_AFAIL == AFAIL_RGB_ONLY)
12351244
if (!atst_pass)
12361245
{
1237-
#if PS_COLOR_FEEDBACK && PS_NO_COLOR1 // No dual src blend
1246+
#if PS_COLOR_FEEDBACK
12381247
output.c0.a = RtTexture.Load(int3(input.p.xy, 0)).a;
12391248
#endif
1240-
#if PS_DEPTH_FEEDBACK
1249+
#if PS_DEPTH_FEEDBACK && PS_ZCLAMP
12411250
input.p.z = DepthTexture.Load(int3(input.p.xy, 0)).r;
12421251
#endif
12431252
}
@@ -1249,8 +1258,6 @@ PS_OUTPUT ps_main(PS_INPUT input)
12491258

12501259
#if PS_ZCLAMP
12511260
output.depth = min(input.p.z, MaxDepthPS);
1252-
#elif PS_DEPTH_FEEDBACK && AFAIL_NEEDS_DEPTH
1253-
output.depth = input.p.z; // Output depth value for ATST pass/fail
12541261
#endif
12551262

12561263
return output;

bin/resources/shaders/opengl/tfx_fs.glsl

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@
2121
#define AFAIL_FB_ONLY 1
2222
#define AFAIL_ZB_ONLY 2
2323
#define AFAIL_RGB_ONLY 3
24+
#define AFAIL_RGB_ONLY_DSB 4
25+
#endif
26+
27+
#ifndef PS_ATST_NONE
28+
#define PS_ATST_NONE 0
29+
#define PS_ATST_LEQUAL 1
30+
#define PS_ATST_GEQUAL 2
31+
#define PS_ATST_EQUAL 3
32+
#define PS_ATST_NOTEQUAL 4
2433
#endif
2534

2635
// TEX_COORD_DEBUG output the uv coordinate as color. It is useful
@@ -37,7 +46,7 @@
3746
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
3847
#define PS_PRIMID_INIT (PS_DATE == 1 || PS_DATE == 2)
3948
#define NEEDS_RT_EARLY (PS_TEX_IS_FB == 1 || PS_DATE >= 5)
40-
#define NEEDS_RT_FOR_AFAIL (PS_AFAIL == PS_ZB_ONLY || (PS_AFAIL == AFAIL_RGB_ONLY && PS_NO_COLOR1))
49+
#define NEEDS_RT_FOR_AFAIL (PS_AFAIL == PS_ZB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
4150
#define NEEDS_DEPTH_FOR_AFAIL (PS_AFAIL == AFAIL_FB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
4251
#define NEEDS_RT (NEEDS_RT_EARLY || NEEDS_RT_FOR_AFAIL || (!PS_PRIMID_INIT && (PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW)) || PS_COLOR_FEEDBACK)
4352
#define NEEDS_TEX (PS_TFX != 4)
@@ -655,17 +664,26 @@ bool atst(vec4 C)
655664
{
656665
float a = C.a;
657666

658-
#if (PS_ATST == 1)
667+
#if PS_ATST == PS_ATST_LEQUAL
668+
659669
return (a <= AREF);
660-
#elif (PS_ATST == 2)
670+
671+
#elif PS_ATST == PS_ATST_GEQUAL
672+
661673
return (a >= AREF);
662-
#elif (PS_ATST == 3)
674+
675+
#elif PS_ATST == PS_ATST_EQUAL
676+
663677
return (abs(a - AREF) <= 0.5f);
664-
#elif (PS_ATST == 4)
678+
679+
#elif PS_ATST == PS_ATST_NOTEQUAL
680+
665681
return (abs(a - AREF) >= 0.5f);
682+
666683
#else
667-
// nothing to do
684+
668685
return true;
686+
669687
#endif
670688
}
671689

@@ -1154,7 +1172,7 @@ void ps_main()
11541172

11551173
ps_fbmask(C);
11561174

1157-
#if PS_AFAIL == AFAIL_RGB && !PS_NO_COLOR1
1175+
#if (PS_AFAIL == AFAIL_RGB_ONLY_DSB) && !PS_NO_COLOR1
11581176
// Use alpha blend factor to determine whether to update A.
11591177
alpha_blend.a = float(atst_pass);
11601178
#endif
@@ -1172,7 +1190,7 @@ void ps_main()
11721190
#endif
11731191

11741192
// Alpha test with feedback
1175-
#if (PS_AFAIL == AFAIL_FB_ONLY) && NEEDS_DEPTH
1193+
#if (PS_AFAIL == AFAIL_FB_ONLY) && NEEDS_DEPTH && PS_ZCLAMP
11761194
if (!atst_pass)
11771195
FragCoord.z = sample_from_depth().r;
11781196
#elif (PS_AFAIL == AFAIL_ZB_ONLY) && NEEDS_RT
@@ -1181,10 +1199,10 @@ void ps_main()
11811199
#elif (PS_AFAIL == AFAIL_RGB_ONLY)
11821200
if (!atst_pass)
11831201
{
1184-
#if NEEDS_RT && PS_NO_COLOR1 // No dual src blend
1202+
#if NEEDS_RT
11851203
C.a = sample_from_rt().a;
11861204
#endif
1187-
#if NEEDS_DEPTH
1205+
#if NEEDS_DEPTH && PS_ZCLAMP
11881206
FragCoord.z = sample_from_depth().r;
11891207
#endif
11901208
}
@@ -1201,7 +1219,5 @@ void ps_main()
12011219

12021220
#if PS_ZCLAMP
12031221
gl_FragDepth = min(FragCoord.z, MaxDepthPS);
1204-
#elif NEEDS_DEPTH && AFAIL_NEEDS_DEPTH
1205-
gl_FragDepth = FragCoord.z; // Output depth value for ATST pass/fail
12061222
#endif
12071223
}

bin/resources/shaders/vulkan/tfx.glsl

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,15 @@ void main()
255255
#define AFAIL_FB_ONLY 1
256256
#define AFAIL_ZB_ONLY 2
257257
#define AFAIL_RGB_ONLY 3
258+
#define AFAIL_RGB_ONLY_DSB 4
259+
#endif
260+
261+
#ifndef PS_ATST_NONE
262+
#define PS_ATST_NONE 0
263+
#define PS_ATST_LEQUAL 1
264+
#define PS_ATST_GEQUAL 2
265+
#define PS_ATST_EQUAL 3
266+
#define PS_ATST_NOTEQUAL 4
258267
#endif
259268

260269
#ifndef PS_FST
@@ -315,7 +324,7 @@ void main()
315324
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
316325
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
317326
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
318-
#define AFAIL_NEEDS_RT (PS_AFAIL == AFAIL_ZB_ONLY || (PS_AFAIL == AFAIL_RGB_ONLY && PS_NO_COLOR1))
327+
#define AFAIL_NEEDS_RT (PS_AFAIL == AFAIL_ZB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
319328
#define AFAIL_NEEDS_DEPTH (PS_AFAIL == AFAIL_FB_ONLY || PS_AFAIL == AFAIL_RGB_ONLY)
320329

321330
#define PS_FEEDBACK_LOOP_IS_NEEDED_RT (PS_TEX_IS_FB == 1 || AFAIL_NEEDS_RT || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5) || PS_COLOR_FEEDBACK)
@@ -920,28 +929,27 @@ bool atst(vec4 C)
920929
{
921930
float a = C.a;
922931

923-
#if (PS_ATST == 1)
924-
{
925-
return (a <= AREF);
926-
}
927-
#elif (PS_ATST == 2)
928-
{
929-
return (a >= AREF);
930-
}
931-
#elif (PS_ATST == 3)
932-
{
933-
return (abs(a - AREF) <= 0.5f);
934-
}
935-
#elif (PS_ATST == 4)
936-
{
937-
return (abs(a - AREF) >= 0.5f);
938-
}
939-
#else
940-
{
941-
// nothing to do
942-
return true;
943-
}
944-
#endif
932+
#if PS_ATST == PS_ATST_LEQUAL
933+
934+
return (a <= AREF);
935+
936+
#elif PS_ATST == PS_ATST_GEQUAL
937+
938+
return (a >= AREF);
939+
940+
#elif PS_ATST == PS_ATST_EQUAL
941+
942+
return (abs(a - AREF) <= 0.5f);
943+
944+
#elif PS_ATST == PS_ATST_NOTEQUAL
945+
946+
return (abs(a - AREF) >= 0.5f);
947+
948+
#else
949+
950+
return true;
951+
952+
#endif
945953
}
946954

947955
vec4 fog(vec4 c, float f)
@@ -1426,7 +1434,7 @@ void main()
14261434

14271435
ps_fbmask(C);
14281436

1429-
#if (PS_AFAIL == AFAIL_RGB_ONLY) && !PS_NO_COLOR1
1437+
#if (PS_AFAIL == AFAIL_RGB_ONLY_DSB) && !PS_NO_COLOR1
14301438
// Use alpha blend factor to determine whether to update A.
14311439
alpha_blend.a = float(atst_pass);
14321440
#endif
@@ -1447,7 +1455,7 @@ void main()
14471455
#endif
14481456

14491457
// Alpha test with feedback
1450-
#if (PS_AFAIL == AFAIL_FB_ONLY) && PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
1458+
#if (PS_AFAIL == AFAIL_FB_ONLY) && PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && PS_ZCLAMP
14511459
if (!atst_pass)
14521460
FragCoord.z = sample_from_depth().r;
14531461
#elif (PS_AFAIL == AFAIL_ZB_ONLY) && PS_FEEDBACK_LOOP_IS_NEEDED_RT
@@ -1456,10 +1464,10 @@ void main()
14561464
#elif (PS_AFAIL == AFAIL_RGB_ONLY)
14571465
if (!atst_pass)
14581466
{
1459-
#if PS_FEEDBACK_LOOP_IS_NEEDED_RT && PS_NO_COLOR1 // No dual src blend
1467+
#if PS_FEEDBACK_LOOP_IS_NEEDED_RT
14601468
o_col0.a = sample_from_rt().a;
14611469
#endif
1462-
#if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
1470+
#if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && PS_ZCLAMP
14631471
FragCoord.z = sample_from_depth().r;
14641472
#endif
14651473
}
@@ -1468,8 +1476,6 @@ void main()
14681476

14691477
#if PS_ZCLAMP
14701478
gl_FragDepth = min(FragCoord.z, MaxDepthPS);
1471-
#elif PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && AFAIL_NEEDS_DEPTH
1472-
gl_FragDepth = FragCoord.z; // Output depth value for ATST pass/fail
14731479
#endif
14741480
#endif // PS_DATE
14751481
}

pcsx2/GS/GSRegs.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ enum GS_AFAIL
201201
AFAIL_RGB_ONLY = 3,
202202
};
203203

204+
enum GS_ALPHA_BITS
205+
{
206+
ALPHA_ABC_CS = 0,
207+
ALPHA_ABC_CD = 1,
208+
ALPHA_C_AS = 0,
209+
ALPHA_C_AD = 1,
210+
ALPHA_C_FIX = 2,
211+
};
212+
204213
enum class GS_MIN_FILTER : uint8_t
205214
{
206215
Nearest = 0,
@@ -773,8 +782,6 @@ REG64_(GIFReg, TEST)
773782
u32 _PAD1 : 13;
774783
u32 _PAD2 : 32;
775784
REG_END2
776-
__forceinline bool DoFirstPass() const { return !ATE || ATST != ATST_NEVER; } // not all pixels fail automatically
777-
__forceinline bool DoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL != AFAIL_KEEP; } // pixels may fail, write fb/z
778785
__forceinline u32 GetAFAIL(u32 fpsm) const { return (AFAIL == AFAIL_RGB_ONLY && (fpsm & 0xF) != 0) ? static_cast<u32>(AFAIL_FB_ONLY) : AFAIL; } // FB Only when not 32bit Framebuffer
779786
REG_END2
780787

0 commit comments

Comments
 (0)