GS/HW: Kill old dirty targets when source not using them

This commit is contained in:
refractionpcsx2 2023-08-13 01:26:17 +01:00
parent 5cc851e175
commit 2f01299472
4 changed files with 13 additions and 11 deletions

View File

@ -2518,7 +2518,7 @@ void GSRendererHW::Draw()
rt->m_TEX0 = FRAME_TEX0;
}
if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM))
if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM || (rt && ds->m_TEX0.TBW != rt->m_TEX0.TBW)))
ds->m_TEX0 = ZBUF_TEX0;
}
else if (!m_texture_shuffle)
@ -2782,12 +2782,6 @@ void GSRendererHW::Draw()
// Temporary source *must* be invalidated before normal, because otherwise it'll be double freed.
g_texture_cache->InvalidateTemporarySource();
// Set the RT format back to 32bits after the shuffle.
if (rt && m_texture_shuffle && rt->m_32_bits_fmt)
{
rt->m_TEX0.PSM = PSMCT32;
}
// Invalidation of old targets when changing to double-buffering.
if (old_rt)
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, old_rt->m_TEX0.TBP0);

View File

@ -123,7 +123,7 @@ private:
// We modify some of the context registers to optimize away unnecessary operations.
// Instead of messing with the real context, we copy them and use those instead.
struct
struct HWCachedCtx
{
GIFRegTEX0 TEX0;
GIFRegCLAMP CLAMP;
@ -143,7 +143,7 @@ private:
return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then
}
} m_cached_ctx;
};
// CRC Hacks
bool IsBadFrame();
@ -174,6 +174,7 @@ private:
GSVector2i m_lod = {}; // Min & Max level of detail
GSHWDrawConfig m_conf = {};
HWCachedCtx m_cached_ctx;
// software sprite renderer state
std::vector<GSVertexSW> m_sw_vertex_buffer;
@ -185,7 +186,7 @@ public:
virtual ~GSRendererHW() override;
__fi static GSRendererHW* GetInstance() { return static_cast<GSRendererHW*>(g_gs_renderer.get()); }
__fi HWCachedCtx* GetCachedCtx() { return &m_cached_ctx; }
void Destroy() override;
void UpdateRenderFixes() override;

View File

@ -4008,6 +4008,13 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
}
else
{
if (GSUtil::GetChannelMask(TEX0.PSM) == 0xf && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.Block() && TEX0.TBP0 != GSRendererHW::GetInstance()->GetCachedCtx()->ZBUF.Block())
{
// Kill any possible targets we missed, they might be wrong now.
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, TEX0.TBP0, TEX0.PSM, GSRendererHW::GetInstance()->GetCachedCtx()->FRAME.FBMSK, true);
}
// maintain the clut even when paltex is on for the dump/replacement texture lookup
bool paltex = (GSConfig.GPUPaletteConversion && psm.pal > 0) || gpu_clut;
const u32* clut = (psm.pal > 0) ? static_cast<const u32*>(g_gs_renderer->m_mem.m_clut) : nullptr;

View File

@ -495,7 +495,7 @@ public:
bool Has32BitTarget(u32 bp);
void InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 write_psm = PSMCT32);
void InvalidateVideoMemType(int type, u32 bp, u32 write_psm = PSMCT32, u32 write_fbmsk = 0);
void InvalidateVideoMemType(int type, u32 bp, u32 write_psm = PSMCT32, u32 write_fbmsk = 0, bool dirty_only = false);
void InvalidateVideoMemSubTarget(GSTextureCache::Target* rt);
void InvalidateVideoMem(const GSOffset& off, const GSVector4i& r, bool target = true);
void InvalidateLocalMem(const GSOffset& off, const GSVector4i& r, bool full_flush = false);