Files
ARMSX2/pcsx2/PerformanceMetrics.h
T
Brian Degenhardt 1edbeb1fbb gsrunner: per-frame stats JSON, percentiles, and a generic -set override
gsrunner's textual output was run-aggregate only: totals for the whole run plus
min/avg/max frame time. A single spiky frame was invisible, and nothing was
machine-readable. The -perf block is also useless on short runs, because
PerformanceMetrics only updates about once a second -- an 8-frame replay reports
nan/inf for every field.

-stats-json <path> writes a per-frame series plus a run summary. Counters are
exact per-frame deltas (update_stat now returns the delta it accumulates, so the
series and the totals stay derived from one source), and frame_ms is measured
directly rather than taken from PerformanceMetrics' window averages. Adds
PerformanceMetrics::GetLastGPUTime for the same reason: OnGPUPresent already
receives a per-frame GPU time but only accumulated it, and an averaged value
hides the spike we are looking for.

Percentiles (p50/p95/p99) and the worst-frame index are reported over drawn
frames only; idle frames are present-only and would drag the distribution down.

-set <Section/Key>=<value> overrides any setting generically. Every experiment
previously needed a bespoke flag -- -accblend, -no-fb-fetch, -no-tex-barriers,
-no-vs-expand, -backthread -- which is a flag per question and makes a sweep
driver impossible. Verified equivalent: -accblend 3 and
-set EmuCore/GS/accurate_blending_unit=3 produce identical counters, and the
override demonstrably bites (accblend 0 -> 4 barriers, accblend 5 -> 365).

Also prints the previously-accumulated-but-never-printed PS2-level draw count,
adds prim accounting, and surfaces the new texture-cache hit/miss counters.
2026-07-22 21:16:45 -07:00

73 lines
2.0 KiB
C++

// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include <array>
#include "common/Threading.h"
namespace PerformanceMetrics
{
enum class InternalFPSMethod
{
None,
GSPrivilegedRegister,
DISPFBBlit
};
static constexpr u32 NUM_FRAME_TIME_SAMPLES = 150;
using FrameTimeHistory = std::array<float, NUM_FRAME_TIME_SAMPLES>;
void Clear();
void Reset();
void Update(bool gs_register_write, bool fb_blit, bool is_skipping_present);
void OnGPUPresent(float gpu_time, u64 vs_invocations, u64 ps_invocations);
/// Logs the whole-session average framerate (frames since Clear() over
/// wall time). Called at VM shutdown so every -logfile run records it.
void LogSessionSummary();
/// Sets the EE thread for CPU usage calculations.
void SetCPUThread(Threading::ThreadHandle thread);
/// Sets timers for GS software threads.
void SetGSSWThreadCount(u32 count);
void SetGSSWThread(u32 index, Threading::ThreadHandle thread);
u64 GetFrameNumber();
InternalFPSMethod GetInternalFPSMethod();
bool IsInternalFPSValid();
float GetFPS();
float GetInternalFPS();
float GetSpeed();
float GetAverageFrameTime();
float GetMinimumFrameTime();
float GetMaximumFrameTime();
double GetCPUThreadUsage();
double GetCPUThreadAverageTime();
float GetGSThreadUsage();
float GetGSThreadAverageTime();
float GetVUThreadUsage();
float GetVUThreadAverageTime();
float GetCaptureThreadUsage();
float GetCaptureThreadAverageTime();
u32 GetGSSWThreadCount();
double GetGSSWThreadUsage(u32 index);
double GetGSSWThreadAverageTime(u32 index);
float GetGPUUsage();
float GetGPUAverageTime();
/// GPU time for the most recent present only, not a window average. Used by the
/// per-frame stats series, where an averaged value would hide the spike.
float GetLastGPUTime();
double GetGPUAverageVSInvocations();
double GetGPUAveragePSInvocations();
const FrameTimeHistory& GetFrameTimeHistory();
u32 GetFrameTimeHistoryPos();
} // namespace PerformanceMetrics