GSdx: next attempt to fix frame skipping

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5078 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2012-01-21 12:34:36 +00:00
parent 9b8c753ead
commit 20cd5e9b81
5 changed files with 147 additions and 16 deletions

View File

@ -92,7 +92,8 @@ enum GIF_REG
enum GIF_REG_COMPLEX
{
GIF_REG_STQRGBAXYZF2 = 0x00,
GIF_REG_STQRGBAXYZF2 = 0x00,
GIF_REG_STQRGBAXYZ2 = 0x01,
};
enum GIF_A_D_REG
@ -1101,19 +1102,58 @@ __aligned(struct, 32) GIFPath
uint32 type;
GSVector4i regs;
enum {TYPE_UNKNOWN, TYPE_ADONLY, TYPE_STQRGBAXYZF2};
enum {TYPE_UNKNOWN, TYPE_ADONLY, TYPE_STQRGBAXYZF2, TYPE_STQRGBAXYZ2};
__forceinline void SetTag(const void* mem)
{
GSVector4i v = GSVector4i::load<false>(mem);
GSVector4i::store<true>(&tag, v);
reg = 0;
nreg = tag.NREG ? tag.NREG : 16;
regs = v.uph8(v >> 4) & GSVector4i::x0f(nreg);
nloop = tag.NLOOP;
if(regs.u32[0] == 0x00040102 && nreg == 3) type = TYPE_STQRGBAXYZF2;
else if(regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1) type = TYPE_ADONLY;
else type = TYPE_UNKNOWN;
type = TYPE_UNKNOWN;
if(tag.FLG == GIF_FLG_PACKED)
{
if(regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1)
{
type = TYPE_ADONLY;
}
else
{
switch(nreg)
{
case 1: break;
case 2: break;
case 3:
if(regs.u32[0] == 0x00040102) type = TYPE_STQRGBAXYZF2; // many games, TODO: formats mixed with NOPs (xeno2: 040f010f02, 04010f020f, mgs3: 04010f0f02, 0401020f0f, 04010f020f)
if(regs.u32[0] == 0x00050102) type = TYPE_STQRGBAXYZ2; // GoW (has other crazy formats, like ...030503050103)
// TODO: common types with UV instead
break;
case 4: break;
case 5: break;
case 6: break;
case 7: break;
case 8: break;
case 9:
if(regs.u32[0] == 0x02040102 && regs.u32[1] == 0x01020401 && regs.u32[2] == 0x00000004) {type = TYPE_STQRGBAXYZF2; nreg = 3; nloop *= 3;} // ffx
break;
case 10: break;
case 11: break;
case 12:
if(regs.u32[0] == 0x02040102 && regs.u32[1] == 0x01020401 && regs.u32[2] == 0x04010204) {type = TYPE_STQRGBAXYZF2; nreg = 3; nloop *= 4;} // dq8 (not many, mostly 040102)
break;
case 13: break;
case 14: break;
case 15: break;
case 16: break;
default:
__assume(0);
}
}
}
}
__forceinline uint8 GetReg()

View File

