GS: Fix some edge cases with fbfetch

Second alpha pass with A masked, DATE enabled, etc.
This commit is contained in:
Connor McLaughlin 2022-03-21 10:20:56 +10:00 committed by refractionpcsx2
parent bf9c1176b6
commit 1927896442
3 changed files with 30 additions and 9 deletions

View File

@ -43,6 +43,10 @@ in SHADER
// Only enable framebuffer fetch when we actually need it.
#if HAS_FRAMEBUFFER_FETCH && (PS_TEX_IS_FB == 1 || PS_FBMASK || SW_BLEND_NEEDS_RT || PS_DATE != 0)
// We need to force the colour to be defined here, to read from it.
// Basically the only scenario where this'll happen is RGBA masked and DATE is active.
#undef PS_NO_COLOR
#define PS_NO_COLOR 0
#if defined(GL_EXT_shader_framebuffer_fetch)
#undef TARGET_0_QUALIFIER
#define TARGET_0_QUALIFIER inout

View File

@ -282,6 +282,22 @@ struct alignas(16) GSHWDrawConfig
{
return tex_is_fb || fbmask || date > 0 || blend_a == 1 || blend_b == 1 || blend_c == 1 || blend_d == 1;
}
/// Disables color output from the pixel shader, this is done when all channels are masked.
__fi void DisableColorOutput()
{
// remove software blending, since this will cause the color to be declared inout with fbfetch.
blend_a = blend_b = blend_c = blend_d = 0;
// TEX_IS_FB relies on us having a color output to begin with.
tex_is_fb = 0;
// no point having fbmask, since we're not writing. DATE has to stay.
fbmask = 0;
// disable both outputs.
no_color = no_color1 = 1;
}
};
#pragma pack(pop)
struct PSSelectorHash

View File

@ -868,7 +868,6 @@ void GSRendererNew::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool&
// Output is Cd, set rgb write to 0.
m_conf.colormask.wrgba &= 0x8;
m_conf.ps.no_color = (m_conf.colormask.wrgba == 0);
}
else if (sw_blending)
{
@ -1521,16 +1520,17 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
else
{
m_conf.blend = {}; // No blending please
m_conf.ps.no_color = !rt || (m_conf.colormask.wrgba == 0);
m_conf.ps.no_color1 = true;
}
if (features.framebuffer_fetch)
{
// barriers aren't needed with fbfetch
m_conf.require_one_barrier = false;
m_conf.require_full_barrier = false;
}
// No point outputting colours if we're just writing depth.
// We might still need the framebuffer for DATE, though.
if (!rt || m_conf.colormask.wrgba == 0)
m_conf.ps.DisableColorOutput();
// Barriers aren't needed with fbfetch.
m_conf.require_one_barrier &= !features.framebuffer_fetch;
m_conf.require_full_barrier &= !features.framebuffer_fetch;
if (m_conf.ps.scanmsk & 2)
DATE_PRIMID = false; // to have discard in the shader work correctly
@ -1785,7 +1785,8 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
m_conf.alpha_second_pass.colormask.wg = g;
m_conf.alpha_second_pass.colormask.wb = b;
m_conf.alpha_second_pass.colormask.wa = a;
m_conf.alpha_second_pass.ps.no_color |= !(r || g || b || a);
if (m_conf.alpha_second_pass.colormask.wrgba == 0)
m_conf.alpha_second_pass.ps.DisableColorOutput();
}
else
{