mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
9b8c753ead
commit
20cd5e9b81
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
/*
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue