summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorSam Belliveau <sam.belliveau@gmail.com>2023-01-06 17:21:17 -0500
committerSam Belliveau <sam.belliveau@gmail.com>2023-01-06 17:21:17 -0500
commitbc1cc9eeb44f48a7333fc5acfefc0f2eaaa30fc3 (patch)
tree81c20e42f250dafbaa83e702f1883fff57f6ed12 /Source/Core/VideoCommon
parent2da39f7e00d01fbfc7ea2728231a6e52395f5b1e (diff)
CoreTiming: Throttle Before Every Event Using Chrono
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/PerformanceMetrics.cpp160
-rw-r--r--Source/Core/VideoCommon/PerformanceMetrics.h24
2 files changed, 128 insertions, 56 deletions
diff --git a/Source/Core/VideoCommon/PerformanceMetrics.cpp b/Source/Core/VideoCommon/PerformanceMetrics.cpp
index 23e35623cb..b343af0f4f 100644
--- a/Source/Core/VideoCommon/PerformanceMetrics.cpp
+++ b/Source/Core/VideoCommon/PerformanceMetrics.cpp
@@ -3,10 +3,14 @@
#include "VideoCommon/PerformanceMetrics.h"
+#include <mutex>
+
#include <imgui.h>
#include <implot.h>
+#include "Core/CoreTiming.h"
#include "Core/HW/VideoInterface.h"
+#include "Core/System.h"
#include "VideoCommon/VideoConfig.h"
PerformanceMetrics g_perf_metrics;
@@ -16,6 +20,10 @@ void PerformanceMetrics::Reset()
m_fps_counter.Reset();
m_vps_counter.Reset();
m_speed_counter.Reset();
+
+ m_time_sleeping = DT::zero();
+ m_real_times.fill(Clock::now());
+ m_cpu_times.fill(Core::System::GetInstance().GetCoreTiming().GetCPUTimePoint(0));
}
void PerformanceMetrics::CountFrame()
@@ -29,6 +37,20 @@ void PerformanceMetrics::CountVBlank()
m_speed_counter.Count();
}
+void PerformanceMetrics::CountThrottleSleep(DT sleep)
+{
+ std::unique_lock lock(m_time_lock);
+ m_time_sleeping += sleep;
+}
+
+void PerformanceMetrics::CountPerformanceMarker(Core::System& system, s64 cyclesLate)
+{
+ std::unique_lock lock(m_time_lock);
+ m_real_times[m_time_index] = Clock::now() - m_time_sleeping;
+ m_cpu_times[m_time_index] = system.GetCoreTiming().GetCPUTimePoint(cyclesLate);
+ m_time_index += 1;
+}
+
double PerformanceMetrics::GetFPS() const
{
return m_fps_counter.GetHzAvg();
@@ -41,7 +63,14 @@ double PerformanceMetrics::GetVPS() const
double PerformanceMetrics::GetSpeed() const
{
- return 100.0 * m_speed_counter.GetHzAvg() / VideoInterface::GetTargetRefreshRate();
+ return m_speed_counter.GetHzAvg() / VideoInterface::GetTargetRefreshRate();
+}
+
+double PerformanceMetrics::GetMaxSpeed() const
+{
+ std::shared_lock lock(m_time_lock);
+ return DT_s(m_cpu_times[u8(m_time_index - 1)] - m_cpu_times[m_time_index]) /
+ DT_s(m_real_times[u8(m_time_index - 1)] - m_real_times[m_time_index]);
}
double PerformanceMetrics::GetLastSpeedDenominator() const
@@ -49,7 +78,7 @@ double PerformanceMetrics::GetLastSpeedDenominator() const
return DT_s(m_speed_counter.GetLastRawDt()).count() * VideoInterface::GetTargetRefreshRate();
}
-void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
+void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
{
const float bg_alpha = 0.7f;
const auto imgui_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs |
@@ -65,9 +94,9 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
float r = 0.0f, g = 1.0f, b = 1.0f;
if (g_ActiveConfig.bShowSpeedColors)
{
- r = 1.0 - (speed - 80.0) / 20.0;
- g = speed / 80.0;
- b = (speed - 90.0) / 10.0;
+ r = 1.0 - (speed - 0.8) / 0.2;
+ g = speed / 0.8;
+ b = (speed - 0.9) / 0.1;
}
const float window_padding = 8.f * backbuffer_scale;
@@ -79,6 +108,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
const float graph_height =
std::min(200.f * backbuffer_scale, ImGui::GetIO().DisplaySize.y - 85.f * backbuffer_scale);
+ const bool stack_vertically = !g_ActiveConfig.bShowGraphs;
+
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 14.f * backbuffer_scale);
if (g_ActiveConfig.bShowGraphs)
@@ -93,40 +124,39 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
if (ImGui::Begin("PerformanceGraphs", nullptr, imgui_flags))
{
- const static int num_ticks = 17;
- const static double tick_marks[num_ticks] = {0.0,
- 1000.0 / 360.0,
- 1000.0 / 240.0,
- 1000.0 / 180.0,
- 1000.0 / 120.0,
- 1000.0 / 90.00,
- 1000.0 / 59.94,
- 1000.0 / 40.00,
- 1000.0 / 29.97,
- 1000.0 / 24.00,
- 1000.0 / 20.00,
- 1000.0 / 15.00,
- 1000.0 / 10.00,
- 1000.0 / 5.000,
- 1000.0 / 2.000,
- 1000.0,
- 2000.0};
-
- const DT vblank_time = m_vps_counter.GetDtAvg() + m_vps_counter.GetDtStd();
- const DT frame_time = m_fps_counter.GetDtAvg() + m_fps_counter.GetDtStd();
+ static constexpr std::size_t num_ticks = 17;
+ static constexpr std::array<double, num_ticks> tick_marks = {0.0,
+ 1000.0 / 360.0,
+ 1000.0 / 240.0,
+ 1000.0 / 180.0,
+ 1000.0 / 120.0,
+ 1000.0 / 90.00,
+ 1000.0 / 59.94,
+ 1000.0 / 40.00,
+ 1000.0 / 29.97,
+ 1000.0 / 24.00,
+ 1000.0 / 20.00,
+ 1000.0 / 15.00,
+ 1000.0 / 10.00,
+ 1000.0 / 5.000,
+ 1000.0 / 2.000,
+ 1000.0,
+ 2000.0};
+
+ const DT vblank_time = m_vps_counter.GetDtAvg() + 2 * m_vps_counter.GetDtStd();
+ const DT frame_time = m_fps_counter.GetDtAvg() + 2 * m_fps_counter.GetDtStd();
const double target_max_time = DT_ms(vblank_time + frame_time).count();
const double a =
- std::max(0.0, 1.0 - std::exp(-4000.0 * m_vps_counter.GetLastRawDt().count() /
- DT_ms(m_vps_counter.GetSampleWindow()).count()));
+ std::max(0.0, 1.0 - std::exp(-4.0 * (DT_s(m_vps_counter.GetLastRawDt()) /
+ DT_s(m_vps_counter.GetSampleWindow()))));
- static double max_time = 0.0;
- if (std::isfinite(max_time))
- max_time += a * (target_max_time - max_time);
+ if (std::isfinite(m_graph_max_time))
+ m_graph_max_time += a * (target_max_time - m_graph_max_time);
else
- max_time = target_max_time;
+ m_graph_max_time = target_max_time;
- const double total_frame_time = std::max(DT_ms(m_fps_counter.GetSampleWindow()).count(),
- DT_ms(m_vps_counter.GetSampleWindow()).count());
+ const double total_frame_time =
+ DT_ms(std::max(m_fps_counter.GetSampleWindow(), m_vps_counter.GetSampleWindow())).count();
if (ImPlot::BeginPlot("PerformanceGraphs", ImVec2(-1.0, -1.0),
ImPlotFlags_NoFrame | ImPlotFlags_NoTitle | ImPlotFlags_NoMenus))
@@ -141,8 +171,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
ImPlotAxisFlags_Lock | ImPlotAxisFlags_Invert | ImPlotAxisFlags_NoLabel |
ImPlotAxisFlags_NoHighlight);
ImPlot::SetupAxisFormat(ImAxis_Y1, "%.1f");
- ImPlot::SetupAxisTicks(ImAxis_Y1, tick_marks, num_ticks);
- ImPlot::SetupAxesLimits(0, total_frame_time, 0, max_time, ImGuiCond_Always);
+ ImPlot::SetupAxisTicks(ImAxis_Y1, tick_marks.data(), num_ticks);
+ ImPlot::SetupAxesLimits(0, total_frame_time, 0, m_graph_max_time, ImGuiCond_Always);
ImPlot::SetupLegend(ImPlotLocation_SouthEast, ImPlotLegendFlags_None);
m_vps_counter.ImPlotPlotLines("V-Blank (ms)");
m_fps_counter.ImPlotPlotLines("Frame (ms)");
@@ -155,14 +185,42 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
}
}
- if (g_ActiveConfig.bShowFPS || g_ActiveConfig.bShowFTimes)
+ if (g_ActiveConfig.bShowSpeed)
{
// Position in the top-right corner of the screen.
+ float window_height = 47.f * backbuffer_scale;
+
+ ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
+ ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
+ ImGui::SetNextWindowBgAlpha(bg_alpha);
+
+ if (stack_vertically)
+ window_y += window_height + window_padding;
+ else
+ window_x -= window_width + window_padding;
+
+ if (ImGui::Begin("SpeedStats", nullptr, imgui_flags))
+ {
+ ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Speed:%4.0lf%%", 100.0 * speed);
+ ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Max:%6.0lf%%", 100.0 * GetMaxSpeed());
+ ImGui::End();
+ }
+ }
+
+ if (g_ActiveConfig.bShowFPS || g_ActiveConfig.bShowFTimes)
+ {
int count = g_ActiveConfig.bShowFPS + 2 * g_ActiveConfig.bShowFTimes;
+ float window_height = (12.f + 17.f * count) * backbuffer_scale;
+
+ // Position in the top-right corner of the screen.
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
- ImGui::SetNextWindowSize(ImVec2(window_width, (12.f + 17.f * count) * backbuffer_scale));
+ ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
ImGui::SetNextWindowBgAlpha(bg_alpha);
- window_x -= window_width + window_padding;
+
+ if (stack_vertically)
+ window_y += window_height + window_padding;
+ else
+ window_x -= window_width + window_padding;
if (ImGui::Begin("FPSStats", nullptr, imgui_flags))
{
@@ -181,12 +239,18 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
if (g_ActiveConfig.bShowVPS || g_ActiveConfig.bShowVTimes)
{
- // Position in the top-right corner of the screen.
int count = g_ActiveConfig.bShowVPS + 2 * g_ActiveConfig.bShowVTimes;
+ float window_height = (12.f + 17.f * count) * backbuffer_scale;
+
+ // Position in the top-right corner of the screen.
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
ImGui::SetNextWindowSize(ImVec2(window_width, (12.f + 17.f * count) * backbuffer_scale));
ImGui::SetNextWindowBgAlpha(bg_alpha);
- window_x -= window_width + window_padding;
+
+ if (stack_vertically)
+ window_y += window_height + window_padding;
+ else
+ window_x -= window_width + window_padding;
if (ImGui::Begin("VPSStats", nullptr, imgui_flags))
{
@@ -203,19 +267,5 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const
}
}
- if (g_ActiveConfig.bShowSpeed)
- {
- // Position in the top-right corner of the screen.
- ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
- ImGui::SetNextWindowSize(ImVec2(window_width, 29.f * backbuffer_scale));
- ImGui::SetNextWindowBgAlpha(bg_alpha);
-
- if (ImGui::Begin("SpeedStats", nullptr, imgui_flags))
- {
- ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Speed:%4.0lf%%", speed);
- ImGui::End();
- }
- }
-
ImGui::PopStyleVar(2);
}
diff --git a/Source/Core/VideoCommon/PerformanceMetrics.h b/Source/Core/VideoCommon/PerformanceMetrics.h
index eb6f8ecb00..009c27fd3f 100644
--- a/Source/Core/VideoCommon/PerformanceMetrics.h
+++ b/Source/Core/VideoCommon/PerformanceMetrics.h
@@ -3,8 +3,17 @@
#pragma once
+#include <array>
+#include <shared_mutex>
+
+#include "Common/CommonTypes.h"
#include "VideoCommon/PerformanceTracker.h"
+namespace Core
+{
+class System;
+}
+
class PerformanceMetrics
{
public:
@@ -21,20 +30,33 @@ public:
void CountFrame();
void CountVBlank();
+ void CountThrottleSleep(DT sleep);
+ void CountPerformanceMarker(Core::System& system, s64 cyclesLate);
+
// Getter Functions
double GetFPS() const;
double GetVPS() const;
double GetSpeed() const;
+ double GetMaxSpeed() const;
double GetLastSpeedDenominator() const;
// ImGui Functions
- void DrawImGuiStats(const float backbuffer_scale) const;
+ void DrawImGuiStats(const float backbuffer_scale);
private:
PerformanceTracker m_fps_counter{"render_times.txt"};
PerformanceTracker m_vps_counter{"vblank_times.txt"};
PerformanceTracker m_speed_counter{std::nullopt, 500000};
+
+ double m_graph_max_time = 0.0;
+
+ mutable std::shared_mutex m_time_lock;
+
+ u8 m_time_index = 0;
+ std::array<TimePoint, 256> m_real_times;
+ std::array<TimePoint, 256> m_cpu_times;
+ DT m_time_sleeping;
};
extern PerformanceMetrics g_perf_metrics;