GS-TC: Update draw rect on draw + invalidate bad match old targets

This commit is contained in:
refractionpcsx2 2023-03-18 01:58:59 +00:00
parent bfca8b8461
commit ed5984aa3a
3 changed files with 41 additions and 15 deletions

View File

@ -2053,11 +2053,14 @@ void GSRendererHW::Draw()
rt->ResizeTexture(new_w, new_h); rt->ResizeTexture(new_w, new_h);
if (!m_texture_shuffle && !m_channel_shuffle) if (!m_texture_shuffle && !m_channel_shuffle)
{
rt->ResizeValidity(rt->GetUnscaledRect()); rt->ResizeValidity(rt->GetUnscaledRect());
rt->ResizeDrawn(rt->GetUnscaledRect());
}
// Limit to 2x the vertical height of the resolution (for double buffering) // Limit to 2x the vertical height of the resolution (for double buffering)
rt->UpdateValidity(m_r, can_update_size || m_r.w <= (resolution.y * 2)); rt->UpdateValidity(m_r, can_update_size || m_r.w <= (resolution.y * 2));
rt->UpdateDrawn(m_r, can_update_size || m_r.w <= (resolution.y * 2));
// Probably changing to double buffering, so invalidate any old target that was next to it. // Probably changing to double buffering, so invalidate any old target that was next to it.
// This resolves an issue where the PCRTC will find the old target in FMV's causing flashing. // This resolves an issue where the PCRTC will find the old target in FMV's causing flashing.
// Grandia Xtreme, Onimusha Warlord. // Grandia Xtreme, Onimusha Warlord.
@ -2090,10 +2093,14 @@ void GSRendererHW::Draw()
ds->ResizeTexture(new_w, new_h); ds->ResizeTexture(new_w, new_h);
if (!m_texture_shuffle && !m_channel_shuffle) if (!m_texture_shuffle && !m_channel_shuffle)
{
ds->ResizeValidity(ds->GetUnscaledRect()); ds->ResizeValidity(ds->GetUnscaledRect());
ds->ResizeDrawn(ds->GetUnscaledRect());
}
// Limit to 2x the vertical height of the resolution (for double buffering) // Limit to 2x the vertical height of the resolution (for double buffering)
ds->UpdateValidity(m_r, can_update_size || m_r.w <= (resolution.y * 2)); ds->UpdateValidity(m_r, can_update_size || m_r.w <= (resolution.y * 2));
ds->UpdateDrawn(m_r, can_update_size || m_r.w <= (resolution.y * 2));
if (!new_rect && new_height && old_end_block != ds->m_end_block) if (!new_rect && new_height && old_end_block != ds->m_end_block)
{ {

View File

@ -2053,6 +2053,21 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
// It's quicker, and Surface Offsets can get it wrong. // It's quicker, and Surface Offsets can get it wrong.
// Example doing PSMT8H to C32, BP 0x1c80, TBP 0x1d80, incoming rect 0,128 -> 128,256 // Example doing PSMT8H to C32, BP 0x1c80, TBP 0x1d80, incoming rect 0,128 -> 128,256
// Surface offsets translates it to 0, 128 -> 128, 128, not 0, 0 -> 128, 128. // Surface offsets translates it to 0, 128 -> 128, 128, not 0, 0 -> 128, 128.
// If the RT is more than 1 frame old and the new data just doesn't line up properly, it's probably not made for it, kill the old target.
if (t->m_age > 1 && bw > 1 && bw != t->m_TEX0.TBW)
{
i = list.erase(j);
GL_CACHE("TC: Tex in RT Remove Old Target(%s) %d (0x%x) TPSM %x PSM %x bp 0x%x", to_string(type),
t->m_texture ? t->m_texture->GetID() : 0,
t->m_TEX0.TBP0,
t->m_TEX0.PSM,
psm,
bp);
delete t;
continue;
}
const GSVector2i page_size = GSLocalMemory::m_psm[psm].pgs; const GSVector2i page_size = GSLocalMemory::m_psm[psm].pgs;
const bool can_translate = CanTranslate(bp, bw, psm, r, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW); const bool can_translate = CanTranslate(bp, bw, psm, r, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW);
@ -4394,6 +4409,22 @@ void GSTextureCache::Target::UpdateIfDirtyIntersects(const GSVector4i& rc)
break; break;
} }
} }
void GSTextureCache::Target::ResizeDrawn(const GSVector4i& rect)
{
m_drawn_since_read = m_drawn_since_read.rintersect(rect);
}
void GSTextureCache::Target::UpdateDrawn(const GSVector4i& rect, bool can_resize)
{
if (can_resize)
{
if(m_drawn_since_read.rempty())
m_drawn_since_read = rect.rintersect(m_valid);
else
m_drawn_since_read = m_drawn_since_read.runion(rect);
}
}
void GSTextureCache::Target::ResizeValidity(const GSVector4i& rect) void GSTextureCache::Target::ResizeValidity(const GSVector4i& rect)
{ {
@ -4423,12 +4454,6 @@ void GSTextureCache::Target::ResizeValidity(const GSVector4i& rect)
void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect, bool can_resize) void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect, bool can_resize)
{ {
if (m_valid.runion(rect).eq(m_valid))
{
m_drawn_since_read = m_drawn_since_read.runion(rect);
return;
}
if (can_resize) if (can_resize)
{ {
if (m_valid.eq(GSVector4i::zero())) if (m_valid.eq(GSVector4i::zero()))
@ -4447,14 +4472,6 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect, bool can_res
m_end_block = (((m_end_block + page_mask) & ~page_mask)) - 1; m_end_block = (((m_end_block + page_mask) & ~page_mask)) - 1;
} }
} }
if (m_drawn_since_read.eq(GSVector4i::zero()) || !can_resize)
{
m_drawn_since_read = rect.rintersect(m_valid);
}
else
m_drawn_since_read = m_drawn_since_read.runion(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);
} }

View File

@ -267,6 +267,8 @@ public:
Target(const GIFRegTEX0& TEX0, const bool depth_supported, const int type); Target(const GIFRegTEX0& TEX0, const bool depth_supported, const int type);
~Target(); ~Target();
void ResizeDrawn(const GSVector4i& rect);
void UpdateDrawn(const GSVector4i& rect, bool can_resize = true);
void ResizeValidity(const GSVector4i& rect); void ResizeValidity(const GSVector4i& rect);
void UpdateValidity(const GSVector4i& rect, bool can_resize = true); void UpdateValidity(const GSVector4i& rect, bool can_resize = true);
void UpdateValidBits(u32 bits_written); void UpdateValidBits(u32 bits_written);