#include "EndUserBenchmark.h" #if COLLECT_END_USER_BENCHMARKS #include "time.h" #include "fwsys/timer.h" #include "grcore/diag_d3d.h" #include "grcore\adapter_d3d11.h" #include "script\script.h" #include "script\streamedscripts.h" #include "script\thread.h" #include "camera/CamInterface.h" #include "network/NetworkInterface.h" #if __BANK #include "bank/bank.h" #include "bank/button.h" #include "bank/bkmgr.h" #endif #include "Network/Live/NetworkTelemetry.h" eFRONTEND_MENU_VERSION EndUserBenchmarks::m_bMenuTrigger = 0; bool EndUserBenchmarks::m_bActive = false; bool EndUserBenchmarks::m_bStartedFromCommandline = false; int EndUserBenchmarks::m_StartTestCounter = 0; strLocalIndex EndUserBenchmarks::m_scriptID = strLocalIndex(-1); MetricsCapture::SampledValue EndUserBenchmarks::m_fpsSample; atArray EndUserBenchmarks::m_fpsResults; int EndUserBenchmarks::m_frameTimeSlots[MAX_FRAME_TIME_MS]; float* EndUserBenchmarks::m_pFrameTimesMs = NULL; NOSTRIP_PC_PARAM(benchmark, "Starts the benchmark test from the command line"); NOSTRIP_PC_PARAM(benchmarkFrameTimes, "Optionally output the individual frame times from the benchmark"); NOSTRIP_PC_PARAM(benchmarkIterations, "Specifies the number of iterations to run the benchmark for"); NOSTRIP_PC_PARAM(benchmarkPass, "Specifies an individual benchmark scene test should be done, and which test that should be"); void EndUserBenchmarks::Init(unsigned /*initMode*/) { m_bActive = false; ResetBenchmarks(); #if __BANK InitWidgets(); #endif } void EndUserBenchmarks::Shutdown(unsigned /*shutdownMode*/) { if (m_bActive) { StopBenchmark(); ResetBenchmarks(); Assert(m_pFrameTimesMs == NULL); } m_bActive = false; } bool EndUserBenchmarks::GetWasBenchmarkOnCommandline() { return PARAM_benchmark.Get(); } void EndUserBenchmarks::Update() { #if !__FINAL if(CControlMgr::GetKeyboard().GetKeyJustDown(KEY_S,KEYBOARD_MODE_DEBUG_CNTRL_SHIFT,"Start Benchmark mode")) { if (!m_bActive) { ResetBenchmarks(); StartBenchmark(); } else { StopBenchmark(); OutputBenchmarkResults(); } } else #endif // !__FINAL if( m_bActive ) { if (m_fpsSample.Samples() < MAX_FRAME_TIME_COUNT-1) { // Collect FPS data AccumulateFPSData(); } else { Errorf("Ran out of samples. Dumping benchmark .txt file"); StopBenchmark(); OutputBenchmarkResults(); } } else if( (PARAM_benchmark.Get() && m_bStartedFromCommandline == false) || GetWasStartedFromPauseMenu(FE_MENU_VERSION_LANDING_MENU)) { if( CNetwork::GetGoStraightToMultiplayer() ) { m_bStartedFromCommandline = true; // Set to true for MP game, so if we go back to SP this still won't fire. } else { // We must wait for the script global blocks to be init'd scrValue **globals = scrProgram::GetGlobalsBlocks(); if( globals && *globals && !IsScriptRunning() /* && camInterface::IsFadedIn() */) { // Start it StartBenchmarkScript(); m_bStartedFromCommandline = true; } } } } void EndUserBenchmarks::ResetBenchmarks() { for(int result=0; resulttm_year-100, date->tm_mon+1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec ); // Create the folder ASSET.CreateLeadingPath(filenameAndPath); // Save out our file fiStream *outHandle = ASSET.Create(filenameAndPath,"txt"); if( outHandle != INVALID_HANDLE_VALUE ) { char* tempString; fprintf(outHandle, "Frames Per Second (Higher is better) Min, Max, Avg\r\n"); for(int i=0;i= sampleCountRequiredForPercentile) break; sampleCountUnderPercentile += thisResult.frameTimeSlots[numMs]; } fprintf(outHandle, "%d%%,\t%.2f\n", percentiles[percentileNum], (float)numMs); } fprintf(outHandle, "\n", i); } fprintf(outHandle, "=== SYSTEM ===\n"); DXDiag::DumpDisplayableInfoString(&tempString, true); fprintf(outHandle, "%s",tempString); delete [] tempString; DXGI_ADAPTER_DESC oAdapterDesc; GRCDEVICE.GetAdapterDescription(oAdapterDesc); fprintf(outHandle, "Graphics Card Vendor Id 0x%x with Device ID 0x%x\n\n", oAdapterDesc.VendorId, oAdapterDesc.DeviceId); CSettingsManager::GetInstance().GraphicsConfigSource(tempString); delete [] tempString; // Output the game settings const Settings & CurrentSettings = CSettingsManager::GetInstance().GetSettings(); const CVideoSettings & VideoSettings = CurrentSettings.m_video; fprintf(outHandle, "=== SETTINGS ===\n"); fprintf(outHandle, "Display: %dx%d (%s) @ %dHz VSync %s", VideoSettings.m_ScreenWidth, VideoSettings.m_ScreenHeight, VideoSettings.m_Windowed ? "Windowed" : "FullScreen", VideoSettings.m_RefreshRate, VideoSettings.m_VSync ? "ON" : "OFF"); if (VideoSettings.m_Stereo) fprintf(outHandle, "NVSTEREO"); fprintf(outHandle,"\n"); CurrentSettings.m_graphics.OutputSettings(outHandle); outHandle->Close(); } if (PARAM_benchmarkFrameTimes.Get()) { for(u32 pass=0; passtm_year-100, date->tm_mon+1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec ); fiStream *outHandle = ASSET.Create(filenameAndPath,"txt"); if( outHandle != INVALID_HANDLE_VALUE ) { fpsResult &thisResult = m_fpsResults[pass]; fprintf(outHandle, "Frame\tTime(ms)\n"); for(u32 frameNo=0;frameNoClose(); } } } CNetworkTelemetry::AppendBenchmarkMetrics(m_fpsResults); } s32 EndUserBenchmarks::GetIterationCount() { const char *pParam; if( PARAM_benchmarkIterations.Get(pParam) ) { s32 paramVal = atoi(pParam); return paramVal; } return -1; } s32 EndUserBenchmarks::GetSinglePassInfo() { const char *pParam; if( PARAM_benchmarkPass.Get(pParam) ) { s32 paramVal = atoi(pParam); return paramVal; } return -1; } void EndUserBenchmarks::AccumulateFPSData() { float fSystemTime = fwTimer::GetSystemTimeStep(); m_pFrameTimesMs[m_fpsSample.Samples()] = fSystemTime * 1000.0f; float fps = 1.0f / rage::Max(0.001f, fSystemTime); m_fpsSample.AddSample(fps); int numMs = (int)(fSystemTime * 1000.0f); // To ms numMs = rage::Min(numMs, MAX_FRAME_TIME_MS-1); m_frameTimeSlots[numMs]++; } void EndUserBenchmarks::StartBenchmarkScript() { m_scriptID = g_StreamedScripts.FindSlot("benchmark"); if(Verifyf(m_scriptID != -1, "Graphics benchmarking script does not exist")) { g_StreamedScripts.StreamingRequest(m_scriptID, STRFLAG_PRIORITY_LOAD|STRFLAG_MISSION_REQUIRED); CStreaming::LoadAllRequestedObjects(); if(Verifyf(g_StreamedScripts.HasObjectLoaded(m_scriptID), "Failed to stream in benchmarking script")) { CTheScripts::GtaStartNewThreadOverride("benchmark", NULL, 0, GtaThread::GetDefaultStackSize()); } } } bool EndUserBenchmarks::IsBenchmarkScriptRunning() { if(m_scriptID == -1) { // We must wait for the script global blocks to be init'd scrValue **globals = scrProgram::GetGlobalsBlocks(); if(globals && *globals) { m_scriptID = g_StreamedScripts.FindSlot("benchmark"); } } return IsScriptRunning(); } bool EndUserBenchmarks::IsScriptRunning() { bool bIsRunning = false; if(m_scriptID != -1) { bIsRunning = g_StreamedScripts.GetNumRefs(strLocalIndex(m_scriptID)) > 0; } return bIsRunning; } #if __BANK void EndUserBenchmarks::InitWidgets() { bkBank * pBank = &BANKMGR.CreateBank("End User Benchmarks"); if(pBank) { pBank->AddButton("Reset Benchmarks", ResetBenchmarks); pBank->AddButton("Start Benchmark", StartBenchmark); pBank->AddButton("Stop Benchmark", StopBenchmark); pBank->AddButton("Output Benchmark Results", OutputBenchmarkResults); } } #endif //__BANK #endif //COLLECT_END_USER_BENCHMARKS