mirror of https://github.com/PCSX2/pcsx2.git
ImGuiOverlays: Add frame time graph
This commit is contained in:
parent
bb7ab5690c
commit
4bf6b1df5e
|
@ -144,6 +144,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowIndicators, "EmuCore/GS", "OsdShowIndicators", true);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowIndicators, "EmuCore/GS", "OsdShowIndicators", true);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowSettings, "EmuCore/GS", "OsdShowSettings", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowSettings, "EmuCore/GS", "OsdShowSettings", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowInputs, "EmuCore/GS", "OsdShowInputs", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowInputs, "EmuCore/GS", "OsdShowInputs", false);
|
||||||
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.osdShowFrameTimes, "EmuCore/GS", "OsdShowFrameTimes", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.warnAboutUnsafeSettings, "EmuCore", "WarnAboutUnsafeSettings", true);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.warnAboutUnsafeSettings, "EmuCore", "WarnAboutUnsafeSettings", true);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fxaa, "EmuCore/GS", "fxaa", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.fxaa, "EmuCore/GS", "fxaa", false);
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.shadeBoost, "EmuCore/GS", "ShadeBoost", false);
|
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.shadeBoost, "EmuCore/GS", "ShadeBoost", false);
|
||||||
|
|
|
@ -1552,13 +1552,20 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="1">
|
||||||
<widget class="QCheckBox" name="warnAboutUnsafeSettings">
|
<widget class="QCheckBox" name="warnAboutUnsafeSettings">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Warn About Unsafe Settings</string>
|
<string>Warn About Unsafe Settings</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="osdShowFrameTimes">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Frame Times</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -508,7 +508,8 @@ struct Pcsx2Config
|
||||||
OsdShowGSStats : 1,
|
OsdShowGSStats : 1,
|
||||||
OsdShowIndicators : 1,
|
OsdShowIndicators : 1,
|
||||||
OsdShowSettings : 1,
|
OsdShowSettings : 1,
|
||||||
OsdShowInputs : 1;
|
OsdShowInputs : 1,
|
||||||
|
OsdShowFrameTimes : 1;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HWSpinGPUForReadbacks : 1,
|
HWSpinGPUForReadbacks : 1,
|
||||||
|
|
|
@ -2495,6 +2495,8 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
||||||
"EmuCore/GS", "OsdShowSettings", false);
|
"EmuCore/GS", "OsdShowSettings", false);
|
||||||
DrawToggleSetting(bsi, ICON_FA_GAMEPAD " Show Inputs",
|
DrawToggleSetting(bsi, ICON_FA_GAMEPAD " Show Inputs",
|
||||||
"Shows the current controller state of the system in the bottom-left corner of the display.", "EmuCore/GS", "OsdShowInputs", false);
|
"Shows the current controller state of the system in the bottom-left corner of the display.", "EmuCore/GS", "OsdShowInputs", false);
|
||||||
|
DrawToggleSetting(bsi, ICON_FA_RULER_HORIZONTAL " Show Frame Times",
|
||||||
|
"Shows a visual history of frame times in the upper-left corner of the display.", "EmuCore/GS", "OsdShowFrameTimes", false);
|
||||||
DrawToggleSetting(bsi, ICON_FA_EXCLAMATION_CIRCLE " Warn About Unsafe Settings",
|
DrawToggleSetting(bsi, ICON_FA_EXCLAMATION_CIRCLE " Warn About Unsafe Settings",
|
||||||
"Displays warnings when settings are enabled which may break games.", "EmuCore", "WarnAboutUnsafeSettings", true);
|
"Displays warnings when settings are enabled which may break games.", "EmuCore", "WarnAboutUnsafeSettings", true);
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,18 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "gsl/span"
|
||||||
#include "fmt/core.h"
|
#include "fmt/core.h"
|
||||||
|
|
||||||
|
#include "common/Align.h"
|
||||||
#include "common/StringUtil.h"
|
#include "common/StringUtil.h"
|
||||||
#include "common/Timer.h"
|
#include "common/Timer.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
@ -33,6 +37,7 @@
|
||||||
#include "Frontend/ImGuiOverlays.h"
|
#include "Frontend/ImGuiOverlays.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
#include "GS/GS.h"
|
#include "GS/GS.h"
|
||||||
|
#include "GS/GSVector.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
#include "HostDisplay.h"
|
#include "HostDisplay.h"
|
||||||
#include "IconsFontAwesome5.h"
|
#include "IconsFontAwesome5.h"
|
||||||
|
@ -60,6 +65,32 @@ namespace ImGuiManager
|
||||||
#endif
|
#endif
|
||||||
} // namespace ImGuiManager
|
} // namespace ImGuiManager
|
||||||
|
|
||||||
|
static std::tuple<float, float> GetMinMax(gsl::span<const float> values)
|
||||||
|
{
|
||||||
|
GSVector4 vmin(GSVector4::load<false>(values.data()));
|
||||||
|
GSVector4 vmax(vmin);
|
||||||
|
|
||||||
|
const u32 count = static_cast<u32>(values.size());
|
||||||
|
const u32 aligned_count = Common::AlignDownPow2(count, 4);
|
||||||
|
u32 i = 4;
|
||||||
|
for (; i < aligned_count; i += 4)
|
||||||
|
{
|
||||||
|
const GSVector4 v(GSVector4::load<false>(&values[i]));
|
||||||
|
vmin = vmin.min(v);
|
||||||
|
vmax = vmax.max(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float min = std::min(vmin.x, std::min(vmin.y, std::min(vmin.z, vmin.w)));
|
||||||
|
float max = std::max(vmax.x, std::max(vmax.y, std::max(vmax.z, vmax.w)));
|
||||||
|
for (; i < count; i++)
|
||||||
|
{
|
||||||
|
min = std::min(min, values[i]);
|
||||||
|
max = std::max(max, values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::tie(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGuiManager::FormatProcessorStat(std::string& text, double usage, double time)
|
void ImGuiManager::FormatProcessorStat(std::string& text, double usage, double time)
|
||||||
{
|
{
|
||||||
// Some values, such as GPU (and even CPU to some extent) can be out of phase with the wall clock,
|
// Some values, such as GPU (and even CPU to some extent) can be out of phase with the wall clock,
|
||||||
|
@ -224,6 +255,69 @@ void ImGuiManager::DrawPerformanceOverlay()
|
||||||
DRAW_LINE(standard_font, is_slowmo ? ICON_FA_FORWARD : ICON_FA_FAST_FORWARD, IM_COL32(255, 255, 255, 255));
|
DRAW_LINE(standard_font, is_slowmo ? ICON_FA_FORWARD : ICON_FA_FAST_FORWARD, IM_COL32(255, 255, 255, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PCSX2_CORE
|
||||||
|
if (GSConfig.OsdShowFrameTimes)
|
||||||
|
{
|
||||||
|
const ImVec2 history_size(200.0f * scale, 50.0f * scale);
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(history_size.x, history_size.y));
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x - margin - history_size.x, position_y));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.25f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_PlotLines, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||||
|
ImGui::PushFont(fixed_font);
|
||||||
|
if (ImGui::Begin("##frame_times", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs))
|
||||||
|
{
|
||||||
|
auto [min, max] = GetMinMax(PerformanceMetrics::GetFrameTimeHistory());
|
||||||
|
|
||||||
|
// add a little bit of space either side, so we're not constantly resizing
|
||||||
|
if ((max - min) < 4.0f)
|
||||||
|
{
|
||||||
|
min = min - std::fmod(min, 1.0f);
|
||||||
|
max = max - std::fmod(max, 1.0f) + 1.0f;
|
||||||
|
min = std::max(min - 2.0f, 0.0f);
|
||||||
|
max += 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PlotEx(
|
||||||
|
ImGuiPlotType_Lines, "##frame_times",
|
||||||
|
[](void*, int idx) -> float {
|
||||||
|
return PerformanceMetrics::GetFrameTimeHistory()[(
|
||||||
|
(PerformanceMetrics::GetFrameTimeHistoryPos() + idx) % PerformanceMetrics::NUM_FRAME_TIME_SAMPLES)];
|
||||||
|
},
|
||||||
|
nullptr, PerformanceMetrics::NUM_FRAME_TIME_SAMPLES, 0, nullptr, min, max, history_size);
|
||||||
|
|
||||||
|
ImDrawList* win_dl = ImGui::GetCurrentWindow()->DrawList;
|
||||||
|
const ImVec2 wpos(ImGui::GetCurrentWindow()->Pos);
|
||||||
|
|
||||||
|
text.clear();
|
||||||
|
fmt::format_to(std::back_inserter(text), "{:.1f} ms", max);
|
||||||
|
text_size = fixed_font->CalcTextSizeA(fixed_font->FontSize, FLT_MAX, 0.0f, text.c_str(), text.c_str() + text.length());
|
||||||
|
win_dl->AddText(ImVec2(wpos.x + history_size.x - text_size.x - spacing + shadow_offset, wpos.y + shadow_offset),
|
||||||
|
IM_COL32(0, 0, 0, 100), text.c_str(), text.c_str() + text.length());
|
||||||
|
win_dl->AddText(ImVec2(wpos.x + history_size.x - text_size.x - spacing, wpos.y), IM_COL32(255, 255, 255, 255), text.c_str(),
|
||||||
|
text.c_str() + text.length());
|
||||||
|
|
||||||
|
text.clear();
|
||||||
|
fmt::format_to(std::back_inserter(text), "{:.1f} ms", min);
|
||||||
|
text_size = fixed_font->CalcTextSizeA(fixed_font->FontSize, FLT_MAX, 0.0f, text.c_str(), text.c_str() + text.length());
|
||||||
|
win_dl->AddText(ImVec2(wpos.x + history_size.x - text_size.x - spacing + shadow_offset,
|
||||||
|
wpos.y + history_size.y - fixed_font->FontSize + shadow_offset),
|
||||||
|
IM_COL32(0, 0, 0, 100), text.c_str(), text.c_str() + text.length());
|
||||||
|
win_dl->AddText(ImVec2(wpos.x + history_size.x - text_size.x - spacing, wpos.y + history_size.y - fixed_font->FontSize),
|
||||||
|
IM_COL32(255, 255, 255, 255), text.c_str(), text.c_str() + text.length());
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::PopFont();
|
||||||
|
ImGui::PopStyleVar(5);
|
||||||
|
ImGui::PopStyleColor(3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (!fsui_active)
|
else if (!fsui_active)
|
||||||
{
|
{
|
||||||
|
|
|
@ -605,7 +605,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||||
if (Host::BeginPresentFrame(true))
|
if (Host::BeginPresentFrame(true))
|
||||||
Host::EndPresentFrame();
|
Host::EndPresentFrame();
|
||||||
g_gs_device->RestoreAPIState();
|
g_gs_device->RestoreAPIState();
|
||||||
PerformanceMetrics::Update(registers_written, fb_sprite_frame);
|
PerformanceMetrics::Update(registers_written, fb_sprite_frame, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
|
||||||
PerformanceMetrics::OnGPUPresent(g_host_display->GetAndResetAccumulatedGPUTime());
|
PerformanceMetrics::OnGPUPresent(g_host_display->GetAndResetAccumulatedGPUTime());
|
||||||
}
|
}
|
||||||
g_gs_device->RestoreAPIState();
|
g_gs_device->RestoreAPIState();
|
||||||
PerformanceMetrics::Update(registers_written, fb_sprite_frame);
|
PerformanceMetrics::Update(registers_written, fb_sprite_frame, false);
|
||||||
|
|
||||||
// snapshot
|
// snapshot
|
||||||
// wx is dumb and call this from the UI thread...
|
// wx is dumb and call this from the UI thread...
|
||||||
|
|
|
@ -321,6 +321,7 @@ Pcsx2Config::GSOptions::GSOptions()
|
||||||
OsdShowIndicators = true;
|
OsdShowIndicators = true;
|
||||||
OsdShowSettings = false;
|
OsdShowSettings = false;
|
||||||
OsdShowInputs = false;
|
OsdShowInputs = false;
|
||||||
|
OsdShowFrameTimes = false;
|
||||||
|
|
||||||
HWDownloadMode = GSHardwareDownloadMode::Enabled;
|
HWDownloadMode = GSHardwareDownloadMode::Enabled;
|
||||||
HWSpinGPUForReadbacks = false;
|
HWSpinGPUForReadbacks = false;
|
||||||
|
@ -544,6 +545,7 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
|
||||||
GSSettingBool(OsdShowIndicators);
|
GSSettingBool(OsdShowIndicators);
|
||||||
GSSettingBool(OsdShowSettings);
|
GSSettingBool(OsdShowSettings);
|
||||||
GSSettingBool(OsdShowInputs);
|
GSSettingBool(OsdShowInputs);
|
||||||
|
GSSettingBool(OsdShowFrameTimes);
|
||||||
|
|
||||||
GSSettingBool(HWSpinGPUForReadbacks);
|
GSSettingBool(HWSpinGPUForReadbacks);
|
||||||
GSSettingBool(HWSpinCPUForReadbacks);
|
GSSettingBool(HWSpinCPUForReadbacks);
|
||||||
|
|
|
@ -41,6 +41,7 @@ static float s_average_frame_time = 0.0f;
|
||||||
static float s_average_frame_time_accumulator = 0.0f;
|
static float s_average_frame_time_accumulator = 0.0f;
|
||||||
static float s_worst_frame_time_accumulator = 0.0f;
|
static float s_worst_frame_time_accumulator = 0.0f;
|
||||||
static u32 s_frames_since_last_update = 0;
|
static u32 s_frames_since_last_update = 0;
|
||||||
|
static u32 s_unskipped_frames_since_last_update = 0;
|
||||||
static Common::Timer s_last_update_time;
|
static Common::Timer s_last_update_time;
|
||||||
static Common::Timer s_last_frame_time;
|
static Common::Timer s_last_frame_time;
|
||||||
|
|
||||||
|
@ -65,6 +66,9 @@ static float s_gs_thread_time = 0.0f;
|
||||||
static float s_vu_thread_usage = 0.0f;
|
static float s_vu_thread_usage = 0.0f;
|
||||||
static float s_vu_thread_time = 0.0f;
|
static float s_vu_thread_time = 0.0f;
|
||||||
|
|
||||||
|
static PerformanceMetrics::FrameTimeHistory s_frame_time_history;
|
||||||
|
static u32 s_frame_time_history_pos = 0;
|
||||||
|
|
||||||
struct GSSWThreadStats
|
struct GSSWThreadStats
|
||||||
{
|
{
|
||||||
Threading::ThreadHandle handle;
|
Threading::ThreadHandle handle;
|
||||||
|
@ -100,11 +104,15 @@ void PerformanceMetrics::Clear()
|
||||||
s_gpu_usage = 0.0f;
|
s_gpu_usage = 0.0f;
|
||||||
|
|
||||||
s_frame_number = 0;
|
s_frame_number = 0;
|
||||||
|
|
||||||
|
s_frame_time_history.fill(0.0f);
|
||||||
|
s_frame_time_history_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerformanceMetrics::Reset()
|
void PerformanceMetrics::Reset()
|
||||||
{
|
{
|
||||||
s_frames_since_last_update = 0;
|
s_frames_since_last_update = 0;
|
||||||
|
s_unskipped_frames_since_last_update = 0;
|
||||||
s_gs_framebuffer_blits_since_last_update = 0;
|
s_gs_framebuffer_blits_since_last_update = 0;
|
||||||
s_gs_privileged_register_writes_since_last_update = 0;
|
s_gs_privileged_register_writes_since_last_update = 0;
|
||||||
s_average_frame_time_accumulator = 0.0f;
|
s_average_frame_time_accumulator = 0.0f;
|
||||||
|
@ -125,11 +133,18 @@ void PerformanceMetrics::Reset()
|
||||||
stat.last_cpu_time = stat.handle.GetCPUTime();
|
stat.last_cpu_time = stat.handle.GetCPUTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerformanceMetrics::Update(bool gs_register_write, bool fb_blit)
|
void PerformanceMetrics::Update(bool gs_register_write, bool fb_blit, bool is_skipping_present)
|
||||||
{
|
{
|
||||||
const float frame_time = s_last_frame_time.GetTimeMillisecondsAndReset();
|
if (!is_skipping_present)
|
||||||
s_average_frame_time_accumulator += frame_time;
|
{
|
||||||
s_worst_frame_time_accumulator = std::max(s_worst_frame_time_accumulator, frame_time);
|
const float frame_time = s_last_frame_time.GetTimeMillisecondsAndReset();
|
||||||
|
s_average_frame_time_accumulator += frame_time;
|
||||||
|
s_worst_frame_time_accumulator = std::max(s_worst_frame_time_accumulator, frame_time);
|
||||||
|
s_frame_time_history[s_frame_time_history_pos] = frame_time;
|
||||||
|
s_frame_time_history_pos = (s_frame_time_history_pos + 1) % NUM_FRAME_TIME_SAMPLES;
|
||||||
|
s_unskipped_frames_since_last_update++;
|
||||||
|
}
|
||||||
|
|
||||||
s_frames_since_last_update++;
|
s_frames_since_last_update++;
|
||||||
s_gs_privileged_register_writes_since_last_update += static_cast<u32>(gs_register_write);
|
s_gs_privileged_register_writes_since_last_update += static_cast<u32>(gs_register_write);
|
||||||
s_gs_framebuffer_blits_since_last_update += static_cast<u32>(fb_blit);
|
s_gs_framebuffer_blits_since_last_update += static_cast<u32>(fb_blit);
|
||||||
|
@ -144,10 +159,10 @@ void PerformanceMetrics::Update(bool gs_register_write, bool fb_blit)
|
||||||
s_last_update_time.ResetTo(now_ticks);
|
s_last_update_time.ResetTo(now_ticks);
|
||||||
s_worst_frame_time = s_worst_frame_time_accumulator;
|
s_worst_frame_time = s_worst_frame_time_accumulator;
|
||||||
s_worst_frame_time_accumulator = 0.0f;
|
s_worst_frame_time_accumulator = 0.0f;
|
||||||
s_average_frame_time = s_average_frame_time_accumulator / static_cast<float>(s_frames_since_last_update);
|
s_average_frame_time = s_average_frame_time_accumulator / static_cast<float>(s_unskipped_frames_since_last_update);
|
||||||
s_average_frame_time_accumulator = 0.0f;
|
s_average_frame_time_accumulator = 0.0f;
|
||||||
s_fps = static_cast<float>(s_frames_since_last_update) / time;
|
s_fps = static_cast<float>(s_frames_since_last_update) / time;
|
||||||
s_average_gpu_time = s_accumulated_gpu_time / static_cast<float>(s_frames_since_last_update);
|
s_average_gpu_time = s_accumulated_gpu_time / static_cast<float>(s_unskipped_frames_since_last_update);
|
||||||
s_gpu_usage = s_accumulated_gpu_time / (time * 10.0f);
|
s_gpu_usage = s_accumulated_gpu_time / (time * 10.0f);
|
||||||
s_accumulated_gpu_time = 0.0f;
|
s_accumulated_gpu_time = 0.0f;
|
||||||
|
|
||||||
|
@ -209,6 +224,7 @@ void PerformanceMetrics::Update(bool gs_register_write, bool fb_blit)
|
||||||
}
|
}
|
||||||
|
|
||||||
s_frames_since_last_update = 0;
|
s_frames_since_last_update = 0;
|
||||||
|
s_unskipped_frames_since_last_update = 0;
|
||||||
s_presents_since_last_update = 0;
|
s_presents_since_last_update = 0;
|
||||||
|
|
||||||
#ifdef PCSX2_CORE
|
#ifdef PCSX2_CORE
|
||||||
|
@ -339,3 +355,13 @@ float PerformanceMetrics::GetGPUAverageTime()
|
||||||
{
|
{
|
||||||
return s_average_gpu_time;
|
return s_average_gpu_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PerformanceMetrics::FrameTimeHistory& PerformanceMetrics::GetFrameTimeHistory()
|
||||||
|
{
|
||||||
|
return s_frame_time_history;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 PerformanceMetrics::GetFrameTimeHistoryPos()
|
||||||
|
{
|
||||||
|
return s_frame_time_history_pos;
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include "common/Threading.h"
|
#include "common/Threading.h"
|
||||||
|
|
||||||
namespace PerformanceMetrics
|
namespace PerformanceMetrics
|
||||||
|
@ -25,9 +27,12 @@ namespace PerformanceMetrics
|
||||||
DISPFBBlit
|
DISPFBBlit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr u32 NUM_FRAME_TIME_SAMPLES = 150;
|
||||||
|
using FrameTimeHistory = std::array<float, NUM_FRAME_TIME_SAMPLES>;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Reset();
|
void Reset();
|
||||||
void Update(bool gs_register_write, bool fb_blit);
|
void Update(bool gs_register_write, bool fb_blit, bool is_skipping_present);
|
||||||
void OnGPUPresent(float gpu_time);
|
void OnGPUPresent(float gpu_time);
|
||||||
|
|
||||||
/// Sets the EE thread for CPU usage calculations.
|
/// Sets the EE thread for CPU usage calculations.
|
||||||
|
@ -64,4 +69,7 @@ namespace PerformanceMetrics
|
||||||
|
|
||||||
float GetGPUUsage();
|
float GetGPUUsage();
|
||||||
float GetGPUAverageTime();
|
float GetGPUAverageTime();
|
||||||
|
|
||||||
|
const FrameTimeHistory& GetFrameTimeHistory();
|
||||||
|
u32 GetFrameTimeHistoryPos();
|
||||||
} // namespace PerformanceMetrics
|
} // namespace PerformanceMetrics
|
||||||
|
|
Loading…
Reference in New Issue