mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
164 lines
4.8 KiB
C++
164 lines
4.8 KiB
C++
// emulator is profiled every real-time second.
|
|
// status bar should present and contain at least two sections :
|
|
// first (largest) is used for frame timing percentage
|
|
// second (small) is used for FPS
|
|
#include "pch.h"
|
|
|
|
//
|
|
// local data
|
|
//
|
|
|
|
static BOOL Profiler; // uservar
|
|
|
|
static int64_t startTime, stopTime;
|
|
static int64_t gfxStartTime, gfxStopTime;
|
|
static int64_t sfxStartTime, sfxStopTime;
|
|
static int64_t dvdStartTime, dvdStopTime;
|
|
static int64_t cpuTime, gfxTime, sfxTime, dvdTime;
|
|
static int64_t ONE_SECOND;
|
|
static DWORD checkTime;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// precede timer utility
|
|
|
|
static void __fastcall MyReadTimeStampCounter(int64_t *ptr)
|
|
{
|
|
*ptr = __rdtsc();
|
|
}
|
|
|
|
// get average CPU speed (in MHz)
|
|
static float GetClockSpeed()
|
|
{
|
|
int i = 0;
|
|
LARGE_INTEGER t0, t1, perfFreq;
|
|
int64_t stamp0 = 0, stamp1 = 0;
|
|
int64_t diffStamp, diffTicks;
|
|
|
|
if(QueryPerformanceFrequency(&perfFreq))
|
|
{
|
|
while(i < 3)
|
|
{
|
|
i++;
|
|
|
|
QueryPerformanceCounter(&t0);
|
|
t1.LowPart = t0.LowPart;
|
|
t1.HighPart = t0.HighPart;
|
|
|
|
while((t1.LowPart - t0.LowPart) < 50)
|
|
{
|
|
QueryPerformanceCounter(&t1);
|
|
MyReadTimeStampCounter(&stamp0);
|
|
}
|
|
|
|
t0.LowPart = t1.LowPart;
|
|
t0.HighPart = t1.HighPart;
|
|
|
|
while((t1.LowPart - t0.LowPart) < 1000)
|
|
{
|
|
QueryPerformanceCounter(&t1);
|
|
MyReadTimeStampCounter(&stamp1);
|
|
}
|
|
}
|
|
|
|
diffStamp = stamp1 - stamp0;
|
|
diffTicks = t1.LowPart - t0.LowPart;
|
|
diffTicks *= 100000;
|
|
diffTicks = diffTicks / (perfFreq.LowPart / 10);
|
|
|
|
return (float)((float)diffStamp / (float)diffTicks);
|
|
}
|
|
else return 0.0f;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void OpenProfiler(bool enable)
|
|
{
|
|
// load user variable
|
|
Profiler = enable;
|
|
|
|
// status window should be valid
|
|
if(!IsWindow(wnd.hStatusWindow)) Profiler = FALSE;
|
|
|
|
// high-precision timer should exist
|
|
LARGE_INTEGER freq;
|
|
if(!QueryPerformanceFrequency(&freq)) Profiler = FALSE;
|
|
|
|
// reset counters
|
|
if(Profiler)
|
|
{
|
|
cpuTime = gfxTime = sfxTime = dvdTime = 0;
|
|
ONE_SECOND = (int64_t)((double)GetClockSpeed() * (double)1000000.0);
|
|
MyReadTimeStampCounter(&startTime);
|
|
}
|
|
|
|
checkTime = GetTickCount();
|
|
}
|
|
|
|
// update after every fifo call
|
|
void UpdateProfiler()
|
|
{
|
|
TCHAR gcTime[256];
|
|
|
|
if(Profiler)
|
|
{
|
|
TCHAR buf[128], mips[128];
|
|
|
|
if((GetTickCount() - checkTime) < 1000) return;
|
|
checkTime = GetTickCount();
|
|
|
|
// measure time
|
|
MyReadTimeStampCounter(&stopTime);
|
|
int64_t total = stopTime - startTime;
|
|
|
|
cpuTime = total - gfxTime - sfxTime - dvdTime;
|
|
int64_t cur; MyReadTimeStampCounter(&cur);
|
|
int64_t diff = cur - startTime;
|
|
|
|
// frames per second
|
|
_stprintf_s(buf, _countof(buf) - 1, _T("FPS:%zi"), vi.frames);
|
|
vi.frames = 0;
|
|
SetStatusText(STATUS_ENUM::Fps, buf);
|
|
|
|
// MIPS
|
|
_stprintf_s (mips, _countof(mips) - 1, _T("%.1f"), (float)Gekko::Gekko->GetOpcodeCount() / 1000000.0f);
|
|
Gekko::Gekko->ResetOpcodeCount();
|
|
|
|
// update status bar
|
|
{
|
|
_stprintf_s (buf, _countof(buf) - 1, _T("mips:%s core:%-2.1f video:%-2.1f sound:%-2.1f dvd:%-2.1f"),
|
|
mips,
|
|
(double)cpuTime * 100 / (double)total,
|
|
(double)gfxTime * 100 / (double)total,
|
|
(double)sfxTime * 100 / (double)total,
|
|
(double)dvdTime * 100 / (double)total
|
|
);
|
|
SetStatusText(STATUS_ENUM::Progress, buf);
|
|
}
|
|
|
|
// reset counters
|
|
cpuTime = gfxTime = sfxTime = dvdTime = 0;
|
|
MyReadTimeStampCounter(&startTime);
|
|
|
|
// show system time
|
|
HLE::OSTimeFormat(gcTime, Gekko::Gekko->GetTicks(), false);
|
|
SetStatusText(STATUS_ENUM::Time, gcTime);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// profilers set
|
|
|
|
void BeginProfileGfx() { if(Profiler) MyReadTimeStampCounter(&gfxStartTime); }
|
|
void EndProfileGfx() { if(Profiler) { MyReadTimeStampCounter(&gfxStopTime);
|
|
gfxTime += gfxStopTime - gfxStartTime; } }
|
|
|
|
void BeginProfileSfx() { if(Profiler) MyReadTimeStampCounter(&sfxStartTime); }
|
|
void EndProfileSfx() { if(Profiler) { MyReadTimeStampCounter(&sfxStopTime);
|
|
sfxTime += sfxStopTime - sfxStartTime; } }
|
|
|
|
void BeginProfileDVD() { if(Profiler) MyReadTimeStampCounter(&dvdStartTime); }
|
|
void EndProfileDVD() { if(Profiler) { MyReadTimeStampCounter(&dvdStopTime);
|
|
dvdTime += dvdStopTime - dvdStartTime; } }
|