mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X:
* Fixed crash problems when using SPU2-X with old versions of Pcsx2 (0.9.4 and prior). * Fixed broken Device specification override (the device GUID wasn't being loaded from the INI). Pcsx2: * Added ThreadAffinity stuff to the CPUSpeed detection. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1368 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
b9cb1d3a59
commit
136716a4f5
|
@ -180,20 +180,54 @@ static char* bool_to_char( bool testcond )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDOWS_
|
||||||
|
static HANDLE s_threadId = NULL;
|
||||||
|
static DWORD s_oldmask = ERROR_INVALID_PARAMETER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void SetSingleAffinity()
|
||||||
|
{
|
||||||
|
#ifdef _WINDOWS_
|
||||||
|
// Assign a single CPU thread affinity to ensure rdtsc() accuracy.
|
||||||
|
// (rdtsc for each CPU/core can differ, causing skewed results)
|
||||||
|
|
||||||
|
DWORD_PTR availProcCpus, availSysCpus;
|
||||||
|
if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for( i=0; i<32; ++i )
|
||||||
|
{
|
||||||
|
if( availProcCpus & (1<<i) ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE s_threadId = GetCurrentThread();
|
||||||
|
DWORD s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
|
||||||
|
|
||||||
|
if( s_oldmask == ERROR_INVALID_PARAMETER )
|
||||||
|
{
|
||||||
|
Console::Notice(
|
||||||
|
"CpuDetect: SetThreadAffinityMask failed...\n"
|
||||||
|
"\tSystem Affinity : 0x%08x"
|
||||||
|
"\tProcess Affinity: 0x%08x"
|
||||||
|
"\tAttempted Thread Affinity CPU: i",
|
||||||
|
params availProcCpus, availSysCpus, i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
s64 CPUSpeedHz( u64 time )
|
s64 CPUSpeedHz( u64 time )
|
||||||
{
|
{
|
||||||
u64 timeStart,
|
u64 timeStart, timeStop;
|
||||||
timeStop;
|
s64 startTick, endTick;
|
||||||
s64 startTick,
|
|
||||||
endTick;
|
if( ! cpucaps.hasTimeStampCounter )
|
||||||
|
return 0; //check if function is supported
|
||||||
|
|
||||||
|
SetSingleAffinity();
|
||||||
|
|
||||||
if( ! cpucaps.hasTimeStampCounter )
|
|
||||||
{
|
|
||||||
return 0; //check if function is supported
|
|
||||||
}
|
|
||||||
|
|
||||||
// Align the cpu execution to a cpuTick boundary.
|
// Align the cpu execution to a cpuTick boundary.
|
||||||
|
|
||||||
do { timeStart = GetCPUTicks();
|
do { timeStart = GetCPUTicks();
|
||||||
|
@ -213,6 +247,11 @@ s64 CPUSpeedHz( u64 time )
|
||||||
}
|
}
|
||||||
while( ( timeStop - timeStart ) < time );
|
while( ( timeStop - timeStart ) < time );
|
||||||
|
|
||||||
|
#ifdef _WINDOWS_
|
||||||
|
if( s_oldmask != ERROR_INVALID_PARAMETER )
|
||||||
|
SetThreadAffinityMask( s_threadId, s_oldmask );
|
||||||
|
#endif
|
||||||
|
|
||||||
return (s64)( endTick - startTick );
|
return (s64)( endTick - startTick );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,8 +307,7 @@ EXPORT_C_(void) SPU2shutdown()
|
||||||
|
|
||||||
EXPORT_C_(void) SPU2setClockPtr(u32 *ptr)
|
EXPORT_C_(void) SPU2setClockPtr(u32 *ptr)
|
||||||
{
|
{
|
||||||
cPtr=ptr;
|
cyclePtr = ptr;
|
||||||
hasPtr=(cPtr!=NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool numpad_plus = false, numpad_plus_old = false;
|
bool numpad_plus = false, numpad_plus_old = false;
|
||||||
|
@ -341,14 +340,14 @@ EXPORT_C_(void) SPU2async(u32 cycles)
|
||||||
numpad_plus_old = numpad_plus;*/
|
numpad_plus_old = numpad_plus;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasPtr)
|
if(cyclePtr != NULL)
|
||||||
{
|
{
|
||||||
TimeUpdate(*cPtr);
|
TimeUpdate( *cyclePtr );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pClocks+=cycles;
|
pClocks += cycles;
|
||||||
TimeUpdate(pClocks);
|
TimeUpdate( pClocks );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +372,7 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TimeUpdate( *cPtr );
|
TimeUpdate( *cyclePtr );
|
||||||
|
|
||||||
if (rmem>>16 == 0x1f80)
|
if (rmem>>16 == 0x1f80)
|
||||||
{
|
{
|
||||||
|
@ -430,7 +429,9 @@ EXPORT_C_(void) SPU2write(u32 rmem, u16 value)
|
||||||
// If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather
|
// If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather
|
||||||
// incorrect pitches and loop lengths.
|
// incorrect pitches and loop lengths.
|
||||||
|
|
||||||
TimeUpdate( *cPtr );
|
if( cyclePtr != NULL )
|
||||||
|
TimeUpdate( *cyclePtr );
|
||||||
|
|
||||||
if (rmem>>16 == 0x1f80)
|
if (rmem>>16 == 0x1f80)
|
||||||
SPU_ps1_write(rmem,value);
|
SPU_ps1_write(rmem,value);
|
||||||
else
|
else
|
||||||
|
|
|
@ -313,7 +313,7 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
|
||||||
|
|
||||||
void SPU2readDMA(int core, u16* pMem, u32 size)
|
void SPU2readDMA(int core, u16* pMem, u32 size)
|
||||||
{
|
{
|
||||||
if(hasPtr) TimeUpdate(*cPtr);
|
if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
|
||||||
|
|
||||||
Cores[core].TSA &= 0xffff8;
|
Cores[core].TSA &= 0xffff8;
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ void SPU2readDMA(int core, u16* pMem, u32 size)
|
||||||
|
|
||||||
void SPU2writeDMA(int core, u16* pMem, u32 size)
|
void SPU2writeDMA(int core, u16* pMem, u32 size)
|
||||||
{
|
{
|
||||||
if(hasPtr) TimeUpdate(*cPtr);
|
if(cyclePtr != NULL) TimeUpdate(*cyclePtr);
|
||||||
|
|
||||||
Cores[core].DMAPtr=pMem;
|
Cores[core].DMAPtr=pMem;
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,8 @@ s16 OutPos;
|
||||||
s16 InputPos;
|
s16 InputPos;
|
||||||
u32 Cycles;
|
u32 Cycles;
|
||||||
|
|
||||||
u32* cPtr=NULL;
|
u32* cyclePtr = NULL;
|
||||||
u32 lClocks=0;
|
u32 lClocks = 0;
|
||||||
|
|
||||||
bool hasPtr=false;
|
|
||||||
|
|
||||||
int PlayMode;
|
int PlayMode;
|
||||||
|
|
||||||
|
@ -932,10 +930,13 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
|
||||||
|
|
||||||
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
|
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
|
||||||
{
|
{
|
||||||
if(hasPtr)
|
// When we have exact cycle update info from the Pcsx2 IOP unit, then use
|
||||||
|
// the more accurate delayed initialization system.
|
||||||
|
|
||||||
|
if(cyclePtr != NULL)
|
||||||
{
|
{
|
||||||
thiscore.InitDelay=1;
|
thiscore.InitDelay = 1;
|
||||||
thiscore.Regs.STATX=0;
|
thiscore.Regs.STATX = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,13 +174,12 @@ extern int PlayMode;
|
||||||
extern int recording;
|
extern int recording;
|
||||||
|
|
||||||
extern u32 lClocks;
|
extern u32 lClocks;
|
||||||
extern u32* cPtr;
|
extern u32* cyclePtr;
|
||||||
extern bool hasPtr;
|
|
||||||
|
|
||||||
extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
|
extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
|
||||||
|
|
||||||
extern void TimeUpdate(u32 cClocks);
|
extern void TimeUpdate(u32 cClocks);
|
||||||
extern u16 SPU_ps1_read(u32 mem);
|
extern u16 SPU_ps1_read(u32 mem);
|
||||||
extern void SPU_ps1_write(u32 mem, u16 value);
|
extern void SPU_ps1_write(u32 mem, u16 value);
|
||||||
extern void SPU2_FastWrite( u32 rmem, u16 value );
|
extern void SPU2_FastWrite( u32 rmem, u16 value );
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default)
|
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default)
|
||||||
{
|
{
|
||||||
wchar_t workspace[512];
|
wchar_t workspace[512];
|
||||||
GetPrivateProfileString(Section,Name,L"",workspace,DataSize,CfgFile);
|
GetPrivateProfileString(Section,Name,L"",workspace,DataSize,CfgFile);
|
||||||
|
|
|
@ -69,7 +69,7 @@ void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value);
|
||||||
void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data);
|
void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data);
|
||||||
|
|
||||||
bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default);
|
bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default);
|
||||||
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default);
|
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default);
|
||||||
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default);
|
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default);
|
||||||
int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);
|
int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);
|
||||||
|
|
||||||
|
|
|
@ -194,10 +194,6 @@ public:
|
||||||
|
|
||||||
for(uint i=0;i<m_NumBuffers;i++)
|
for(uint i=0;i<m_NumBuffers;i++)
|
||||||
{
|
{
|
||||||
// [Air] note: wfx.nBlockAlign modifier was *10 -- seems excessive to me but maybe
|
|
||||||
// it was needed for some quirky driver? Theoretically we want the notification as soon
|
|
||||||
// as possible after the buffer has finished playing.
|
|
||||||
|
|
||||||
buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
|
buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
|
||||||
not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
|
not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
|
||||||
not[i].hEventNotify = buffer_events[i];
|
not[i].hEventNotify = buffer_events[i];
|
||||||
|
|
Loading…
Reference in New Issue