mirror of https://github.com/PCSX2/pcsx2.git
GS: Favour newer targets unless no match found. No age update on frame.
This commit is contained in:
parent
05dd0831c1
commit
a2a635a141
|
@ -1691,7 +1691,6 @@ void GSRendererHW::Draw()
|
|||
// The rectangle of the draw
|
||||
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
||||
|
||||
|
||||
if (!GSConfig.UserHacks_DisableSafeFeatures)
|
||||
{
|
||||
// Constant Direct Write without texture/test/blending (aka a GS mem clear)
|
||||
|
@ -1701,13 +1700,13 @@ void GSRendererHW::Draw()
|
|||
&& !m_context->TEST.ATE // no alpha test
|
||||
&& (!m_context->TEST.ZTE || m_context->TEST.ZTST == ZTST_ALWAYS) // no depth test
|
||||
&& (m_vt.m_eq.rgba == 0xFFFF) // constant color write
|
||||
&& m_r.x == 0 && m_r.y == 0) { // Likely full buffer write
|
||||
&& m_r.x == 0 && m_r.y == 0) // Likely full buffer write
|
||||
{
|
||||
|
||||
if (OI_GsMemClear() && m_r.w > 1024)
|
||||
{
|
||||
if ((fm & fm_mask) != fm_mask)
|
||||
{
|
||||
|
||||
m_tc->InvalidateVideoMem(context->offset.fb, m_r, true);
|
||||
|
||||
m_tc->InvalidateVideoMemType(GSTextureCache::RenderTarget, context->FRAME.Block());
|
||||
|
@ -1840,7 +1839,8 @@ void GSRendererHW::Draw()
|
|||
&& !m_context->TEST.ATE // no alpha test
|
||||
&& (!m_context->TEST.ZTE || m_context->TEST.ZTST == ZTST_ALWAYS) // no depth test
|
||||
&& (m_vt.m_eq.rgba == 0xFFFF) // constant color write
|
||||
&& m_r.x == 0 && m_r.y == 0) { // Likely full buffer write
|
||||
&& m_r.x == 0 && m_r.y == 0) // Likely full buffer write
|
||||
{
|
||||
OI_DoubleHalfClear(rt, ds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -446,6 +446,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
|
||||
Target* dst = nullptr;
|
||||
auto& list = m_dst[type];
|
||||
Target* old_found = nullptr;
|
||||
|
||||
if (!is_frame)
|
||||
{
|
||||
for (auto i = list.begin(); i != list.end(); ++i)
|
||||
|
@ -477,8 +479,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
// If the frame is older than 30 frames (0.5 seconds) then it hasn't been updated for ages, so it's probably not a valid output frame.
|
||||
// The rest of the checks will get better equality, so suffer less from misdetection.
|
||||
// Kind of arbitrary but it's low enough to not break Grandia Xtreme and high enough not to break Mission Impossible Operation Surma.
|
||||
if (t->m_age > 30)
|
||||
if (t->m_age > 30 && !old_found)
|
||||
{
|
||||
old_found = t;
|
||||
continue;
|
||||
}
|
||||
|
||||
dst = t;
|
||||
GL_CACHE("TC: Lookup Frame %dx%d, perfect hit: %d (0x%x -> 0x%x %s)", size.x, size.y, dst->m_texture->GetID(), bp, t->m_end_block, psm_str(TEX0.PSM));
|
||||
|
@ -497,6 +502,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
// Make sure the target is inside the texture
|
||||
if (t->m_TEX0.TBP0 <= bp && bp <= t->m_end_block && t->Inside(bp, TEX0.TBW, TEX0.PSM, GSVector4i(0, 0, real_w, real_h)))
|
||||
{
|
||||
if (old_found && t->m_age > 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dst = t;
|
||||
GL_CACHE("TC: Lookup Frame %dx%d, inclusive hit: %d (0x%x, took 0x%x -> 0x%x %s)", size.x, size.y, t->m_texture->GetID(), bp, t->m_TEX0.TBP0, t->m_end_block, psm_str(TEX0.PSM));
|
||||
|
||||
|
@ -508,6 +518,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
}
|
||||
}
|
||||
|
||||
if (!dst && old_found)
|
||||
{
|
||||
dst = old_found;
|
||||
}
|
||||
|
||||
// 3rd try ! Try to find a frame that doesn't contain valid data (honestly I'm not sure we need to do it)
|
||||
if (!dst)
|
||||
{
|
||||
|
@ -530,7 +545,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
{
|
||||
GL_CACHE("TC: Lookup %s(%s) %dx%d, hit: %d (0x%x, %s)", is_frame ? "Frame" : "Target", to_string(type), size.x, size.y, dst->m_texture->GetID(), bp, psm_str(TEX0.PSM));
|
||||
|
||||
dst->Update();
|
||||
dst->Update(!is_frame || old_found == dst);
|
||||
|
||||
const GSVector2& old_s = dst->m_texture->GetScale();
|
||||
if (new_s != old_s)
|
||||
|
@ -573,7 +588,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
|
||||
if (dst_match)
|
||||
{
|
||||
dst_match->Update();
|
||||
dst_match->Update(true);
|
||||
calcRescale(dst_match->m_texture);
|
||||
dst = CreateTarget(TEX0, new_size.x, new_size.y, type, clear);
|
||||
dst->m_32_bits_fmt = dst_match->m_32_bits_fmt;
|
||||
|
@ -624,7 +639,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
max_h = std::min<int>(max_h, TEX0.TBW * 64);
|
||||
|
||||
dst->m_dirty.push_back(GSDirtyRect(GSVector4i(0, 0, TEX0.TBW * 64, is_frame ? real_h : max_h), TEX0.PSM, TEX0.TBW));
|
||||
dst->Update();
|
||||
dst->Update(true);
|
||||
}
|
||||
}
|
||||
if (used)
|
||||
|
@ -733,7 +748,7 @@ void GSTextureCache::ExpandTarget(const GIFRegBITBLTBUF& BITBLTBUF, const GSVect
|
|||
dst->ResizeTexture(upsc_width, upsc_height);
|
||||
dst->m_dirty.push_back(GSDirtyRect(r, TEX0.PSM, TEX0.TBW));
|
||||
GetTargetHeight(TEX0.TBP0, TEX0.TBW, TEX0.PSM, r.w);
|
||||
dst->Update();
|
||||
dst->Update(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1753,7 +1768,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|||
src->m_valid_rect = dst->m_valid;
|
||||
src->m_end_block = dst->m_end_block;
|
||||
|
||||
dst->Update();
|
||||
dst->Update(true);
|
||||
|
||||
// do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows)
|
||||
|
||||
|
@ -2666,8 +2681,9 @@ GSTextureCache::Target::Target(const GIFRegTEX0& TEX0, const bool depth_supporte
|
|||
m_dirty_alpha = GSLocalMemory::m_psm[TEX0.PSM].trbpp != 24;
|
||||
}
|
||||
|
||||
void GSTextureCache::Target::Update()
|
||||
void GSTextureCache::Target::Update(bool reset_age)
|
||||
{
|
||||
if(reset_age)
|
||||
Surface::UpdateAge();
|
||||
|
||||
// FIXME: the union of the rects may also update wrong parts of the render target (but a lot faster :)
|
||||
|
@ -2770,7 +2786,7 @@ void GSTextureCache::Target::UpdateIfDirtyIntersects(const GSVector4i& rc)
|
|||
// but, to keep things simple, just update the whole thing
|
||||
GL_CACHE("TC: Update dirty rectangle [%d,%d,%d,%d] due to intersection with [%d,%d,%d,%d]",
|
||||
dirty_rc.x, dirty_rc.y, dirty_rc.z, dirty_rc.w, rc.x, rc.y, rc.z, rc.w);
|
||||
Update();
|
||||
Update(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
|
||||
void UpdateValidity(const GSVector4i& rect);
|
||||
|
||||
void Update();
|
||||
void Update(bool reset_age);
|
||||
|
||||
/// Updates the target, if the dirty area intersects with the specified rectangle.
|
||||
void UpdateIfDirtyIntersects(const GSVector4i& rc);
|
||||
|
|
Loading…
Reference in New Issue