From e2c472baa9267270f7c5c23c0c4cb9d9d47796f4 Mon Sep 17 00:00:00 2001 From: iMineLink Date: Fri, 19 Jun 2020 21:36:19 +0200 Subject: [PATCH] GSdx-hw, TC: invalidate Source w overlapping draw. (#3131) Improve texture cache Source objects invalidation logic taking into account overlapping with current draw. Fixes eyes rendering for the Major in Jak 1. --- plugins/GSdx/Renderers/HW/GSTextureCache.cpp | 33 ++++++++++++++------ plugins/GSdx/Renderers/HW/GSTextureCache.h | 5 +-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/plugins/GSdx/Renderers/HW/GSTextureCache.cpp b/plugins/GSdx/Renderers/HW/GSTextureCache.cpp index a04e8cfc10..632aea6b89 100644 --- a/plugins/GSdx/Renderers/HW/GSTextureCache.cpp +++ b/plugins/GSdx/Renderers/HW/GSTextureCache.cpp @@ -161,6 +161,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0 src->m_from_target_TEX0 = dst->m_TEX0; src->m_32_bits_fmt = dst->m_32_bits_fmt; src->m_valid_rect = dst->m_valid; + src->m_end_block = dst->m_end_block; // Insert the texture in the hash set to keep track of it. But don't bother with // texture cache list. It means that a new Source is created everytime we need it. @@ -865,10 +866,11 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* off, const GSVector4i& rect, b else { // render target used as input texture - // TODO - b |= bp == s->m_from_target_TEX0.TBP0; + if (!b) + b = s->Overlaps(bp, bw, psm, rect); + if(b) { m_src.RemoveAt(s); @@ -1222,6 +1224,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_from_target = dst->m_texture; src->m_from_target_TEX0 = dst->m_TEX0; src->m_texture->SetScale(scale); + src->m_end_block = dst->m_end_block; if (psm.pal > 0) { // Attach palette for GPU texture conversion @@ -1248,6 +1251,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_target = true; src->m_from_target = dst->m_texture; src->m_from_target_TEX0 = dst->m_TEX0; + src->m_end_block = dst->m_end_block; // Even if we sample the framebuffer directly we might need the palette // to handle the format conversion on GPU @@ -1281,6 +1285,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_from_target = dst->m_texture; src->m_from_target_TEX0 = dst->m_TEX0; src->m_valid_rect = dst->m_valid; + src->m_end_block = dst->m_end_block; dst->Update(); @@ -1586,6 +1591,7 @@ GSTextureCache::Surface::Surface(GSRenderer* r, uint8* temp) , m_temp(temp) , m_32_bits_fmt(false) , m_shared_texture(false) + , m_end_block(0) { m_TEX0.TBP0 = 0x3fff; } @@ -1603,6 +1609,21 @@ void GSTextureCache::Surface::UpdateAge() m_age = 0; } +bool GSTextureCache::Surface::Inside(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect) +{ + // Valid only for color formats. + uint32 const end_block = GSLocalMemory::m_psm[psm].bn(rect.z - 1, rect.w - 1, bp, bw); + return bp >= m_TEX0.TBP0 && end_block <= m_end_block; +} + +bool GSTextureCache::Surface::Overlaps(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect) +{ + // Valid only for color formats. + uint32 const end_block = GSLocalMemory::m_psm[psm].bn(rect.z - 1, rect.w - 1, bp, bw); + return (m_TEX0.TBP0 <= bp && bp <= m_end_block) + || (m_TEX0.TBP0 <= end_block && end_block <= m_end_block); +} + // GSTextureCache::Source GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, uint8* temp, bool dummy_container) @@ -1877,7 +1898,6 @@ GSTextureCache::Target::Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* tem , m_type(-1) , m_used(false) , m_depth_supported(depth_supported) - , m_end_block(0) { m_TEX0 = TEX0; m_32_bits_fmt |= (GSLocalMemory::m_psm[TEX0.PSM].trbpp != 16); @@ -1989,13 +2009,6 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect) // GL_CACHE("UpdateValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w); } -bool GSTextureCache::Target::Inside(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect) -{ - uint32 block = GSLocalMemory::m_psm[psm].bn(rect.z - 1, rect.w - 1, bp, bw); // Valid only for color formats - - return bp >= m_TEX0.TBP0 && block <= m_end_block; -} - // GSTextureCache::SourceMap void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset* off) diff --git a/plugins/GSdx/Renderers/HW/GSTextureCache.h b/plugins/GSdx/Renderers/HW/GSTextureCache.h index 20f0639178..cffaa1c488 100644 --- a/plugins/GSdx/Renderers/HW/GSTextureCache.h +++ b/plugins/GSdx/Renderers/HW/GSTextureCache.h @@ -43,12 +43,15 @@ public: uint8* m_temp; bool m_32_bits_fmt; // Allow to detect the casting of 32 bits as 16 bits texture bool m_shared_texture; + uint32 m_end_block; // Hint of the surface area. public: Surface(GSRenderer* r, uint8* temp); virtual ~Surface(); void UpdateAge(); + bool Inside(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect); + bool Overlaps(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect); }; struct PaletteKey { @@ -138,13 +141,11 @@ public: GSVector4i m_valid; bool m_depth_supported; bool m_dirty_alpha; - uint32 m_end_block; // Hint of the target area public: Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* temp, bool depth_supported); void UpdateValidity(const GSVector4i& rect); - bool Inside(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect); void Update(); };