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.
This commit is contained in:
iMineLink 2020-06-19 21:36:19 +02:00 committed by GitHub
parent 5362fc9c26
commit e2c472baa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 12 deletions

View File

@ -161,6 +161,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
src->m_from_target_TEX0 = dst->m_TEX0; src->m_from_target_TEX0 = dst->m_TEX0;
src->m_32_bits_fmt = dst->m_32_bits_fmt; src->m_32_bits_fmt = dst->m_32_bits_fmt;
src->m_valid_rect = dst->m_valid; 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 // 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. // 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 else
{ {
// render target used as input texture // render target used as input texture
// TODO
b |= bp == s->m_from_target_TEX0.TBP0; b |= bp == s->m_from_target_TEX0.TBP0;
if (!b)
b = s->Overlaps(bp, bw, psm, rect);
if(b) if(b)
{ {
m_src.RemoveAt(s); 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 = dst->m_texture;
src->m_from_target_TEX0 = dst->m_TEX0; src->m_from_target_TEX0 = dst->m_TEX0;
src->m_texture->SetScale(scale); src->m_texture->SetScale(scale);
src->m_end_block = dst->m_end_block;
if (psm.pal > 0) { if (psm.pal > 0) {
// Attach palette for GPU texture conversion // Attach palette for GPU texture conversion
@ -1248,6 +1251,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_target = true; src->m_target = true;
src->m_from_target = dst->m_texture; src->m_from_target = dst->m_texture;
src->m_from_target_TEX0 = dst->m_TEX0; 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 // Even if we sample the framebuffer directly we might need the palette
// to handle the format conversion on GPU // 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 = dst->m_texture;
src->m_from_target_TEX0 = dst->m_TEX0; src->m_from_target_TEX0 = dst->m_TEX0;
src->m_valid_rect = dst->m_valid; src->m_valid_rect = dst->m_valid;
src->m_end_block = dst->m_end_block;
dst->Update(); dst->Update();
@ -1586,6 +1591,7 @@ GSTextureCache::Surface::Surface(GSRenderer* r, uint8* temp)
, m_temp(temp) , m_temp(temp)
, m_32_bits_fmt(false) , m_32_bits_fmt(false)
, m_shared_texture(false) , m_shared_texture(false)
, m_end_block(0)
{ {
m_TEX0.TBP0 = 0x3fff; m_TEX0.TBP0 = 0x3fff;
} }
@ -1603,6 +1609,21 @@ void GSTextureCache::Surface::UpdateAge()
m_age = 0; 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
GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, uint8* temp, bool dummy_container) 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_type(-1)
, m_used(false) , m_used(false)
, m_depth_supported(depth_supported) , m_depth_supported(depth_supported)
, m_end_block(0)
{ {
m_TEX0 = TEX0; m_TEX0 = TEX0;
m_32_bits_fmt |= (GSLocalMemory::m_psm[TEX0.PSM].trbpp != 16); 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); // 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 // GSTextureCache::SourceMap
void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset* off) void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSOffset* off)

View File

@ -43,12 +43,15 @@ public:
uint8* m_temp; uint8* m_temp;
bool m_32_bits_fmt; // Allow to detect the casting of 32 bits as 16 bits texture bool m_32_bits_fmt; // Allow to detect the casting of 32 bits as 16 bits texture
bool m_shared_texture; bool m_shared_texture;
uint32 m_end_block; // Hint of the surface area.
public: public:
Surface(GSRenderer* r, uint8* temp); Surface(GSRenderer* r, uint8* temp);
virtual ~Surface(); virtual ~Surface();
void UpdateAge(); 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 { struct PaletteKey {
@ -138,13 +141,11 @@ public:
GSVector4i m_valid; GSVector4i m_valid;
bool m_depth_supported; bool m_depth_supported;
bool m_dirty_alpha; bool m_dirty_alpha;
uint32 m_end_block; // Hint of the target area
public: public:
Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* temp, bool depth_supported); Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* temp, bool depth_supported);
void UpdateValidity(const GSVector4i& rect); void UpdateValidity(const GSVector4i& rect);
bool Inside(uint32 bp, uint32 bw, uint32 psm, const GSVector4i& rect);
void Update(); void Update();
}; };