Skip to content

Commit

Permalink
GS/HW: Don't try to dirty targets which don't overlap
Browse files Browse the repository at this point in the history
The current invalidation code sucks, but at least this stops things
which are blatently wrong from happening.
  • Loading branch information
stenzek authored and refractionpcsx2 committed Feb 23, 2023
1 parent c1bc1af commit c7e9c95
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pcsx2/GS/Renderers/HW/GSRendererHW.cpp
Expand Up @@ -1330,7 +1330,8 @@ void GSRendererHW::Draw()
// We trigger the sw prim render here super early, to avoid creating superfluous render targets.
if (CanUseSwPrimRender(no_rt, no_ds, draw_sprite_tex) && SwPrimRender(*this, true))
{
GL_CACHE("Possible texture decompression, drawn with SwPrimRender()");
GL_CACHE("Possible texture decompression, drawn with SwPrimRender() (BP %x BW %u TBP0 %x TBW %u)",
m_context->FRAME.Block(), m_context->FRAME.FBMSK, m_context->TEX0.TBP0, m_context->TEX0.TBW);
return;
}

Expand Down
11 changes: 11 additions & 0 deletions pcsx2/GS/Renderers/HW/GSTextureCache.cpp
Expand Up @@ -1192,6 +1192,10 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
if (!target)
return;

// Handle the case where the transfer wrapped around the end of GS memory.
const u32 end_bp = off.bn(rect.z - 1, rect.w - 1);
const u32 unwrapped_end_bp = end_bp + ((end_bp < bp) ? MAX_BLOCKS : 0);

for (int type = 0; type < 2; type++)
{
auto& list = m_dst[type];
Expand All @@ -1200,6 +1204,13 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
auto j = i;
Target* t = *j;

// Don't bother checking any further if the target doesn't overlap with the write/invalidation.
if ((bp < t->m_TEX0.TBP0 && unwrapped_end_bp < t->m_TEX0.TBP0) || bp > t->UnwrappedEndBlock())
{
++i;
continue;
}

// GH: (I think) this code is completely broken. Typical issue:
// EE write an alpha channel into 32 bits texture
// Results: the target is deleted (because HasCompatibleBits is false)
Expand Down
7 changes: 7 additions & 0 deletions pcsx2/GS/Renderers/HW/GSTextureCache.h
Expand Up @@ -248,6 +248,13 @@ class GSTextureCache
Target(const GIFRegTEX0& TEX0, const bool depth_supported, const int type);
~Target();

/// Returns true if the target wraps around the end of GS memory.
bool Wraps() const { return (m_end_block < m_TEX0.TBP0); }

/// Returns the end block for the target, but doesn't wrap at 0x3FFF.
/// Can be used for overlap tests.
u32 UnwrappedEndBlock() const { return (m_end_block + (Wraps() ? MAX_BLOCKS : 0)); }

void ResizeValidity(const GSVector4i& rect);
void UpdateValidity(const GSVector4i& rect, bool can_resize = true);

Expand Down

0 comments on commit c7e9c95

Please sign in to comment.