@ -131,9 +131,28 @@ void GSRendererSW::VSync(int field)
m_regs->PMODE.ALP
);
fprintf(s_fp, "SMODE1 %08x_%08x\n",
m_regs->SMODE1.u32[0],
m_regs->SMODE1.u32[1]
fprintf(s_fp, "SMODE1 CLKSEL=%d CMOD=%d EX=%d GCONT=%d LC=%d NVCK=%d PCK2=%d PEHS=%d PEVS=%d PHS=%d PRST=%d PVS=%d RC=%d SINT=%d SLCK=%d SLCK2=%d SPML=%d T1248=%d VCKSEL=%d VHP=%d XPCK=%d\n",
m_regs->SMODE1.CLKSEL,
m_regs->SMODE1.CMOD,
m_regs->SMODE1.EX,
m_regs->SMODE1.GCONT,
m_regs->SMODE1.LC,
m_regs->SMODE1.NVCK,
m_regs->SMODE1.PCK2,
m_regs->SMODE1.PEHS,
m_regs->SMODE1.PEVS,
m_regs->SMODE1.PHS,
m_regs->SMODE1.PRST,
m_regs->SMODE1.PVS,
m_regs->SMODE1.RC,
m_regs->SMODE1.SINT,
m_regs->SMODE1.SLCK,
m_regs->SMODE1.SLCK2,
m_regs->SMODE1.SPML,
m_regs->SMODE1.T1248,
m_regs->SMODE1.VCKSEL,
m_regs->SMODE1.VHP,
m_regs->SMODE1.XPCK
);
fprintf(s_fp, "SMODE2 INT=%d FFMD=%d DPMS=%d\n",
@ -485,7 +504,7 @@ void GSRendererSW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
{
if(m_fzb_pages[*p])
{
Sync(6);
Sync(7);
break;
}
@ -581,7 +600,7 @@ void GSRendererSW::CheckDependencies(SharedData* sd)
if(source_syncpoint)
{
Sync(7);
Sync(8);
}
sd->UseSourcePages();
@ -598,7 +617,7 @@ void GSRendererSW::CheckDependencies(SharedData* sd)
if(target_syncpoint)
{
Sync(8);
Sync(9);
}
}
@ -653,7 +672,7 @@ bool GSRendererSW::CheckTargetPages(const uint32* fb_pages, const uint32* zb_pag
return true;
}
if(LOG) {fprintf(s_fp, "no syncpoint *\n"); fflush(s_fp);}
//if(LOG) {fprintf(s_fp, "no syncpoint *\n"); fflush(s_fp);}
}
}
else
@ -759,7 +778,7 @@ bool GSRendererSW::CheckSourcePages(SharedData* sd)
for(size_t i = 0; sd->m_tex[i].t != NULL; i++)
{
sd->m_tex[i].t->m_offset->GetPages(sd->m_tex[i].r, m_tmp_pages);
uint32* pages = m_tmp_pages; // sd->m_tex[i].t->m_pages.n;
for(const uint32* p = pages; *p != GSOffset::EOP; p++)
@ -1337,9 +1356,16 @@ void GSRendererSW::SharedData::UseSourcePages()
{
m_parent->UsePages(m_tex[i].t->m_pages.n, 2);
m_tex[i].t->Update(m_tex[i].r); // TODO: check return value, false (out-of-memory) then disable texturing
if(m_tex[i].t->Update(m_tex[i].r))
{
global.tex[i] = m_tex[i].t->m_buff;
}
else
{
printf("GSdx: out-of-memory, texturing temporarily disabled\n");
global.tex[i] = m_tex[i].t->m_buff;
global.sel.tfx = TFX_NONE;
}
// TODO
/*

View File

@ -166,6 +166,7 @@ void GSState::SetFrameSkip(int skip)
m_fpGIFRegHandlers[GIF_A_D_REG_XYZ3] = &GSState::GIFRegHandlerNOP;
m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZF2] = &GSState::GIFPackedRegHandlerNOP;
m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZ2] = &GSState::GIFPackedRegHandlerNOP;
}
else
{
@ -223,6 +224,7 @@ void GSState::ResetHandlers()
m_fpGIFRegHandlerXYZ[P][2] = &GSState::GIFRegHandlerXYZ2<P, 0>; \
m_fpGIFRegHandlerXYZ[P][3] = &GSState::GIFRegHandlerXYZ2<P, 1>; \
m_fpGIFPackedRegHandlerSTQRGBAXYZF2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZF2<P>; \
m_fpGIFPackedRegHandlerSTQRGBAXYZ2[P] = &GSState::GIFPackedRegHandlerSTQRGBAXYZ2<P>; \
SetHandlerXYZ(GS_POINTLIST);
SetHandlerXYZ(GS_LINELIST);
@ -340,6 +342,8 @@ GSVector4i GSState::GetFrameRect(int i)
GSVector2i GSState::GetDeviceSize(int i)
{
// TODO: return (m_regs->SMODE1.CMOD & 1) ? GSVector2i(640, 576) : GSVector2i(640, 480);
// TODO: other params of SMODE1 should affect the true device display size
// TODO2: pal games at 60Hz
@ -538,6 +542,33 @@ void GSState::GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, ui
}
}
template<uint32 prim>
void GSState::GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size)
{
ASSERT(size > 0 && size % 3 == 0);
const GIFPackedReg* RESTRICT r_end = r + size;
while(r < r_end)
{
GSVector4i st = GSVector4i::loadl(&r[0].u64[0]);
GSVector4i q = GSVector4i::loadl(&r[0].u64[1]);
GSVector4i rgba = (GSVector4i::load<false>(&r[1]) & GSVector4i::x000000ff()).ps32().pu16();
m_v.m[0] = st.upl64(rgba.upl32(q)); // TODO: only store the last one
GSVector4i xy = GSVector4i::loadl(&r[2].u64[0]);
GSVector4i z = GSVector4i::loadl(&r[2].u64[1]);
GSVector4i xyz = xy.upl16(xy.srl<4>()).upl32(z);
m_v.m[1] = xyz.upl64(GSVector4i::loadl(&m_v.UV)); // TODO: only store the last one
VertexKick<prim>(r[2].XYZ2.Skip());
r += 3;
}
}
void GSState::GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, uint32 size)
{
}
@ -1633,6 +1664,8 @@ template void GSState::Transfer<1>(const uint8* mem, uint32 size);
template void GSState::Transfer<2>(const uint8* mem, uint32 size);
template void GSState::Transfer<3>(const uint8* mem, uint32 size);
static hash_map<uint64, uint64> s_tags;
template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
{
GSPerfMonAutoTimer pmat(&m_perfmon);
@ -1647,6 +1680,15 @@ template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
{
path.SetTag(mem);
if(0)
{
uint64 hash;
if(path.tag.NREG < 8) hash = path.tag.u32[2] & ((1 << path.tag.NREG * 4) - 1);
else if(path.tag.NREG < 16) {hash = path.tag.u32[2]; ((uint32*)&hash)[1] = path.tag.u32[3] & ((1 << (path.tag.NREG - 8) * 4) - 1);}
else hash = path.tag.u64[1];
s_tags[hash] += path.nloop * path.nreg;
}
mem += sizeof(GIFTag);
size--;
@ -1734,6 +1776,14 @@ template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
break;
case GIFPath::TYPE_STQRGBAXYZ2:
(this->*m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZ2])((GIFPackedReg*)mem, total);
mem += total * sizeof(GIFPackedReg);
break;
default:
__assume(0);
@ -2093,6 +2143,8 @@ void GSState::UpdateScissor()
void GSState::UpdateVertexKick()
{
if(m_frameskip) return;
uint32 prim = PRIM->PRIM;
m_fpGIFPackedRegHandlers[GIF_REG_XYZF2] = m_fpGIFPackedRegHandlerXYZ[prim][0];
@ -2106,6 +2158,7 @@ void GSState::UpdateVertexKick()
m_fpGIFRegHandlers[GIF_A_D_REG_XYZ3] = m_fpGIFRegHandlerXYZ[prim][3];
m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZF2] = m_fpGIFPackedRegHandlerSTQRGBAXYZF2[prim];
m_fpGIFPackedRegHandlersC[GIF_REG_STQRGBAXYZ2] = m_fpGIFPackedRegHandlerSTQRGBAXYZ2[prim];
}
void GSState::GrowVertexBuffer()

View File

@ -61,10 +61,12 @@ class GSState : public GSAlignedClass<32>
typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, uint32 size);
GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[1];
GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[2];
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8];
GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8];
template<uint32 prim> void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, uint32 size);
template<uint32 prim> void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, uint32 size);
void GIFPackedRegHandlerNOP(const GIFPackedReg* RESTRICT r, uint32 size);
template<int i> void ApplyTEX0(GIFRegTEX0& TEX0);

View File

@ -225,10 +225,20 @@ void GSVertexTrace::FindMinMax(const void* vertex, const uint32* index, int coun
m_min.t = tmin * s;
m_max.t = tmax * s;
}
else
{
m_min.t = GSVector4::zero();
m_max.t = GSVector4::zero();
}
if(color)
{
m_min.c = cmin.zzzz().u8to32();
m_max.c = cmax.zzzz().u8to32();
}
else
{
m_min.c = GSVector4i::zero();
m_max.c = GSVector4i::zero();
}
}