mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Improve full dirty rect clears. Remember new EE draws.
Rocky Legends transfers the new frame sometimes just before vsync, and it was getting lost.
This commit is contained in:
parent
261b3f7e5c
commit
e2a4657777
|
@ -26,6 +26,7 @@
|
||||||
#include <iomanip> // Dump Verticles
|
#include <iomanip> // Dump Verticles
|
||||||
|
|
||||||
int GSState::s_n = 0;
|
int GSState::s_n = 0;
|
||||||
|
int GSState::s_last_transfer_draw_n = 0;
|
||||||
int GSState::s_transfer_n = 0;
|
int GSState::s_transfer_n = 0;
|
||||||
|
|
||||||
static __fi bool IsAutoFlushEnabled()
|
static __fi bool IsAutoFlushEnabled()
|
||||||
|
@ -1780,6 +1781,7 @@ void GSState::Write(const u8* mem, int len)
|
||||||
r.right = r.left + m_env.TRXREG.RRW;
|
r.right = r.left + m_env.TRXREG.RRW;
|
||||||
r.bottom = r.top + m_env.TRXREG.RRH;
|
r.bottom = r.top + m_env.TRXREG.RRH;
|
||||||
|
|
||||||
|
s_last_transfer_draw_n = s_n;
|
||||||
// Store the transfer for preloading new RT's.
|
// Store the transfer for preloading new RT's.
|
||||||
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP))
|
if ((m_draw_transfers.size() > 0 && blit.DBP == m_draw_transfers.back().blit.DBP))
|
||||||
{
|
{
|
||||||
|
@ -1982,6 +1984,8 @@ void GSState::Move()
|
||||||
r.top = m_env.TRXPOS.DSAY;
|
r.top = m_env.TRXPOS.DSAY;
|
||||||
r.right = r.left + m_env.TRXREG.RRW;
|
r.right = r.left + m_env.TRXREG.RRW;
|
||||||
r.bottom = r.top + m_env.TRXREG.RRH;
|
r.bottom = r.top + m_env.TRXREG.RRH;
|
||||||
|
|
||||||
|
s_last_transfer_draw_n = s_n;
|
||||||
// Store the transfer for preloading new RT's.
|
// Store the transfer for preloading new RT's.
|
||||||
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP))
|
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP))
|
||||||
{
|
{
|
||||||
|
|
|
@ -237,6 +237,7 @@ public:
|
||||||
std::vector<GSUploadQueue> m_draw_transfers;
|
std::vector<GSUploadQueue> m_draw_transfers;
|
||||||
|
|
||||||
static int s_n;
|
static int s_n;
|
||||||
|
static int s_last_transfer_draw_n;
|
||||||
static int s_transfer_n;
|
static int s_transfer_n;
|
||||||
|
|
||||||
static constexpr u32 STATE_VERSION = 8;
|
static constexpr u32 STATE_VERSION = 8;
|
||||||
|
|
|
@ -130,8 +130,25 @@ void GSRendererHW::VSync(u32 field, bool registers_written, bool idle_frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!idle_frame)
|
||||||
m_draw_transfers.clear();
|
{
|
||||||
|
// If it did draws very recently, we should keep the recent stuff in case it hasn't been preloaded/used yet.
|
||||||
|
// Rocky Legend does this with the main menu FMV's.
|
||||||
|
if (s_last_transfer_draw_n == s_n)
|
||||||
|
{
|
||||||
|
for (auto iter = m_draw_transfers.begin(); iter != m_draw_transfers.end();)
|
||||||
|
{
|
||||||
|
if ((s_n - iter->draw) > 5)
|
||||||
|
iter = m_draw_transfers.erase(iter);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_draw_transfers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (GSConfig.LoadTextureReplacements)
|
if (GSConfig.LoadTextureReplacements)
|
||||||
GSTextureReplacements::ProcessAsyncLoadedTextures();
|
GSTextureReplacements::ProcessAsyncLoadedTextures();
|
||||||
|
|
|
@ -99,7 +99,7 @@ bool GSTextureCache::FullRectDirty(Target* target)
|
||||||
RGBAMask rgba;
|
RGBAMask rgba;
|
||||||
rgba._u32 = GSUtil::GetChannelMask(target->m_TEX0.PSM);
|
rgba._u32 = GSUtil::GetChannelMask(target->m_TEX0.PSM);
|
||||||
// One complete dirty rect, not pieces (Add dirty rect function should be able to join these all together).
|
// One complete dirty rect, not pieces (Add dirty rect function should be able to join these all together).
|
||||||
if (target->m_age > 2 && target->m_dirty.size() == 1 && rgba._u32 == target->m_dirty[0].rgba._u32 && target->m_valid.rintersect(target->m_dirty[0].r).eq(target->m_valid))
|
if (target->m_age != 0 && target->m_dirty.size() == 1 && rgba._u32 == target->m_dirty[0].rgba._u32 && target->m_valid.rintersect(target->m_dirty[0].r).eq(target->m_valid))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue