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";
|
return "GS TRANSFER";
|
||||||
case GSFlushReason::UPLOADDIRTYTEX:
|
case GSFlushReason::UPLOADDIRTYTEX:
|
||||||
return "GS UPLOAD OVERWRITES CURRENT TEXTURE OR CLUT";
|
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:
|
case GSFlushReason::LOCALTOLOCALMOVE:
|
||||||
return "GS LOCAL TO LOCAL OVERWRITES CURRENT TEXTURE OR CLUT";
|
return "GS LOCAL TO LOCAL OVERWRITES CURRENT TEXTURE OR CLUT";
|
||||||
case GSFlushReason::DOWNLOADFIFO:
|
case GSFlushReason::DOWNLOADFIFO:
|
||||||
|
@ -1725,15 +1729,41 @@ void GSState::Write(const u8* mem, int len)
|
||||||
|
|
||||||
if (m_tr.end == 0)
|
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_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 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.
|
// 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).
|
// 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)
|
||||||
{
|
{
|
||||||
|
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);
|
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.
|
// Invalid the CLUT if it crosses paths.
|
||||||
m_mem.m_clut.InvalidateRange(write_start_bp, write_end_bp);
|
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 spo = m_mem.GetOffset(sbp, sbw, m_env.BITBLTBUF.SPSM);
|
||||||
const GSOffset dpo = m_mem.GetOffset(dbp, dbw, m_env.BITBLTBUF.DPSM);
|
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.
|
// 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.
|
// Unknown if games use this one, but best to be safe.
|
||||||
|
if (m_index.tail > 0)
|
||||||
if (m_index.tail > 0 && m_prev_env.PRIM.TME && write_end_bp >= prev_tex0.TBP0 && write_start_bp <= tex_end_bp)
|
|
||||||
{
|
{
|
||||||
|
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);
|
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;
|
GSVector4i r;
|
||||||
|
|
|
@ -271,14 +271,16 @@ public:
|
||||||
CLUTCHANGE = 1 << 3,
|
CLUTCHANGE = 1 << 3,
|
||||||
GSTRANSFER = 1 << 4,
|
GSTRANSFER = 1 << 4,
|
||||||
UPLOADDIRTYTEX = 1 << 5,
|
UPLOADDIRTYTEX = 1 << 5,
|
||||||
LOCALTOLOCALMOVE = 1 << 6,
|
UPLOADDIRTYFRAME = 1 << 6,
|
||||||
DOWNLOADFIFO = 1 << 7,
|
UPLOADDIRTYZBUF = 1 << 7,
|
||||||
SAVESTATE = 1 << 8,
|
LOCALTOLOCALMOVE = 1 << 8,
|
||||||
LOADSTATE = 1 << 9,
|
DOWNLOADFIFO = 1 << 9,
|
||||||
AUTOFLUSH = 1 << 10,
|
SAVESTATE = 1 << 10,
|
||||||
VSYNC = 1 << 11,
|
LOADSTATE = 1 << 11,
|
||||||
GSREOPEN = 1 << 12,
|
AUTOFLUSH = 1 << 12,
|
||||||
VERTEXCOUNT = 1 << 13,
|
VSYNC = 1 << 13,
|
||||||
|
GSREOPEN = 1 << 14,
|
||||||
|
VERTEXCOUNT = 1 << 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
GSFlushReason m_state_flush_reason = UNKNOWN;
|
GSFlushReason m_state_flush_reason = UNKNOWN;
|
||||||
|
|
Loading…
Reference in New Issue