mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Don't try to dirty targets which don't overlap
The current invalidation code sucks, but at least this stops things which are blatently wrong from happening.
This commit is contained in:
parent
c1bc1af302
commit
c7e9c9542e
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
@ -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)
|
||||
|
|
|
@ -248,6 +248,13 @@ public:
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue