use performance counters (#947)

This commit is contained in:
Roman Fomin 2023-03-19 16:13:23 +07:00 committed by GitHub
parent fc24be131c
commit dd192165e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 42 deletions

View File

@ -24,49 +24,63 @@
#include "doomstat.h" #include "doomstat.h"
#include "m_argv.h" #include "m_argv.h"
static int MSToTic(Uint32 time) static uint64_t basecounter = 0;
static uint64_t basefreq = 0;
static int MSToTic(uint32_t time)
{ {
return time * TICRATE / 1000; return time * TICRATE / 1000;
} }
static Uint32 TicToMS(int tic) static uint64_t TicToCounter(int tic)
{ {
return (Uint32)tic * 1000 / TICRATE; return (uint64_t)tic * basefreq / TICRATE;
} }
static Uint32 basetime = 0;
int I_GetTimeMS(void) int I_GetTimeMS(void)
{ {
Uint32 time; uint64_t counter = SDL_GetPerformanceCounter();
time = SDL_GetTicks(); if (basecounter == 0)
basecounter = counter;
if (basetime == 0) return ((counter - basecounter) * 1000ull) / basefreq;
basetime = time; }
return time - basetime; uint64_t I_GetTimeUS(void)
{
uint64_t counter = SDL_GetPerformanceCounter();
if (basecounter == 0)
basecounter = counter;
return ((counter - basecounter) * 1000000ull) / basefreq;
} }
int time_scale = 100; int time_scale = 100;
static Uint32 GetTimeMS_Scaled(void) static uint64_t GetPerfCounter_Scaled(void)
{ {
Uint32 time; uint64_t counter;
if (time_scale == 100) counter = SDL_GetPerformanceCounter() * time_scale / 100;
{
time = SDL_GetTicks();
}
else
{
time = SDL_GetTicks() * time_scale / 100;
}
if (basetime == 0) if (basecounter == 0)
basetime = time; basecounter = counter;
return time - basetime; return counter - basecounter;
}
static uint32_t GetTimeMS_Scaled(void)
{
uint64_t counter;
counter = SDL_GetPerformanceCounter() * time_scale / 100;
if (basecounter == 0)
basecounter = counter;
return ((counter - basecounter) * 1000ull) / basefreq;
} }
int I_GetTime_RealTime(void) int I_GetTime_RealTime(void)
@ -104,19 +118,21 @@ int (*I_GetFracTime)(void) = I_GetFracTime_Scaled;
void I_InitTimer(void) void I_InitTimer(void)
{ {
basefreq = SDL_GetPerformanceFrequency();
I_GetTime = I_GetTime_Scaled; I_GetTime = I_GetTime_Scaled;
I_GetFracTime = I_GetFracTime_Scaled; I_GetFracTime = I_GetFracTime_Scaled;
} }
void I_SetTimeScale(int scale) void I_SetTimeScale(int scale)
{ {
Uint32 time; uint64_t counter;
time = GetTimeMS_Scaled(); counter = GetPerfCounter_Scaled();
time_scale = scale; time_scale = scale;
basetime += (GetTimeMS_Scaled() - time); basecounter += (GetPerfCounter_Scaled() - counter);
} }
void I_SetFastdemoTimer(boolean on) void I_SetFastdemoTimer(boolean on)
@ -130,11 +146,11 @@ void I_SetFastdemoTimer(boolean on)
} }
else if (I_GetTime == I_GetTime_FastDemo) else if (I_GetTime == I_GetTime_FastDemo)
{ {
Uint32 time; uint64_t counter;
time = TicToMS(I_GetTime_FastDemo()); counter = TicToCounter(I_GetTime_FastDemo());
basetime += (GetTimeMS_Scaled() - time); basecounter += (GetPerfCounter_Scaled() - counter);
I_GetTime = I_GetTime_Scaled; I_GetTime = I_GetTime_Scaled;
I_GetFracTime = I_GetFracTime_Scaled; I_GetFracTime = I_GetFracTime_Scaled;

View File

@ -30,7 +30,9 @@ int I_GetTime_RealTime(void); // killough
extern int (*I_GetFracTime)(void); extern int (*I_GetFracTime)(void);
// [FG] Same as I_GetTime, but returns time in milliseconds // [FG] Same as I_GetTime, but returns time in milliseconds
int I_GetTimeMS(); int I_GetTimeMS(void);
uint64_t I_GetTimeUS(void);
void I_SetTimeScale(int scale); void I_SetTimeScale(int scale);

View File

@ -970,21 +970,29 @@ void I_FinishUpdate(void)
if (uncapped) if (uncapped)
{ {
if (fpslimit >= TICRATE) if (fpslimit >= TICRATE)
{ {
static uint64_t last_frame; uint64_t target_time = 1000000ull / fpslimit;
uint64_t current_frame; static uint64_t start_time;
current_frame = (I_GetTimeMS() * fpslimit) / 1000; while (1)
{
uint64_t current_time = I_GetTimeUS();
uint64_t elapsed_time = current_time - start_time;
uint64_t remaining_time = 0;
while (current_frame == last_frame) if (elapsed_time >= target_time)
{ {
I_Sleep(1); start_time = current_time;
current_frame = (I_GetTimeMS() * fpslimit) / 1000; break;
} }
last_frame = current_frame; remaining_time = target_time - elapsed_time;
}
if (remaining_time > 1000)
I_Sleep((remaining_time - 1000) / 1000);
}
}
// [AM] Figure out how far into the current tic we're in as a fixed_t. // [AM] Figure out how far into the current tic we're in as a fixed_t.
fractionaltic = I_GetFracTime(); fractionaltic = I_GetFracTime();