mirror of https://github.com/PCSX2/pcsx2.git
More MTGS improvements and cleanups. I actually changed some of how the MTGS ring buffer is managed this time, so it might introduce some bugs (lets hope not!).
Removed the SPU2timestretch auto-enable/disable code. Also added checks for frameskipping support to the F4 keypress (just in case). git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@344 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
2f08ff5e70
commit
2f23574430
|
@ -133,14 +133,6 @@ void WriteFIFO(u32 mem, u64 *value) {
|
||||||
data[1] = value[1];
|
data[1] = value[1];
|
||||||
GSgifTransferDummy(2, (u32*)data, 1);
|
GSgifTransferDummy(2, (u32*)data, 1);
|
||||||
GSRINGBUF_DONECOPY((u8*)data, 16);
|
GSRINGBUF_DONECOPY((u8*)data, 16);
|
||||||
|
|
||||||
if( !CHECK_DUALCORE ) {
|
|
||||||
#if defined(_WIN32) && !defined(WIN32_PTHREADS)
|
|
||||||
SetEvent(g_hGsEvent);
|
|
||||||
#else
|
|
||||||
pthread_cond_signal(&g_condGsEvent);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FreezeXMMRegs(1);
|
FreezeXMMRegs(1);
|
||||||
|
|
108
pcsx2/GS.cpp
108
pcsx2/GS.cpp
|
@ -253,6 +253,19 @@ static __forceinline void gsSetEventWait()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mem and size are the ones from GSRingBufCopy
|
||||||
|
void GSRINGBUF_DONECOPY(const u8 *mem, u32 size)
|
||||||
|
{
|
||||||
|
u8* temp = (u8*)(mem) + (size);
|
||||||
|
|
||||||
|
assert( temp <= GS_RINGBUFFEREND);
|
||||||
|
|
||||||
|
if( temp == GS_RINGBUFFEREND ) temp = GS_RINGBUFFERBASE;
|
||||||
|
InterlockedExchangePointer((void**)&g_pGSWritePos, temp);
|
||||||
|
if( !CHECK_DUALCORE ) GS_SETEVENT();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void gsShutdown()
|
void gsShutdown()
|
||||||
{
|
{
|
||||||
if( CHECK_MULTIGS ) {
|
if( CHECK_MULTIGS ) {
|
||||||
|
@ -310,80 +323,88 @@ u8* GSRingBufCopy(void* mem, u32 size, u32 type)
|
||||||
// is reading it.
|
// is reading it.
|
||||||
|
|
||||||
u8* writepos = g_pGSWritePos;
|
u8* writepos = g_pGSWritePos;
|
||||||
u8* tempbuf;
|
|
||||||
assert( size < GS_RINGBUFFERSIZE );
|
assert( size < GS_RINGBUFFERSIZE );
|
||||||
assert( writepos < GS_RINGBUFFEREND );
|
assert( writepos < GS_RINGBUFFEREND );
|
||||||
assert( ((uptr)writepos & 15) == 0 );
|
assert( ((uptr)writepos & 15) == 0 );
|
||||||
assert( (size&15) == 0);
|
assert( (size&15) == 0);
|
||||||
|
|
||||||
size += 16;
|
size += 16;
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
if( writepos + size > GS_RINGBUFFEREND )
|
||||||
if( writepos + size > GS_RINGBUFFEREND ) {
|
{
|
||||||
|
// If the incoming packet doesn't fit, then start over from
|
||||||
|
// the start of the ring buffer (it's a lot easier than trying
|
||||||
|
// to wrap the packet around the end of the buffer).
|
||||||
|
|
||||||
// skip to beginning
|
// We have to be careful not to leapfrog our readposition. If it's
|
||||||
while( writepos < tempbuf || tempbuf == GS_RINGBUFFERBASE ) {
|
// greater than the current write position then we need to stall
|
||||||
|
// until it loops around:
|
||||||
|
|
||||||
|
//const u8* readps = *(volatile PU8*)&g_pGSRingPos;
|
||||||
|
while( *(volatile PU8*)&g_pGSRingPos > writepos ) // && readpos == GS_RINGBUFFERBASE )
|
||||||
gsSetEventWait();
|
gsSetEventWait();
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify GS
|
GSRingBufSimplePacket( GS_RINGTYPE_RESTART, 0, 0, 0 );
|
||||||
if( writepos != GS_RINGBUFFEREND ) {
|
|
||||||
InterlockedExchangePointer((void**)writepos, GS_RINGTYPE_RESTART);
|
writepos = GS_RINGBUFFERBASE;
|
||||||
}
|
|
||||||
|
// stall until the read position is past the end of our incoming block:
|
||||||
|
while( writepos+size >= *(volatile PU8*)&g_pGSRingPos )
|
||||||
|
gsSetEventWait();
|
||||||
|
|
||||||
InterlockedExchangePointer((void**)&g_pGSWritePos, GS_RINGBUFFERBASE);
|
InterlockedExchangePointer((void**)&g_pGSWritePos, GS_RINGBUFFERBASE);
|
||||||
writepos = GS_RINGBUFFERBASE;
|
|
||||||
}
|
}
|
||||||
else if( writepos + size == GS_RINGBUFFEREND ) {
|
else if( writepos + size == GS_RINGBUFFEREND )
|
||||||
while(tempbuf == GS_RINGBUFFERBASE && tempbuf != writepos) {
|
{
|
||||||
gsSetEventWait();
|
// Yay. Perfect fit. What are the odds?
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
// ... apparently very slim because the old code just performed the equivalent
|
||||||
}
|
// of a gsWaitGS (stalling the GS until the ring buffer emptied completely) and
|
||||||
}
|
// no one noticed enough to fix it. :)
|
||||||
|
|
||||||
while( writepos < tempbuf && (writepos+size >= tempbuf || (writepos+size == GS_RINGBUFFEREND && tempbuf == GS_RINGBUFFERBASE)) ) {
|
while( writepos < *(volatile PU8*)&g_pGSRingPos )
|
||||||
gsSetEventWait();
|
gsSetEventWait();
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// two conditionals in the following while() loop, so precache
|
||||||
|
// the readpos for more efficient behavior:
|
||||||
|
const u8* readpos = *(volatile PU8*)&g_pGSRingPos;
|
||||||
|
|
||||||
|
// generic gs wait/stall.
|
||||||
|
// Waits until the readpos is outside the scope of the write area.
|
||||||
|
while( writepos < readpos && writepos+size >= readpos ) // || (writepos+size == GS_RINGBUFFEREND && readpos == GS_RINGBUFFERBASE)) ) {
|
||||||
|
{
|
||||||
|
gsSetEventWait();
|
||||||
|
readpos = *(volatile PU8*)&g_pGSRingPos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// just copy
|
// just copy
|
||||||
*(u32*)writepos = type|(((size-16)>>4)<<16);
|
*(u32*)writepos = type | (((size-16)>>4)<<16);
|
||||||
return writepos+16;
|
return writepos+16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRingBufSimplePacket(int type, int data0, int data1, int data2)
|
void GSRingBufSimplePacket(int type, int data0, int data1, int data2)
|
||||||
{
|
{
|
||||||
u8* writepos = g_pGSWritePos;
|
u8* writepos = g_pGSWritePos;
|
||||||
u8* tempbuf;
|
u8* future_writepos = writepos+16;
|
||||||
|
|
||||||
assert( writepos + 16 <= GS_RINGBUFFEREND );
|
assert( future_writepos <= GS_RINGBUFFEREND );
|
||||||
|
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
if( future_writepos == GS_RINGBUFFEREND )
|
||||||
while(writepos < tempbuf && writepos+16 >= tempbuf ) {
|
future_writepos = GS_RINGBUFFERBASE;
|
||||||
|
|
||||||
|
while( future_writepos == *(volatile PU8*)&g_pGSRingPos )
|
||||||
gsSetEventWait();
|
gsSetEventWait();
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(u32*)writepos = type;
|
*(u32*)writepos = type;
|
||||||
*(u32*)(writepos+4) = data0;
|
*(u32*)(writepos+4) = data0;
|
||||||
*(u32*)(writepos+8) = data1;
|
*(u32*)(writepos+8) = data1;
|
||||||
*(u32*)(writepos+12) = data2;
|
*(u32*)(writepos+12) = data2;
|
||||||
|
|
||||||
writepos += 16;
|
InterlockedExchangePointer((void**)&g_pGSWritePos, future_writepos);
|
||||||
if( writepos == GS_RINGBUFFEREND ) {
|
|
||||||
|
|
||||||
while(tempbuf == GS_RINGBUFFERBASE && tempbuf != g_pGSWritePos) {
|
if( !CHECK_DUALCORE )
|
||||||
gsSetEventWait();
|
|
||||||
tempbuf = *(volatile PU8*)&g_pGSRingPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
writepos = GS_RINGBUFFERBASE;
|
|
||||||
}
|
|
||||||
InterlockedExchangePointer((void**)&g_pGSWritePos, writepos);
|
|
||||||
|
|
||||||
if( !CHECK_DUALCORE ) {
|
|
||||||
GS_SETEVENT();
|
GS_SETEVENT();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gsReset()
|
void gsReset()
|
||||||
|
@ -939,8 +960,6 @@ static __forceinline void WRITERING_DMA(u32 *pMem, u32 qwc) {
|
||||||
GSRINGBUF_DONECOPY(pgsmem, sizetoread);
|
GSRINGBUF_DONECOPY(pgsmem, sizetoread);
|
||||||
GSgifTransferDummy(2, pMem, qwc);
|
GSgifTransferDummy(2, pMem, qwc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !CHECK_DUALCORE ) GS_SETEVENT();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GSGIFTRANSFER3(pMem, qwc);
|
GSGIFTRANSFER3(pMem, qwc);
|
||||||
|
@ -1500,7 +1519,8 @@ void* GSThreadProc(void* lpParam)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_RINGTYPE_FRAMESKIP:
|
case GS_RINGTYPE_FRAMESKIP:
|
||||||
GSsetFrameSkip(*(int*)(g_pGSRingPos+4));
|
if( GSsetFrameSkip != NULL )
|
||||||
|
GSsetFrameSkip(*(int*)(g_pGSRingPos+4));
|
||||||
break;
|
break;
|
||||||
case GS_RINGTYPE_MEMWRITE8:
|
case GS_RINGTYPE_MEMWRITE8:
|
||||||
g_MTGSMem[*(int*)(g_pGSRingPos+4)] = *(u8*)(g_pGSRingPos+8);
|
g_MTGSMem[*(int*)(g_pGSRingPos+4)] = *(u8*)(g_pGSRingPos+8);
|
||||||
|
|
11
pcsx2/GS.h
11
pcsx2/GS.h
|
@ -97,15 +97,6 @@ extern u8* g_pGSWritePos;
|
||||||
|
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
// mem and size are the ones from GSRingBufCopy
|
|
||||||
static __forceinline void GSRINGBUF_DONECOPY(const u8 *mem, u32 size) {
|
|
||||||
u8* temp = (u8*)(mem) + (size);
|
|
||||||
assert( temp <= GS_RINGBUFFEREND);
|
|
||||||
// MTGS_RECWRITE(mem, size);
|
|
||||||
if( temp == GS_RINGBUFFEREND ) temp = GS_RINGBUFFERBASE;
|
|
||||||
InterlockedExchangePointer((void**)&g_pGSWritePos, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(WIN32_PTHREADS)
|
#if defined(_WIN32) && !defined(WIN32_PTHREADS)
|
||||||
|
|
||||||
#define GS_SETEVENT() SetEvent(g_hGsEvent)
|
#define GS_SETEVENT() SetEvent(g_hGsEvent)
|
||||||
|
@ -125,6 +116,8 @@ void gsInit();
|
||||||
void gsShutdown();
|
void gsShutdown();
|
||||||
void gsReset();
|
void gsReset();
|
||||||
|
|
||||||
|
// mem and size are the ones from GSRingBufCopy
|
||||||
|
extern void GSRINGBUF_DONECOPY(const u8 *mem, u32 size);
|
||||||
extern void gsWaitGS();
|
extern void gsWaitGS();
|
||||||
|
|
||||||
// used for resetting GIF fifo
|
// used for resetting GIF fifo
|
||||||
|
|
35
pcsx2/Misc.c
35
pcsx2/Misc.c
|
@ -863,7 +863,8 @@ void ProcessFKeys(int fkey, int shift)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
{
|
||||||
|
const char* limitMsg;
|
||||||
#ifdef PCSX2_NORECBUILD
|
#ifdef PCSX2_NORECBUILD
|
||||||
SysPrintf("frame skipping only valid for recompiler build\n");
|
SysPrintf("frame skipping only valid for recompiler build\n");
|
||||||
#else
|
#else
|
||||||
|
@ -882,33 +883,37 @@ void ProcessFKeys(int fkey, int shift)
|
||||||
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 0, 0, 0);
|
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 0, 0, 0);
|
||||||
else GSsetFrameSkip(0);
|
else GSsetFrameSkip(0);
|
||||||
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
||||||
if(SPU2setTimeStretcher != NULL)
|
limitMsg = "None/Normal";
|
||||||
SPU2setTimeStretcher(1);
|
|
||||||
SysPrintf("Normal - Frame Limit Mode Changed\n");
|
|
||||||
break;
|
break;
|
||||||
case PCSX2_FRAMELIMIT_LIMIT:
|
case PCSX2_FRAMELIMIT_LIMIT:
|
||||||
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 0, 0, 0);
|
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 0, 0, 0);
|
||||||
else GSsetFrameSkip(0);
|
else GSsetFrameSkip(0);
|
||||||
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
||||||
//Quality option, turn off timestretching on the SPU2 plugin
|
//Quality option, turn off timestretching on the SPU2 plugin
|
||||||
if(SPU2setTimeStretcher != NULL)
|
limitMsg = "Limit";
|
||||||
SPU2setTimeStretcher(0);
|
|
||||||
SysPrintf("Limit - Frame Limit Mode Changed\n");
|
|
||||||
break;
|
break;
|
||||||
case PCSX2_FRAMELIMIT_SKIP:
|
case PCSX2_FRAMELIMIT_SKIP:
|
||||||
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
Cpu->ExecuteVU1Block = recExecuteVU1Block;
|
||||||
if(SPU2setTimeStretcher != NULL)
|
|
||||||
SPU2setTimeStretcher(1);
|
|
||||||
SysPrintf("Frame Skip - Frame Limit Mode Changed\n");
|
|
||||||
break;
|
|
||||||
case PCSX2_FRAMELIMIT_VUSKIP:
|
case PCSX2_FRAMELIMIT_VUSKIP:
|
||||||
if(SPU2setTimeStretcher != NULL)
|
if( GSsetFrameSkip == NULL )
|
||||||
SPU2setTimeStretcher(1);
|
{
|
||||||
SysPrintf("VU Skip - Frame Limit Mode Changed\n");
|
Config.Options &= ~PCSX2_FRAMELIMIT_MASK;
|
||||||
|
SysPrintf("Notice: GS Plugin does not support frameskipping.\n");
|
||||||
|
limitMsg = "None/Normal";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
limitMsg = (CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_SKIP) ? "Skip" : "VUSkip";
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SysPrintf("Frame Limit Mode Changed: %s\n", limitMsg );
|
||||||
|
|
||||||
// [Air]: Do we really want to save runtime changes to frameskipping?
|
// [Air]: Do we really want to save runtime changes to frameskipping?
|
||||||
//SaveConfig();
|
//SaveConfig();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
// note: VK_F5-VK_F7 are reserved for GS
|
// note: VK_F5-VK_F7 are reserved for GS
|
||||||
|
|
|
@ -1668,11 +1668,10 @@ static int Vif1TransDirectHL(u32 *data){
|
||||||
if( gsmem != NULL ) {
|
if( gsmem != NULL ) {
|
||||||
FreezeMMXRegs(1);
|
FreezeMMXRegs(1);
|
||||||
memcpy_fast(gsmem, (u32*)splittransfer[0], 16);
|
memcpy_fast(gsmem, (u32*)splittransfer[0], 16);
|
||||||
|
FreezeMMXRegs(0);
|
||||||
GSRINGBUF_DONECOPY(gsmem, 16);
|
GSRINGBUF_DONECOPY(gsmem, 16);
|
||||||
GSgifTransferDummy(1, (u32*)splittransfer[0], 1);
|
GSgifTransferDummy(1, (u32*)splittransfer[0], 1);
|
||||||
}
|
}
|
||||||
FreezeMMXRegs(0);
|
|
||||||
if( !CHECK_DUALCORE ) GS_SETEVENT();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FreezeXMMRegs(1);
|
FreezeXMMRegs(1);
|
||||||
|
@ -1718,8 +1717,6 @@ static int Vif1TransDirectHL(u32 *data){
|
||||||
GSRINGBUF_DONECOPY(gsmem, ret<<2);
|
GSRINGBUF_DONECOPY(gsmem, ret<<2);
|
||||||
GSgifTransferDummy(1, data, ret>>2);
|
GSgifTransferDummy(1, data, ret>>2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !CHECK_DUALCORE ) GS_SETEVENT();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
@ -2331,9 +2328,6 @@ void dmaVIF1()
|
||||||
|
|
||||||
GSRINGBUF_DONECOPY(pMem, 0);
|
GSRINGBUF_DONECOPY(pMem, 0);
|
||||||
|
|
||||||
if( !CHECK_DUALCORE )
|
|
||||||
GS_SETEVENT();
|
|
||||||
|
|
||||||
g_MTGSVifStart = cpuRegs.cycle;
|
g_MTGSVifStart = cpuRegs.cycle;
|
||||||
g_MTGSVifCount = 4000000; // a little less than 1/60th of a second
|
g_MTGSVifCount = 4000000; // a little less than 1/60th of a second
|
||||||
|
|
||||||
|
|
|
@ -5633,14 +5633,6 @@ void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
|
||||||
FreezeMMXRegs(0);
|
FreezeMMXRegs(0);
|
||||||
|
|
||||||
GSRINGBUF_DONECOPY(pmem, size);
|
GSRINGBUF_DONECOPY(pmem, size);
|
||||||
|
|
||||||
if( !CHECK_DUALCORE ) {
|
|
||||||
#if defined(_WIN32) && !defined(WIN32_PTHREADS)
|
|
||||||
SetEvent(g_hGsEvent);
|
|
||||||
#else
|
|
||||||
pthread_cond_signal(&g_condGsEvent);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue