GS/HW: On EE->GS transfer only invalidate area actually transferred

This commit is contained in:
refractionpcsx2
2026-01-27 21:48:15 +00:00
committed by lightningterror
parent fa953d7bb3
commit 32a3e8e62d

View File

@@ -1899,6 +1899,25 @@ void GSState::FlushWrite()
r = m_tr.rect;
// If the end isn't where it said it would be, we need to calculate the end point.
// Star Wars - The Clone Wars just sets the rect to 16x4095 then YOLO's about half a page, then kills the transfer.
// If we just nuke the whole lot, even though nothing has been transferred, we risk killing data we don't mean to.
if (m_tr.end < m_tr.total && GSIsHardwareRenderer())
{
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[m_tr.m_blit.DPSM];
// Convert to nibbles then back to bytes after, in case trbpp is 4.
const u32 in_data_pixel_count = (((len * 2) + ((psm_s.trbpp / 4) - 1)) / (psm_s.trbpp / 4));
const u32 rect_pixel_count = r.width() * r.height();
if (rect_pixel_count > in_data_pixel_count)
{
const int calculated_height = ((in_data_pixel_count + (r.width() - 1)) / r.width());
// Just setting the height should be okay...
r.w = std::max(r.y + calculated_height, psm_s.bs.y);
}
}
InvalidateVideoMem(m_env.BITBLTBUF, r);
const GSLocalMemory::writeImage wi = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].wi;