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
|
||||
|
||||
#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 )
|
||||
{
|
||||
u64 timeStart,
|
||||
timeStop;
|
||||
s64 startTick,
|
||||
endTick;
|
||||
u64 timeStart, timeStop;
|
||||
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.
|
||||
|
||||
do { timeStart = GetCPUTicks();
|
||||
|
@ -213,6 +247,11 @@ s64 CPUSpeedHz( u64 time )
|
|||
}
|
||||
while( ( timeStop - timeStart ) < time );
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
if( s_oldmask != ERROR_INVALID_PARAMETER )
|
||||
SetThreadAffinityMask( s_threadId, s_oldmask );
|
||||
#endif
|
||||
|
||||
return (s64)( endTick - startTick );
|
||||
}
|
||||
|
||||
|
|
|
@ -307,8 +307,7 @@ EXPORT_C_(void) SPU2shutdown()
|
|||
|
||||
EXPORT_C_(void) SPU2setClockPtr(u32 *ptr)
|
||||
{
|
||||
cPtr=ptr;
|
||||
hasPtr=(cPtr!=NULL);
|
||||
cyclePtr = ptr;
|
||||
}
|
||||
|
||||
bool numpad_plus = false, numpad_plus_old = false;
|
||||
|
@ -341,14 +340,14 @@ EXPORT_C_(void) SPU2async(u32 cycles)
|
|||
numpad_plus_old = numpad_plus;*/
|
||||
}
|
||||
|
||||
if(hasPtr)
|
||||
if(cyclePtr != NULL)
|
||||
{
|
||||
TimeUpdate(*cPtr);
|
||||
TimeUpdate( *cyclePtr );
|
||||
}
|
||||
else
|
||||
{
|
||||
pClocks+=cycles;
|
||||
TimeUpdate(pClocks);
|
||||
pClocks += cycles;
|
||||
TimeUpdate( pClocks );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,7 +372,7 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
|
|||
}
|
||||
else
|
||||
{
|
||||
TimeUpdate( *cPtr );
|
||||
TimeUpdate( *cyclePtr );
|
||||
|
||||
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
|
||||
// incorrect pitches and loop lengths.
|
||||
|
||||
TimeUpdate( *cPtr );
|
||||
if( cyclePtr != NULL )
|
||||
TimeUpdate( *cyclePtr );
|
||||
|
||||
if (rmem>>16 == 0x1f80)
|
||||
SPU_ps1_write(rmem,value);
|
||||
else
|
||||
|
|
|
@ -313,7 +313,7 @@ void DoDMAWrite(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;
|
||||
|
||||
|
@ -394,7 +394,7 @@ void SPU2readDMA(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;
|
||||
|
||||
|
|
|
@ -53,10 +53,8 @@ s16 OutPos;
|
|||
s16 InputPos;
|
||||
u32 Cycles;
|
||||
|
||||
u32* cPtr=NULL;
|
||||
u32 lClocks=0;
|
||||
|
||||
bool hasPtr=false;
|
||||
u32* cyclePtr = NULL;
|
||||
u32 lClocks = 0;
|
||||
|
||||
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(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.Regs.STATX=0;
|
||||
thiscore.InitDelay = 1;
|
||||
thiscore.Regs.STATX = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -174,13 +174,12 @@ extern int PlayMode;
|
|||
extern int recording;
|
||||
|
||||
extern u32 lClocks;
|
||||
extern u32* cPtr;
|
||||
extern bool hasPtr;
|
||||
extern u32* cyclePtr;
|
||||
|
||||
extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
|
||||
|
||||
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 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];
|
||||
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);
|
||||
|
||||
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);
|
||||
int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);
|
||||
|
||||
|
|
|
@ -194,10 +194,6 @@ public:
|
|||
|
||||
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);
|
||||
not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
|
||||
not[i].hEventNotify = buffer_events[i];
|
||||
|
|
Loading…
Reference in New Issue