Fix Frame time calculation to properly handle CPU/GPU parallelism

This commit is contained in:
Stephen Saunders 2021-09-27 17:56:45 -04:00
parent 3d7cfe7351
commit 09e0a4c5c8
2 changed files with 8 additions and 7 deletions

View file

@ -290,14 +290,15 @@ float idConsoleLocal::DrawFPS( float y )
const uint64 rendererGPUInteractionsTime = commonLocal.GetRendererGpuInteractionsMicroseconds();
const uint64 rendererGPUShaderPassesTime = commonLocal.GetRendererGpuShaderPassMicroseconds();
const uint64 rendererGPUPostProcessingTime = commonLocal.GetRendererGpuPostProcessingMicroseconds();
const int maxTime = 1000 / com_engineHz_latched * 1000;
const int maxTime = int( 1000 / com_engineHz_latched ) * 1000;
// SRS - Calculate time waiting for GPU to sync at the start of a frame (com_smp = 1 or 0) and at the end of a frame (com_smp = -1)
const uint64 rendererSyncTime_StartFrame = commonLocal.mainFrameTiming.finishSyncTime - commonLocal.mainFrameTiming.startSyncTime;
const uint64 rendererSyncTime_EndFrame = commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.startRenderTime;
// SRS - Total CPU and Frame time calculations depend on whether game is operating in smp mode or not
const uint64 totalCPUTime = ( com_smp.GetInteger() > 0 && com_editors == 0 ? std::max( gameThreadTotalTime, rendererBackEndTime ) : gameThreadTotalTime + rendererBackEndTime );
// SRS - Calculate rendererSyncTime depending on smp mode and use to determine whether a frame loss has occurred
const uint64 rendererSyncTime = ( com_smp.GetInteger() >= 0 ? commonLocal.mainFrameTiming.finishSyncTime - commonLocal.mainFrameTiming.startSyncTime : commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.finishRenderTime );
const uint64 frameLossTime = ( rendererSyncTime < maxTime || rendererGPUTime > maxTime ? 0 : maxTime );
const uint64 totalFrameTime = totalCPUTime + rendererGPUTime + frameLossTime;
const uint64 totalFrameTime = ( com_smp.GetInteger() > 0 && com_editors == 0 ? std::max( gameThreadTotalTime, rendererSyncTime_EndFrame ) : gameThreadTotalTime + rendererSyncTime_EndFrame ) + rendererSyncTime_StartFrame;
#if 1

View file

@ -897,9 +897,9 @@ void idCommonLocal::Frame()
{
// RB: this is the same as Doom 3 renderSystem->EndFrame()
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu, &stats_backend, &stats_frontend );
// SRS - Use finishSyncTime_EndFrame to record timing after sync for com_smp = -1, used in idConsoleLocal::DrawFPS() for calculating rendererSyncTime
frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
}
// SRS - Use finishSyncTime_EndFrame to record timing after sync for com_smp = -1, and just before gameThread.WaitForThread() for com_smp = 1
frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
// make sure the game / draw thread has completed
// This may block if the game is taking longer than the render back end