mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-12 02:08:45 +00:00
GS/TC: Improve handling of different format overlap in preload
This commit is contained in:
committed by
lightningterror
parent
afb875f2c6
commit
d89b4b6fa1
@@ -3565,16 +3565,62 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
||||
|
||||
// Make sure there's sufficient compatibility/overlap between the old target and the new target
|
||||
// to warrant loading from the old target.
|
||||
const u32 old_buffer_width = std::max(1U, old_dst->m_TEX0.TBW);
|
||||
|
||||
if (old_dst->m_TEX0.PSM != dst->m_TEX0.PSM ||
|
||||
!old_dst->Overlaps(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, dst_valid))
|
||||
{
|
||||
if (old_dst->m_TEX0.TBP0 == dst->m_TEX0.TBP0 && dst_end_block >= old_dst->m_end_block && (!src || !src->m_target || src->m_from_target != old_dst))
|
||||
{
|
||||
InvalidateSourcesFromTarget(old_dst);
|
||||
i = list.erase(j);
|
||||
delete old_dst;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (old_dst->Overlaps(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, dst_valid))
|
||||
{
|
||||
const GSLocalMemory::psm_t& psm_o = GSLocalMemory::m_psm[old_dst->m_TEX0.PSM];
|
||||
if (dst->m_TEX0.TBP0 > old_dst->m_TEX0.TBP0)
|
||||
{
|
||||
const int block_diff = dst->m_TEX0.TBP0 - old_dst->m_TEX0.TBP0;
|
||||
const u32 old_pages_wide = old_buffer_width * 64 / psm_o.pgs.x;
|
||||
if ((block_diff % (GS_BLOCKS_PER_PAGE * old_pages_wide)) == 0) // Check for left alignment.
|
||||
{
|
||||
const int new_height = block_diff / (GS_BLOCKS_PER_PAGE * old_pages_wide) * psm_o.pgs.y;
|
||||
old_dst->m_valid = old_dst->m_valid.rintersect(GSVector4i(old_dst->m_valid.x, old_dst->m_valid.y, old_dst->m_valid.z, new_height));
|
||||
old_dst->ResizeValidity(old_dst->m_valid);
|
||||
}
|
||||
}
|
||||
else // new target is behind the old one, so need to move the start of the old one to the end block of the new.
|
||||
{
|
||||
const int block_diff = dst_end_block - old_dst->m_TEX0.TBP0;
|
||||
const u32 old_pages_wide = old_buffer_width * 64 / psm_o.pgs.x;
|
||||
|
||||
if ((block_diff % (GS_BLOCKS_PER_PAGE * old_pages_wide)) == 0) // Check for left alignment.
|
||||
{
|
||||
const int change_height = block_diff / (GS_BLOCKS_PER_PAGE * old_pages_wide) * psm_o.pgs.y;
|
||||
old_dst->m_valid = old_dst->m_valid.rintersect(GSVector4i(old_dst->m_valid.x, old_dst->m_valid.y, old_dst->m_valid.z, old_dst->m_valid.w - change_height));
|
||||
old_dst->m_TEX0.TBP0 += block_diff;
|
||||
|
||||
const GSVector2i new_scaled_size = GSVector2i(old_dst->m_unscaled_size * old_dst->m_scale);
|
||||
if (GSTexture* tex = g_gs_device->CreateCompatible(dst->m_texture, new_scaled_size, true))
|
||||
{
|
||||
const int height_offset = change_height * old_dst->m_scale;
|
||||
g_gs_device->CopyRect(old_dst->m_texture, tex, GSVector4i(0, height_offset, old_dst->GetUnscaledWidth() * old_dst->m_scale, old_dst->GetUnscaledHeight() * old_dst->m_scale), 0, 0);
|
||||
|
||||
g_gs_device->Recycle(old_dst->m_texture);
|
||||
old_dst->m_texture = tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const int page_diff = std::abs(static_cast<int>(old_dst->m_TEX0.TBP0 - dst->m_TEX0.TBP0)) >> 5;
|
||||
const u32 new_buffer_width = std::max(1U, dst->m_TEX0.TBW);
|
||||
const u32 old_buffer_width = std::max(1U, old_dst->m_TEX0.TBW);
|
||||
|
||||
// Handle cases where the buffer widths don't match.
|
||||
if (new_buffer_width != old_buffer_width)
|
||||
@@ -3592,7 +3638,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
||||
const u32 old_pages_wide = old_buffer_width * 64 / psm_s.pgs.x;
|
||||
if ((block_diff % (32 * old_pages_wide)) == 0) // Check for left alignment.
|
||||
{
|
||||
const int new_height = block_diff / (32 * old_pages_wide) * psm_s.pgs.y;
|
||||
const int new_height = block_diff / (GS_BLOCKS_PER_PAGE * old_pages_wide) * psm_s.pgs.y;
|
||||
old_dst->m_valid = old_dst->m_valid.rintersect(GSVector4i(0, 0, old_dst->GetUnscaledWidth(), new_height));
|
||||
if (old_dst->m_valid.rempty())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user