GS/HW: Check for half point on double half clear, improve width check

This commit is contained in:
refractionpcsx2 2023-09-08 00:53:10 +01:00
parent 92acbd006b
commit 5633053655
1 changed files with 27 additions and 10 deletions

View File

@ -5687,6 +5687,14 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
if (half > (base + written_pages) || half <= base)
return false;
GSTextureCache::Target* half_point = g_texture_cache->GetExactTarget(half << 5, m_cached_ctx.FRAME.FBW, clear_depth ? GSTextureCache::RenderTarget : GSTextureCache::DepthStencil, half << 5);
if (half_point)
{
half_point = nullptr;
return false;
}
// Don't allow double half clear to go through when the number of bits written through FRAME and Z are different.
// GTA: LCS does this setup, along with a few other games. Thankfully if it's a zero clear, we'll clear both
// separately, and the end result is the same because it gets invalidated. That's better than falsely detecting
@ -5704,19 +5712,28 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
// Have to check both contexts, because God of War 2 likes to do this in-between setting TRXDIR, which
// causes a flush, and we don't have the next context backed up index set.
bool horizontal = false;
if (((m_env.CTXT[0].FRAME.FBW == m_cached_ctx.FRAME.FBW &&
((m_env.CTXT[0].FRAME.FBP == base &&
(!m_env.CTXT[0].ZBUF.ZMSK || (m_env.CTXT[0].TEST.ZTE && m_env.CTXT[0].TEST.ZTST >= ZTST_GEQUAL)) &&
m_env.CTXT[0].ZBUF.ZBP != half) ||
(m_env.CTXT[0].ZBUF.ZBP == base && m_env.CTXT[0].FRAME.FBP != half)))) ||
(m_env.CTXT[1].FRAME.FBW == m_cached_ctx.FRAME.FBW &&
((m_env.CTXT[1].FRAME.FBP == base && m_env.CTXT[1].ZBUF.ZBP != half) ||
(m_env.CTXT[1].ZBUF.ZBP == base &&
(!m_env.CTXT[1].ZBUF.ZMSK || (m_env.CTXT[1].TEST.ZTE && m_env.CTXT[1].TEST.ZTST >= ZTST_GEQUAL)) &&
m_env.CTXT[1].FRAME.FBP != half))))
const bool ctx0_match = ((((m_env.CTXT[0].FRAME.FBW + 1) & ~1) == m_cached_ctx.FRAME.FBW * 2) || (m_env.CTXT[0].FRAME.FBW == m_cached_ctx.FRAME.FBW)) &&
((m_env.CTXT[0].FRAME.FBP == base &&
(!m_env.CTXT[0].ZBUF.ZMSK || (m_env.CTXT[0].TEST.ZTE && m_env.CTXT[0].TEST.ZTST >= ZTST_GEQUAL)) &&
m_env.CTXT[0].ZBUF.ZBP != half) ||
(m_env.CTXT[0].ZBUF.ZBP == base && m_env.CTXT[0].FRAME.FBP != half));
const bool ctx1_match = ((((m_env.CTXT[1].FRAME.FBW + 1) & ~1) == m_cached_ctx.FRAME.FBW * 2) || (m_env.CTXT[1].FRAME.FBW == m_cached_ctx.FRAME.FBW)) &&
((m_env.CTXT[1].FRAME.FBP == base && m_env.CTXT[1].ZBUF.ZBP != half) ||
(m_env.CTXT[1].ZBUF.ZBP == base &&
(!m_env.CTXT[1].ZBUF.ZMSK || (m_env.CTXT[1].TEST.ZTE && m_env.CTXT[1].TEST.ZTST >= ZTST_GEQUAL)) &&
m_env.CTXT[1].FRAME.FBP != half));
if (ctx0_match || ctx1_match)
{
// Needed for Spider-Man 2 (target was previously half size, double half cleared at new size).
GL_INS("Confirmed double-half clear by next FBP/ZBP");
const int ctx = ctx1_match ? 1 : 0;
if (((m_env.CTXT[ctx].FRAME.FBW + 1) & ~1) == m_cached_ctx.FRAME.FBW * 2)
horizontal = true;
}
else
{