mirror of https://github.com/PCSX2/pcsx2.git
GS-HW: Avoid clears with new targets
This commit is contained in:
parent
68ec70f24f
commit
7f26595804
|
@ -1681,12 +1681,23 @@ void GSRendererHW::Draw()
|
|||
m_vertex.buff[1].RGBAQ.U32[0] :
|
||||
(m_vertex.buff[1].RGBAQ.U32[0] & ~0xFF000000)) == 0) && m_cached_ctx.FRAME.FBMSK == 0 && IsBlendedOrOpaque();
|
||||
|
||||
if (is_zero_clear && OI_GsMemClear() && clear_height_valid)
|
||||
const u32 rt_end = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].info.bn(m_r.z - 1, m_r.w - 1, m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW);
|
||||
const bool req_z = m_cached_ctx.FRAME.FBP != m_cached_ctx.ZBUF.ZBP && !m_cached_ctx.ZBUF.ZMSK;
|
||||
bool no_target_found = false;
|
||||
|
||||
// This is behind the if just to reduce lookups.
|
||||
if (is_zero_clear && !clear_height_valid)
|
||||
no_target_found = !g_texture_cache->GetExactTarget(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, GSTextureCache::RenderTarget, rt_end) &&
|
||||
!g_texture_cache->GetExactTarget(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, GSTextureCache::DepthStencil, rt_end);
|
||||
|
||||
if (is_zero_clear && OI_GsMemClear() && (clear_height_valid || (!req_z && no_target_found)))
|
||||
{
|
||||
GL_INS("Clear draw with mem clear and valid clear height, invalidating.");
|
||||
|
||||
g_texture_cache->InvalidateVideoMem(context->offset.fb, m_r, false, true);
|
||||
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, m_cached_ctx.FRAME.Block());
|
||||
if(no_target_found)
|
||||
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, m_cached_ctx.FRAME.Block());
|
||||
|
||||
if (m_cached_ctx.ZBUF.ZMSK == 0)
|
||||
{
|
||||
|
@ -4792,7 +4803,7 @@ GSRendererHW::CLUTDrawTestResult GSRendererHW::PossibleCLUTDraw()
|
|||
return CLUTDrawTestResult::CLUTDrawOnCPU;
|
||||
|
||||
GSTextureCache::Target* tgt = g_texture_cache->GetExactTarget(
|
||||
m_cached_ctx.TEX0.TBP0, m_cached_ctx.TEX0.TBW, GSTextureCache::RenderTarget);
|
||||
m_cached_ctx.TEX0.TBP0, m_cached_ctx.TEX0.TBW, GSTextureCache::RenderTarget, m_cached_ctx.TEX0.TBP0);
|
||||
if (tgt)
|
||||
{
|
||||
bool is_dirty = false;
|
||||
|
@ -5145,19 +5156,18 @@ bool GSRendererHW::OI_GsMemClear()
|
|||
}
|
||||
else if (format == 2)
|
||||
{
|
||||
; // Hack is used for FMV which are likely 24/32 bits. Let's keep the for reference
|
||||
#if 0
|
||||
const u16 converted_color = ((vert_color >> 16) & 0x8000) | ((vert_color >> 9) & 0x7C00) | ((vert_color >> 6) & 0x7E0) | ((vert_color >> 3) & 0x1F);
|
||||
|
||||
// Based on WritePixel16
|
||||
for (int y = r.top; y < r.bottom; y++)
|
||||
{
|
||||
auto pa = off.assertSizesMatch(GSLocalMemory::swizzle16).paMulti(m_mem.m_vm16, 0, y);
|
||||
auto pa = off.assertSizesMatch(GSLocalMemory::swizzle16).paMulti(m_mem.vm16(), 0, y);
|
||||
|
||||
for (int x = r.left; x < r.right; x++)
|
||||
{
|
||||
*pa.value(x) = 0; // Here the constant color
|
||||
*pa.value(x) = converted_color; // Here the constant color
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1174,7 +1174,7 @@ GSTextureCache::Target* GSTextureCache::FindTargetOverlap(u32 bp, u32 end_block,
|
|||
for (auto t : m_dst[type])
|
||||
{
|
||||
// Only checks that the texure starts at the requested bp, which shares data. Size isn't considered.
|
||||
if (t->m_TEX0.TBP0 >= bp && t->m_TEX0.TBP0 < end_block_bp && GSUtil::HasSharedBits(t->m_TEX0.PSM, psm))
|
||||
if (t->m_TEX0.TBP0 >= bp && t->m_TEX0.TBP0 < end_block_bp && GSUtil::HasCompatibleBits(t->m_TEX0.PSM, psm))
|
||||
return t;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1524,7 +1524,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
|||
|
||||
if (!eerect.rempty())
|
||||
{
|
||||
GL_INS("Preloading the RT DATA");
|
||||
GL_INS("Preloading the RT DATA from updated GS Memory");
|
||||
eerect = eerect.rintersect(newrect);
|
||||
AddDirtyRectTarget(dst, eerect, TEX0.PSM, TEX0.TBW, rgba, GSLocalMemory::m_psm[TEX0.PSM].trbpp >= 16);
|
||||
}
|
||||
|
@ -2583,9 +2583,11 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|||
return false;
|
||||
}
|
||||
|
||||
const u32 src_end = GSLocalMemory::m_psm[SPSM].info.bn(sx + w - 1, sy + h - 1, SBP, SBW);
|
||||
const u32 dst_end = GSLocalMemory::m_psm[DPSM].info.bn(dx + w - 1, dy + h - 1, DBP, DBW);
|
||||
// Look for an exact match on the targets.
|
||||
GSTextureCache::Target* src = GetExactTarget(SBP, SBW, spsm_s.depth ? DepthStencil : RenderTarget);
|
||||
GSTextureCache::Target* dst = GetExactTarget(DBP, DBW, dpsm_s.depth ? DepthStencil : RenderTarget);
|
||||
GSTextureCache::Target* src = GetExactTarget(SBP, SBW, spsm_s.depth ? DepthStencil : RenderTarget, src_end);
|
||||
GSTextureCache::Target* dst = GetExactTarget(DBP, DBW, dpsm_s.depth ? DepthStencil : RenderTarget, dst_end);
|
||||
|
||||
// Beware of the case where a game might create a larger texture by moving a bunch of chunks around.
|
||||
// We use dx/dy == 0 and the TBW check as a safeguard to make sure these go through to local memory.
|
||||
|
@ -2776,13 +2778,15 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|||
return true;
|
||||
}
|
||||
|
||||
GSTextureCache::Target* GSTextureCache::GetExactTarget(u32 BP, u32 BW, int type)
|
||||
GSTextureCache::Target* GSTextureCache::GetExactTarget(u32 BP, u32 BW, int type, u32 end_bp)
|
||||
{
|
||||
auto& rts = m_dst[type];
|
||||
for (auto it = rts.begin(); it != rts.end(); ++it) // Iterate targets from MRU to LRU.
|
||||
{
|
||||
Target* t = *it;
|
||||
if (t->m_TEX0.TBP0 == BP && t->m_TEX0.TBW == BW)
|
||||
const u32 end_block = (t->m_end_block < t->m_TEX0.TBP0) ? t->m_end_block + 0x4000 : t->m_end_block;
|
||||
|
||||
if (t->m_TEX0.TBP0 == BP && t->m_TEX0.TBW == BW && end_block >= end_bp)
|
||||
{
|
||||
rts.MoveFront(it.Index());
|
||||
return t;
|
||||
|
|
|
@ -455,7 +455,7 @@ public:
|
|||
Target* LookupDisplayTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale);
|
||||
|
||||
/// Looks up a target in the cache, and only returns it if the BP/BW match exactly.
|
||||
Target* GetExactTarget(u32 BP, u32 BW, int type);
|
||||
Target* GetExactTarget(u32 BP, u32 BW, int type, u32 end_bp);
|
||||
Target* GetTargetWithSharedBits(u32 BP, u32 PSM) const;
|
||||
|
||||
GSVector2i GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height);
|
||||
|
|
Loading…
Reference in New Issue