mirror of https://github.com/PCSX2/pcsx2.git
GS: Flush when FRAME or Z matches write location
This commit is contained in:
parent
35971b29bc
commit
3a953eb5df
|
@ -402,6 +402,10 @@ const char* GSState::GetFlushReasonString(GSFlushReason reason)
|
|||
return "GS TRANSFER";
|
||||
case GSFlushReason::UPLOADDIRTYTEX:
|
||||
return "GS UPLOAD OVERWRITES CURRENT TEXTURE OR CLUT";
|
||||
case GSFlushReason::UPLOADDIRTYFRAME:
|
||||
return "GS UPLOAD OVERWRITES CURRENT FRAME BUFFER";
|
||||
case GSFlushReason::UPLOADDIRTYZBUF:
|
||||
return "GS UPLOAD OVERWRITES CURRENT ZBUFFER";
|
||||
case GSFlushReason::LOCALTOLOCALMOVE:
|
||||
return "GS LOCAL TO LOCAL OVERWRITES CURRENT TEXTURE OR CLUT";
|
||||
case GSFlushReason::DOWNLOADFIFO:
|
||||
|
@ -1725,15 +1729,41 @@ void GSState::Write(const u8* mem, int len)
|
|||
|
||||
if (m_tr.end == 0)
|
||||
{
|
||||
const GIFRegTEX0& prev_tex0 = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].TEX0;
|
||||
const GSDrawingContext& prev_ctx = m_prev_env.CTXT[m_prev_env.PRIM.CTXT];
|
||||
const u32 write_start_bp = m_mem.m_psm[blit.DPSM].info.bn(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, blit.DBP, blit.DBW);
|
||||
const u32 write_end_bp = m_mem.m_psm[blit.DPSM].info.bn(m_env.TRXPOS.DSAX + w - 1, m_env.TRXPOS.DSAY + h - 1, blit.DBP, blit.DBW);
|
||||
const u32 tex_end_bp = m_mem.m_psm[prev_tex0.PSM].info.bn((1 << prev_tex0.TW) - 1, (1 << prev_tex0.TH) - 1, prev_tex0.TBP0, prev_tex0.TBW);
|
||||
|
||||
// Only flush on a NEW transfer if a pending one is using the same address or overlap.
|
||||
// Check Fast & Furious (Hardare mode) and Assault Suits Valken (either renderer) and Tomb Raider - Angel of Darkness menu (TBP != DBP but overlaps).
|
||||
if (m_index.tail > 0 && m_prev_env.PRIM.TME && write_end_bp > prev_tex0.TBP0 && write_start_bp <= tex_end_bp)
|
||||
if (m_index.tail > 0)
|
||||
{
|
||||
Flush(GSFlushReason::UPLOADDIRTYTEX);
|
||||
const u32 tex_end_bp = m_mem.m_psm[prev_ctx.TEX0.PSM].info.bn((1 << prev_ctx.TEX0.TW) - 1, (1 << prev_ctx.TEX0.TH) - 1, prev_ctx.TEX0.TBP0, prev_ctx.TEX0.TBW);
|
||||
|
||||
if (m_prev_env.PRIM.TME && write_end_bp > prev_ctx.TEX0.TBP0 && write_start_bp <= tex_end_bp)
|
||||
Flush(GSFlushReason::UPLOADDIRTYTEX);
|
||||
else
|
||||
{
|
||||
const u32 frame_mask = GSLocalMemory::m_psm[prev_ctx.FRAME.PSM].fmsk;
|
||||
const bool frame_required = (!(prev_ctx.TEST.ATE && prev_ctx.TEST.ATST == 0 && prev_ctx.TEST.AFAIL == 2) && ((prev_ctx.FRAME.FBMSK & frame_mask) != frame_mask)) || (prev_ctx.TEST.ATE && prev_ctx.TEST.ATST > ATST_ALWAYS);
|
||||
if (frame_required)
|
||||
{
|
||||
const u32 draw_start_bp = m_mem.m_psm[prev_ctx.FRAME.PSM].info.bn(temp_draw_rect.x, temp_draw_rect.y, prev_ctx.FRAME.Block(), prev_ctx.FRAME.FBW);
|
||||
const u32 draw_end_bp = m_mem.m_psm[prev_ctx.FRAME.PSM].info.bn(temp_draw_rect.z - 1, temp_draw_rect.w - 1, prev_ctx.FRAME.Block(), prev_ctx.FRAME.FBW);
|
||||
|
||||
if (write_end_bp > draw_start_bp && write_start_bp <= draw_end_bp)
|
||||
Flush(GSFlushReason::UPLOADDIRTYFRAME);
|
||||
}
|
||||
|
||||
const bool zbuf_required = (!(prev_ctx.TEST.ATE && prev_ctx.TEST.ATST == 0 && prev_ctx.TEST.AFAIL != 2) && !prev_ctx.ZBUF.ZMSK) || (prev_ctx.TEST.ZTE && prev_ctx.TEST.ZTST > ZTST_ALWAYS);
|
||||
if (zbuf_required)
|
||||
{
|
||||
const u32 draw_start_bp = m_mem.m_psm[prev_ctx.ZBUF.PSM].info.bn(temp_draw_rect.x, temp_draw_rect.y, prev_ctx.ZBUF.Block(), prev_ctx.FRAME.FBW);
|
||||
const u32 draw_end_bp = m_mem.m_psm[prev_ctx.ZBUF.PSM].info.bn(temp_draw_rect.z - 1, temp_draw_rect.w - 1, prev_ctx.ZBUF.Block(), prev_ctx.FRAME.FBW);
|
||||
|
||||
if (write_end_bp > draw_start_bp && write_start_bp <= draw_end_bp)
|
||||
Flush(GSFlushReason::UPLOADDIRTYZBUF);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Invalid the CLUT if it crosses paths.
|
||||
m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp);
|
||||
|
@ -1905,17 +1935,41 @@ void GSState::Move()
|
|||
const GSOffset spo = m_mem.GetOffset(sbp, sbw, m_env.BITBLTBUF.SPSM);
|
||||
const GSOffset dpo = m_mem.GetOffset(dbp, dbw, m_env.BITBLTBUF.DPSM);
|
||||
|
||||
GIFRegTEX0& prev_tex0 = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].TEX0;
|
||||
const GSDrawingContext& prev_ctx = m_prev_env.CTXT[m_prev_env.PRIM.CTXT];
|
||||
const u32 write_start_bp = m_mem.m_psm[m_env.BITBLTBUF.DPSM].info.bn(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, dbp, dbw);
|
||||
const u32 write_end_bp = m_mem.m_psm[m_env.BITBLTBUF.DPSM].info.bn(m_env.TRXPOS.DSAX + w - 1, m_env.TRXPOS.DSAY + h - 1, dbp, dbw);
|
||||
|
||||
const u32 write_start_bp = m_mem.m_psm[m_env.BITBLTBUF.DPSM].info.bn(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, dbp, dbw); // (m_mem.*dpsm.pa)(static_cast<int>(m_env.TRXPOS.DSAX), static_cast<int>(m_env.TRXPOS.DSAY), dbp, dbw) >> 6;
|
||||
const u32 write_end_bp = m_mem.m_psm[m_env.BITBLTBUF.DPSM].info.bn(m_env.TRXPOS.DSAX + w - 1, m_env.TRXPOS.DSAY + h - 1, dbp, dbw); // (m_mem.*dpsm.pa)(w + static_cast<int>(m_env.TRXPOS.DSAX) - 1, h + static_cast<int>(m_env.TRXPOS.DSAY) - 1, dbp, dbw) >> 6;
|
||||
const u32 tex_end_bp = m_mem.m_psm[prev_tex0.PSM].info.bn((1 << prev_tex0.TW) - 1, (1 << prev_tex0.TH) - 1, prev_tex0.TBP0, prev_tex0.TBW); // (m_mem.*dpsm.pa)((1 << prev_tex0.TW) - 1, (1 << prev_tex0.TH) - 1, prev_tex0.TBP0, prev_tex0.TBW) >> 6;
|
||||
// Only flush on a NEW transfer if a pending one is using the same address or overlap.
|
||||
// Unknown if games use this one, but best to be safe.
|
||||
|
||||
if (m_index.tail > 0 && m_prev_env.PRIM.TME && write_end_bp >= prev_tex0.TBP0 && write_start_bp <= tex_end_bp)
|
||||
if (m_index.tail > 0)
|
||||
{
|
||||
Flush(GSFlushReason::LOCALTOLOCALMOVE);
|
||||
const u32 tex_end_bp = m_mem.m_psm[prev_ctx.TEX0.PSM].info.bn((1 << prev_ctx.TEX0.TW) - 1, (1 << prev_ctx.TEX0.TH) - 1, prev_ctx.TEX0.TBP0, prev_ctx.TEX0.TBW);
|
||||
|
||||
if (m_prev_env.PRIM.TME && write_end_bp >= prev_ctx.TEX0.TBP0 && write_start_bp <= tex_end_bp)
|
||||
Flush(GSFlushReason::LOCALTOLOCALMOVE);
|
||||
else
|
||||
{
|
||||
const u32 frame_mask = GSLocalMemory::m_psm[prev_ctx.FRAME.PSM].fmsk;
|
||||
const bool frame_required = (!(prev_ctx.TEST.ATE && prev_ctx.TEST.ATST == 0 && prev_ctx.TEST.AFAIL == 2) && ((prev_ctx.FRAME.FBMSK & frame_mask) != frame_mask)) || (prev_ctx.TEST.ATE && prev_ctx.TEST.ATST > ATST_ALWAYS);
|
||||
if (frame_required)
|
||||
{
|
||||
const u32 draw_start_bp = m_mem.m_psm[prev_ctx.FRAME.PSM].info.bn(temp_draw_rect.x, temp_draw_rect.y, prev_ctx.FRAME.Block(), prev_ctx.FRAME.FBW);
|
||||
const u32 draw_end_bp = m_mem.m_psm[prev_ctx.FRAME.PSM].info.bn(temp_draw_rect.z - 1, temp_draw_rect.w - 1, prev_ctx.FRAME.Block(), prev_ctx.FRAME.FBW);
|
||||
|
||||
if (write_end_bp > draw_start_bp && write_start_bp <= draw_end_bp)
|
||||
Flush(GSFlushReason::UPLOADDIRTYFRAME);
|
||||
}
|
||||
|
||||
const bool zbuf_required = (!(prev_ctx.TEST.ATE && prev_ctx.TEST.ATST == 0 && prev_ctx.TEST.AFAIL != 2) && !prev_ctx.ZBUF.ZMSK) || (prev_ctx.TEST.ZTE && prev_ctx.TEST.ZTST > ZTST_ALWAYS);
|
||||
if (zbuf_required)
|
||||
{
|
||||
const u32 draw_start_bp = m_mem.m_psm[prev_ctx.ZBUF.PSM].info.bn(temp_draw_rect.x, temp_draw_rect.y, prev_ctx.ZBUF.Block(), prev_ctx.FRAME.FBW);
|
||||
const u32 draw_end_bp = m_mem.m_psm[prev_ctx.ZBUF.PSM].info.bn(temp_draw_rect.z - 1, temp_draw_rect.w - 1, prev_ctx.ZBUF.Block(), prev_ctx.FRAME.FBW);
|
||||
|
||||
if (write_end_bp > draw_start_bp && write_start_bp <= draw_end_bp)
|
||||
Flush(GSFlushReason::UPLOADDIRTYZBUF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSVector4i r;
|
||||
|
|
|
@ -271,14 +271,16 @@ public:
|
|||
CLUTCHANGE = 1 << 3,
|
||||
GSTRANSFER = 1 << 4,
|
||||
UPLOADDIRTYTEX = 1 << 5,
|
||||
LOCALTOLOCALMOVE = 1 << 6,
|
||||
DOWNLOADFIFO = 1 << 7,
|
||||
SAVESTATE = 1 << 8,
|
||||
LOADSTATE = 1 << 9,
|
||||
AUTOFLUSH = 1 << 10,
|
||||
VSYNC = 1 << 11,
|
||||
GSREOPEN = 1 << 12,
|
||||
VERTEXCOUNT = 1 << 13,
|
||||
UPLOADDIRTYFRAME = 1 << 6,
|
||||
UPLOADDIRTYZBUF = 1 << 7,
|
||||
LOCALTOLOCALMOVE = 1 << 8,
|
||||
DOWNLOADFIFO = 1 << 9,
|
||||
SAVESTATE = 1 << 10,
|
||||
LOADSTATE = 1 << 11,
|
||||
AUTOFLUSH = 1 << 12,
|
||||
VSYNC = 1 << 13,
|
||||
GSREOPEN = 1 << 14,
|
||||
VERTEXCOUNT = 1 << 15,
|
||||
};
|
||||
|
||||
GSFlushReason m_state_flush_reason = UNKNOWN;
|
||||
|
|
Loading…
Reference in New Issue