mirror of https://github.com/PCSX2/pcsx2.git
GS: Add Auto Flush for Z buffer draws
Adjust Burnout CRC hack
This commit is contained in:
parent
d9f914eb7c
commit
90a4a11d49
|
@ -2433,10 +2433,14 @@ GSState::PRIM_OVERLAP GSState::PrimitiveOverlap()
|
|||
|
||||
__forceinline void GSState::HandleAutoFlush()
|
||||
{
|
||||
const bool frame_hit = (m_context->FRAME.Block() == m_context->TEX0.TBP0) && !(m_context->TEST.ATE && m_context->TEST.ATST == 0 && m_context->TEST.AFAIL == 2);
|
||||
// There's a strange behaviour we need to test on a PS2 here, if the FRAME is a Z format, like Powerdrome something swaps over, and it seems Alpha Fail of "FB Only" writes to the Z.. it's odd.
|
||||
const bool zbuf_hit = (m_context->ZBUF.Block() == m_context->TEX0.TBP0) && !(m_context->TEST.ATE && m_context->TEST.ATST == 0 && m_context->TEST.AFAIL != 2 && (m_context->ZBUF.PSM & 0x30) == 0x30) && !m_context->ZBUF.ZMSK;
|
||||
|
||||
// To briefly explain what's going on here, what we are checking for is draws over a texture when the source and destination are themselves.
|
||||
// Because one page of the texture gets buffered in the Texture Cache (the PS2's one) if any of those pixels are overwritten, you still read the old data.
|
||||
// So we need to calculate if a page boundary is being crossed for the format it is in and if the same part of the texture being written and read inside the draw.
|
||||
if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && (m_context->TEX0.PSM == m_context->FRAME.PSM) && PRIM->TME && (m_context->FRAME.FBMSK != 0xFFFFFFFF))
|
||||
if (((frame_hit && ((m_context->TEX0.PSM ^ m_context->FRAME.PSM) & ~0x30) == 0) || (zbuf_hit && ((m_context->TEX0.PSM ^ m_context->ZBUF.PSM) & ~0x30) == 0)) && PRIM->TME && (m_context->FRAME.FBMSK != 0xFFFFFFFF))
|
||||
{
|
||||
const int page_mask_x = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.x - 1);
|
||||
const int page_mask_y = ~(GSLocalMemory::m_psm[m_context->TEX0.PSM].pgs.y - 1);
|
||||
|
@ -2513,12 +2517,20 @@ __forceinline void GSState::HandleAutoFlush()
|
|||
|
||||
if(page_crossed)
|
||||
{
|
||||
// Update the vertex trace, scissor it (important for Jak 3!) and intersect with the current texture.
|
||||
if((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
// Make sure the format matches, otherwise the coordinates aren't gonna match, so the draws won't intersect.
|
||||
if ((frame_hit && (m_context->TEX0.PSM == m_context->FRAME.PSM)) || (zbuf_hit && (m_context->TEX0.PSM == m_context->ZBUF.PSM)))
|
||||
{
|
||||
// Update the vertex trace, scissor it (important for Jak 3!) and intersect with the current texture.
|
||||
if ((m_index.tail - 1) == current_tex_end)
|
||||
m_vt.Update(m_vertex.buff, m_index.buff, m_vertex.tail - m_vertex.head, m_index.tail, GSUtil::GetPrimClass(PRIM->PRIM));
|
||||
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
GSVector4i area_out = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in));
|
||||
if (!area_out.rintersect(tex_rect).rempty())
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
else // Format of the TEX and FRAME/Z is different, so uhh, just fall back to flushing each page. It's slower, sorry.
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
@ -2534,29 +2546,19 @@ __forceinline void GSState::VertexKick(u32 skip)
|
|||
switch (prim)
|
||||
{
|
||||
case GS_POINTLIST:
|
||||
case GS_INVALID:
|
||||
n = 1;
|
||||
break;
|
||||
case GS_LINELIST:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_SPRITE:
|
||||
case GS_LINESTRIP:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_TRIANGLELIST:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_TRIANGLESTRIP:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_TRIANGLEFAN:
|
||||
n = 3;
|
||||
break;
|
||||
case GS_SPRITE:
|
||||
n = 2;
|
||||
break;
|
||||
case GS_INVALID:
|
||||
n = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_context->FRAME.FBMSK != 0xFFFFFFFF)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
bool s_nativeres;
|
||||
static CRCHackLevel s_crc_hack_level = CRCHackLevel::Full;
|
||||
|
||||
bool s_autoflush;
|
||||
// hacks
|
||||
#define CRC_Partial (s_crc_hack_level >= CRCHackLevel::Partial)
|
||||
#define CRC_Full (s_crc_hack_level >= CRCHackLevel::Full)
|
||||
|
@ -419,7 +419,7 @@ bool GSC_BurnoutGames(const GSFrameInfo& fi, int& skip)
|
|||
// 0x01dc0 01c00(MP) ntsc, 0x01f00 0x01d40(MP) ntsc progressive, 0x02200(MP) pal.
|
||||
// Yellow stripes.
|
||||
// Multiplayer tested only on Takedown.
|
||||
skip = 4;
|
||||
skip = s_autoflush ? 2 : 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -950,6 +950,7 @@ void GSState::SetupCrcHack()
|
|||
|
||||
s_nativeres = m_nativeres;
|
||||
s_crc_hack_level = m_crc_hack_level;
|
||||
s_autoflush = m_userhacks_auto_flush;
|
||||
|
||||
memset(lut, 0, sizeof(lut));
|
||||
|
||||
|
|
Loading…
Reference in New Issue