GS/DX: Implement barrier DATE.

Will only be used when fb is already copied and we want to switch from primid date,
or if date one is present and a barrier/fb copy is already on.
This commit is contained in:
lightningterror 2025-08-21 21:40:53 +02:00
parent 567b0173ec
commit 09d0ff2577
3 changed files with 43 additions and 4 deletions

View File

@ -82,6 +82,7 @@
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define SW_BLEND_NEEDS_RT (SW_BLEND && (PS_BLEND_A == 1 || PS_BLEND_B == 1 || PS_BLEND_C == 1 || PS_BLEND_D == 1))
#define SW_AD_TO_HW (PS_BLEND_C == 1 && PS_A_MASKED)
#define NEEDS_RT_FOR_AFAIL (PS_AFAIL == 3 && PS_NO_COLOR1)
struct VS_INPUT
{
@ -1063,6 +1064,36 @@ PS_OUTPUT ps_main(PS_INPUT input)
if (C.a < A_one) C.a += A_one;
}
#if PS_DATE >= 5
#if PS_WRITE_RG == 1
// Pseudo 16 bits access.
float rt_a = RtTexture.Load(int3(input.p.xy, 0)).g;
#else
float rt_a = RtTexture.Load(int3(input.p.xy, 0)).a;
#endif
#if (PS_DATE & 3) == 1
// DATM == 0: Pixel with alpha equal to 1 will failed
#if PS_RTA_CORRECTION
bool bad = (254.5f / 255.0f) < rt_a;
#else
bool bad = (127.5f / 255.0f) < rt_a;
#endif
#elif (PS_DATE & 3) == 2
// DATM == 1: Pixel with alpha equal to 0 will failed
#if PS_RTA_CORRECTION
bool bad = rt_a < (254.5f / 255.0f);
#else
bool bad = rt_a < (127.5f / 255.0f);
#endif
#endif
if (bad)
discard;
#endif
#if PS_DATE == 3
// Note gl_PrimitiveID == stencil_ceil will be the primitive that will update
// the bad alpha value so we must keep it.
@ -1154,7 +1185,7 @@ PS_OUTPUT ps_main(PS_INPUT input)
ps_fbmask(C, input.p.xy);
#if PS_AFAIL == 3 // RGB_ONLY
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY
// Use alpha blend factor to determine whether to update A.
alpha_blend.a = float(atst_pass);
#endif
@ -1165,6 +1196,14 @@ PS_OUTPUT ps_main(PS_INPUT input)
#if !PS_NO_COLOR1
output.c1 = alpha_blend;
#endif
#if PS_AFAIL == 3 && !PS_NO_COLOR1 // RGB_ONLY, no dual src blend
if (!atst_pass)
{
float RTa = NEEDS_RT_FOR_AFAIL ? RtTexture.Load(int3(input.p.xy, 0)).a : 0.0f;
output.c0.a = RTa;
}
#endif
#endif // !PS_NO_COLOR
#endif // PS_DATE != 1/2

View File

@ -5110,7 +5110,7 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
// If date is enabled you need to test the green channel instead of the alpha channel.
// Only enable this code in DATE mode to reduce the number of shaders.
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && features.texture_barrier && m_cached_ctx.TEST.DATE;
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && m_cached_ctx.TEST.DATE;
m_conf.ps.real16src = m_copy_16bit_to_target_shuffle;
m_conf.ps.shuffle_same = m_same_group_texture_shuffle;
// Please bang my head against the wall!
@ -6347,7 +6347,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
// Switch DATE_PRIMID with DATE_BARRIER in such cases to ensure accuracy.
// No mix of COLCLIP + sw blend + DATE_PRIMID, neither sw fbmask + DATE_PRIMID.
// Note: Do the swap in the end, saves the expensive draw splitting/barriers when mixed software blending is used.
if (sw_blending && DATE_PRIMID && features.texture_barrier && m_conf.require_full_barrier)
if (sw_blending && DATE_PRIMID && m_conf.require_full_barrier)
{
GL_PERF("DATE: Swap DATE_PRIMID with DATE_BARRIER");
DATE_PRIMID = false;

View File

@ -3,4 +3,4 @@
/// Version number for GS and other shaders. Increment whenever any of the contents of the
/// shaders change, to invalidate the cache.
static constexpr u32 SHADER_CACHE_VERSION = 70;
static constexpr u32 SHADER_CACHE_VERSION = 71;