Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GS/HW: Don't kill old targets unless completely dirty or targets overlap #11385

Merged
merged 2 commits into from
Jun 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions pcsx2/GS/Renderers/HW/GSTextureCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe
const bool matched_format = (src_info->bpp == dst_info->bpp);
const bool block_matched_format = matched_format && block_aligned_rect;
const bool req_depth_offset = (src_info->depth > 0 && !page_aligned_rect);

bool address_offset = block_offset > 0;
// If there is block offset left over, try to adjust to that.
if (block_matched_format && (block_offset || req_depth_offset))
{
Expand Down Expand Up @@ -586,6 +586,7 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe

b2a_offset.x = 0;
}
address_offset = false;
in_rect = (in_rect + b2a_offset.xyxy()).max_i32(GSVector4i(0));

if (block_offset > 0 && !req_depth_offset)
Expand Down Expand Up @@ -647,6 +648,17 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe
const int block_y = in_rect.y & (src_info->pgs.y - 1);
x_offset += block_x;
y_offset += block_y;

if (address_offset)
{
const int blocks_wide = src_info->pgs.x / src_info->bs.x;
const int block_x_offset = (block_offset % blocks_wide) * src_info->bs.x;
const int block_y_offset = (block_offset / blocks_wide) * src_info->bs.y;

x_offset += block_x_offset;
y_offset += block_y_offset;
}

if (block_x)
in_rect = GSVector4i(in_rect.x - block_x, in_rect.y, in_rect.z - block_x, in_rect.w);
if (block_y)
Expand Down Expand Up @@ -4296,7 +4308,7 @@ void GSTextureCache::IncAge()

AgeHashCache();

// As of 04/15/2024 this is s et to 60 (just 1 second of targets), which should be fine now as it doesn't destroy targets which haven't been coevred.
// As of 04/15/2024 this is s et to 60 (just 1 second of targets), which should be fine now as it doesn't destroy targets which haven't been covered.
//
// For reference, here are some games sensitive to killing old targets:
// Original maxage was 4 here, Xenosaga 2 needs at least 240, else it flickers on scene transitions.
Expand All @@ -4318,7 +4330,7 @@ void GSTextureCache::IncAge()
{
const Target* overlapping_tgt = FindOverlappingTarget(t);

if (!t->m_dirty.empty() || overlapping_tgt != nullptr)
if (overlapping_tgt != nullptr || t->m_dirty.GetTotalRect(t->m_TEX0, GSVector2i(t->m_valid.width(), t->m_valid.height())).rintersect(t->m_valid).eq(t->m_valid))
{
i = list.erase(i);
GL_CACHE("TC: Remove Target(%s): (0x%x) due to age", to_string(type),
Expand Down