Fixed-Point alternative implementation for rdtsc replacement
Both slightly faster, and more accurate than the previous implementation Thanks haxar!
This commit is contained in:
parent
d700120994
commit
97222b6de0
|
@ -70,7 +70,6 @@ namespace xboxkrnl {
|
|||
// TODO: Move these to LLE APUDevice once we have one!
|
||||
|
||||
#define APU_TIMER_FREQUENCY 48000
|
||||
extern LARGE_INTEGER NativePerformanceFrequency;
|
||||
LARGE_INTEGER APUInitialPerformanceCounter;
|
||||
double NativeToXboxAPU_FactorForPerformanceFrequency = 0;
|
||||
|
||||
|
@ -78,7 +77,7 @@ void ResetApuTimer()
|
|||
{
|
||||
// Measure current host performance counter and frequency
|
||||
QueryPerformanceCounter(&APUInitialPerformanceCounter);
|
||||
NativeToXboxAPU_FactorForPerformanceFrequency = (double)APU_TIMER_FREQUENCY / NativePerformanceFrequency.QuadPart;
|
||||
NativeToXboxAPU_FactorForPerformanceFrequency = (double)APU_TIMER_FREQUENCY / APUInitialPerformanceCounter.QuadPart;
|
||||
}
|
||||
|
||||
uint32_t GetAPUTime()
|
||||
|
|
|
@ -240,25 +240,40 @@ void InitDpcAndTimerThread()
|
|||
|
||||
// Xbox Performance Counter Frequency = 733333333 (CPU Clock)
|
||||
#define XBOX_PERFORMANCE_FREQUENCY 733333333
|
||||
|
||||
LARGE_INTEGER NativePerformanceCounter = { 0 };
|
||||
LARGE_INTEGER NativePerformanceFrequency = { 0 };
|
||||
double NativeToXbox_FactorForPerformanceFrequency;
|
||||
uint64_t NativeToXbox_FactorForPerformanceFrequency;
|
||||
|
||||
void ConnectKeInterruptTimeToThunkTable(); // forward
|
||||
|
||||
uint64_t CxbxRdTsc(bool xbox) {
|
||||
LARGE_INTEGER tsc;
|
||||
|
||||
QueryPerformanceCounter(&tsc);
|
||||
|
||||
if (xbox && NativeToXbox_FactorForPerformanceFrequency) {
|
||||
LARGE_INTEGER scaledTsc;
|
||||
scaledTsc.QuadPart = 1000000000;
|
||||
scaledTsc.QuadPart *= tsc.QuadPart;
|
||||
scaledTsc.QuadPart /= NativeToXbox_FactorForPerformanceFrequency;
|
||||
return (uint64_t)scaledTsc.QuadPart;
|
||||
}
|
||||
|
||||
return (uint64_t)tsc.QuadPart;
|
||||
}
|
||||
|
||||
uint64_t CxbxCalibrateTsc()
|
||||
{
|
||||
LARGE_INTEGER pf;
|
||||
QueryPerformanceFrequency(&pf);
|
||||
return pf.QuadPart;
|
||||
}
|
||||
|
||||
void CxbxInitPerformanceCounters()
|
||||
{
|
||||
BootTickCount = GetTickCount64();
|
||||
|
||||
// Measure current host performance counter and frequency
|
||||
QueryPerformanceCounter(&NativePerformanceCounter);
|
||||
QueryPerformanceFrequency(&NativePerformanceFrequency);
|
||||
// TODO : If anything like speed-stepping influences this, prevent or fix it here
|
||||
|
||||
// Calculate the host-to-xbox performance frequency factor,
|
||||
// used the return Xbox-like results in KeQueryPerformanceCounter:
|
||||
NativeToXbox_FactorForPerformanceFrequency = (double)XBOX_PERFORMANCE_FREQUENCY / NativePerformanceFrequency.QuadPart;
|
||||
LARGE_INTEGER t;
|
||||
t.QuadPart = 1000000000;
|
||||
t.QuadPart *= CxbxCalibrateTsc();
|
||||
t.QuadPart /= XBOX_PERFORMANCE_FREQUENCY;
|
||||
NativeToXbox_FactorForPerformanceFrequency = t.QuadPart;
|
||||
|
||||
ConnectKeInterruptTimeToThunkTable();
|
||||
|
||||
|
@ -1102,20 +1117,12 @@ XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCo
|
|||
LOG_FUNC();
|
||||
|
||||
ULONGLONG ret;
|
||||
::LARGE_INTEGER PerformanceCounter;
|
||||
|
||||
//no matter rdtsc is patched or not, we should always return a scaled performance counter here.
|
||||
DbgPrintf("host tick count : %lu\n", CxbxRdTsc(false));
|
||||
ret = CxbxRdTsc(true);
|
||||
DbgPrintf("emulated tick count : %lu\n", ret);
|
||||
|
||||
// Dxbx note : Xbox actually uses the RDTSC machine code instruction for this,
|
||||
// and we we're bound to a single core, so we could do that too, but on Windows
|
||||
// rdtsc is not a very stable counter, so instead, we'll use the native PeformanceCounter :
|
||||
QueryPerformanceCounter(&PerformanceCounter);
|
||||
|
||||
// Re-base the performance counter to increase accuracy of the following conversion :
|
||||
PerformanceCounter.QuadPart -= NativePerformanceCounter.QuadPart;
|
||||
// We appy a conversion factor here, to fake Xbox1-like increment-speed behaviour :
|
||||
PerformanceCounter.QuadPart = (ULONGLONG)(NativeToXbox_FactorForPerformanceFrequency * PerformanceCounter.QuadPart);
|
||||
|
||||
ret = PerformanceCounter.QuadPart;
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue