HUD Statistics Overlay: Improve frame sync time and CPU usage % calculations (all platforms)

This commit is contained in:
Stephen Saunders 2024-01-25 15:09:54 -05:00
parent 6bea484765
commit fea41b50ba
4 changed files with 17 additions and 13 deletions

View file

@ -315,6 +315,7 @@ void idCommonLocal::TimeRenderDemo( const char* demoName, bool twice, bool quit
while( readDemo )
{
BusyWait(); // SRS - BusyWait() calls UpdateScreen() which draws and renders out-of-sequence but still supports frame timing
commonLocal.frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
commonLocal.mainFrameTiming = commonLocal.frameTiming;
// ** End of current logical frame **

View file

@ -298,7 +298,6 @@ float idConsoleLocal::DrawFPS( float y )
const uint64 rendererBackEndTime = commonLocal.GetRendererBackEndMicroseconds();
const uint64 rendererShadowsTime = commonLocal.GetRendererShadowsMicroseconds();
const uint64 rendererMvkEncodeTime = commonLocal.GetRendererMvkEncodeMicroseconds();
const uint64 rendererGPUTime = commonLocal.GetRendererGPUMicroseconds();
const uint64 rendererGPUEarlyZTime = commonLocal.GetRendererGpuEarlyZMicroseconds();
const uint64 rendererGPU_SSAOTime = commonLocal.GetRendererGpuSSAOMicroseconds();
@ -318,14 +317,24 @@ float idConsoleLocal::DrawFPS( float y )
const int64 frameIdleTime = int64( commonLocal.mainFrameTiming.startGameTime ) - int64( commonLocal.mainFrameTiming.finishSyncTime );
const int64 frameBusyTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startGameTime );
// SRS - Frame sync time represents swap buffer synchronization + game thread wait + other time spent outside of rendering
const int64 frameSyncTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startRenderTime ) - int64( rendererBackEndTime );
// SRS - Frame sync time represents swap buffer synchronization + other frame time spent outside of game thread and renderer backend
const int64 gameThreadWaitTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame ) - int64( commonLocal.mainFrameTiming.finishRenderTime );
const int64 frameSyncTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startRenderTime + rendererBackEndTime ) - gameThreadWaitTime;
// SRS - GPU idle time is simply the difference between measured frame-over-frame time and GPU busy time (directly from GPU timers)
const int64 rendererGPUIdleTime = frameBusyTime + frameIdleTime - rendererGPUTime;
// SRS - Estimate CPU busy time measured from start of game thread until completion of game thread and renderer backend (including excess MoltenVK encoding time if applicable)
#if defined(__APPLE__) && defined( USE_MoltenVK )
const int64 rendererMvkEncodeTime = commonLocal.GetRendererMvkEncodeMicroseconds();
const int64 rendererQueueSubmitTime = int64( commonLocal.mainFrameTiming.finishRenderTime - commonLocal.mainFrameTiming.startRenderTime ) - int64( rendererBackEndTime );
const int64 rendererCPUBusyTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.startGameTime ) + Min( Max( int64( 0 ), rendererMvkEncodeTime - rendererQueueSubmitTime - gameThreadWaitTime ), frameSyncTime - rendererQueueSubmitTime );
#else
const int64 rendererCPUBusyTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.startGameTime );
#endif
// SRS - Save current CPU and GPU usage factors in ring buffer to calculate smoothed averages for future frames
previousCpuUsage[(index - 1) % FPS_FRAMES] = float( frameBusyTime - frameSyncTime ) / float( frameBusyTime + frameIdleTime ) * 100.0;
previousCpuUsage[(index - 1) % FPS_FRAMES] = float( rendererCPUBusyTime ) / float( frameBusyTime + frameIdleTime ) * 100.0;
previousGpuUsage[(index - 1) % FPS_FRAMES] = float( rendererGPUTime ) / float( rendererGPUTime + rendererGPUIdleTime ) * 100.0;
#if 1

View file

@ -880,13 +880,13 @@ void idCommonLocal::Frame()
}
frameTiming.finishRenderTime = Sys_Microseconds();
// SRS - Use finishSyncTime_EndFrame to record timing 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
gameThread.WaitForThread();
// SRS - Use finishSyncTime_EndFrame to record timing just after gameThread.WaitForThread()
frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
// Send local usermds to the server.
// This happens after the game frame has run so that prediction data is up to date.
SendUsercmds( Game()->GetLocalClientNum() );

View file

@ -1020,12 +1020,6 @@ bool DeviceManager_VK::createDevice()
m_RendererString = std::string( prop.deviceName.data() );
m_DeviceApiVersion = prop.apiVersion;
// SRS - Determine maxPushConstantSize for Vulkan device
if( r_useVulkanPushConstants.GetBool() )
{
m_DeviceParams.maxPushConstantSize = Min( prop.limits.maxPushConstantsSize, nvrhi::c_MaxPushConstantSize );
}
#if defined( USE_AMD_ALLOCATOR )
// SRS - initialize the vma allocator
VmaVulkanFunctions vulkanFunctions = {};