perf_overlays: add avg and 1p high/low

This commit is contained in:
Megamouse 2021-05-19 21:14:49 +02:00
parent f103004aa0
commit 98b668b3a8
9 changed files with 129 additions and 20 deletions

View file

@ -1131,9 +1131,15 @@ namespace rsx
color4f m_color; color4f m_color;
f32 m_min{}; f32 m_min{};
f32 m_max{}; f32 m_max{};
f32 m_avg{};
f32 m_1p{};
f32 m_guide_interval{}; f32 m_guide_interval{};
label m_label{}; label m_label{};
bool m_show_min_max{false};
bool m_show_1p_avg{false};
bool m_1p_sort_high{false};
public: public:
graph(); graph();
void set_pos(u16 _x, u16 _y) override; void set_pos(u16 _x, u16 _y) override;
@ -1144,6 +1150,8 @@ namespace rsx
void set_count(u32 datapoint_count); void set_count(u32 datapoint_count);
void set_color(color4f color); void set_color(color4f color);
void set_guide_interval(f32 guide_interval); void set_guide_interval(f32 guide_interval);
void set_labels_visible(bool show_min_max, bool show_1p_avg);
void set_one_percent_sort_high(bool sort_1p_high);
u16 get_height() const; u16 get_height() const;
u32 get_datapoint_count() const; u32 get_datapoint_count() const;
void record_datapoint(f32 datapoint); void record_datapoint(f32 datapoint);

View file

@ -244,6 +244,9 @@ namespace rsx
void perf_metrics_overlay::init() void perf_metrics_overlay::init()
{ {
m_fps_graph.set_one_percent_sort_high(false);
m_frametime_graph.set_one_percent_sort_high(true);
reset_transforms(); reset_transforms();
force_next_update(); force_next_update();
@ -271,7 +274,7 @@ namespace rsx
if (enabled) if (enabled)
{ {
m_fps_graph.set_title(" Framerate"); m_fps_graph.set_title("Framerate: 00.0");
m_fps_graph.set_font_size(static_cast<u16>(m_font_size * 0.8)); m_fps_graph.set_font_size(static_cast<u16>(m_font_size * 0.8));
m_fps_graph.set_color(convert_color_code(m_color_body, m_opacity)); m_fps_graph.set_color(convert_color_code(m_color_body, m_opacity));
m_fps_graph.set_guide_interval(10); m_fps_graph.set_guide_interval(10);
@ -289,7 +292,7 @@ namespace rsx
if (enabled) if (enabled)
{ {
m_frametime_graph.set_title(" Frametime"); m_frametime_graph.set_title("Frametime: 0.0");
m_frametime_graph.set_font_size(static_cast<u16>(m_font_size * 0.8)); m_frametime_graph.set_font_size(static_cast<u16>(m_font_size * 0.8));
m_frametime_graph.set_color(convert_color_code(m_color_body, m_opacity)); m_frametime_graph.set_color(convert_color_code(m_color_body, m_opacity));
m_frametime_graph.set_guide_interval(8); m_frametime_graph.set_guide_interval(8);
@ -316,6 +319,18 @@ namespace rsx
m_force_repaint = true; m_force_repaint = true;
} }
void perf_metrics_overlay::set_graph_detail_levels(perf_graph_detail_level framerate_level, perf_graph_detail_level frametime_level)
{
m_fps_graph.set_labels_visible(
framerate_level == perf_graph_detail_level::show_all || framerate_level == perf_graph_detail_level::show_min_max,
framerate_level == perf_graph_detail_level::show_all || framerate_level == perf_graph_detail_level::show_one_percent_avg);
m_frametime_graph.set_labels_visible(
frametime_level == perf_graph_detail_level::show_all || frametime_level == perf_graph_detail_level::show_min_max,
frametime_level == perf_graph_detail_level::show_all || frametime_level == perf_graph_detail_level::show_one_percent_avg);
m_force_repaint = true;
}
void perf_metrics_overlay::set_detail_level(detail_level level) void perf_metrics_overlay::set_detail_level(detail_level level)
{ {
if (m_detail == level) if (m_detail == level)
@ -420,9 +435,10 @@ namespace rsx
{ {
if (m_frametime_graph_enabled && !m_force_update) if (m_frametime_graph_enabled && !m_force_update)
{ {
const auto elapsed_frame = m_frametime_timer.GetElapsedTimeInMilliSec(); const float elapsed_frame = static_cast<float>(m_frametime_timer.GetElapsedTimeInMilliSec());
m_frametime_timer.Start(); m_frametime_timer.Start();
m_frametime_graph.record_datapoint(static_cast<float>(elapsed_frame)); m_frametime_graph.record_datapoint(elapsed_frame);
m_frametime_graph.set_title(fmt::format("Frametime: %4.1f", elapsed_frame).c_str());
} }
if (m_force_repaint) if (m_force_repaint)
@ -495,7 +511,10 @@ namespace rsx
{ {
m_fps = std::max(0.f, static_cast<f32>(m_frames / (elapsed_update / 1000))); m_fps = std::max(0.f, static_cast<f32>(m_frames / (elapsed_update / 1000)));
if (m_is_initialised && m_framerate_graph_enabled) if (m_is_initialised && m_framerate_graph_enabled)
{
m_fps_graph.record_datapoint(m_fps); m_fps_graph.record_datapoint(m_fps);
m_fps_graph.set_title(fmt::format("Framerate: %04.1f", m_fps).c_str());
}
break; break;
} }
} }
@ -680,6 +699,17 @@ namespace rsx
m_guide_interval = guide_interval; m_guide_interval = guide_interval;
} }
void graph::set_labels_visible(bool show_min_max, bool show_1p_avg)
{
m_show_min_max = show_min_max;
m_show_1p_avg = show_1p_avg;
}
void graph::set_one_percent_sort_high(bool sort_1p_high)
{
m_1p_sort_high = sort_1p_high;
}
u16 graph::get_height() const u16 graph::get_height() const
{ {
return h + m_label.h + m_label.padding_top + m_label.padding_bottom; return h + m_label.h + m_label.padding_top + m_label.padding_bottom;
@ -699,9 +729,15 @@ namespace rsx
// Record datapoint // Record datapoint
m_datapoints.push_back(datapoint); m_datapoints.push_back(datapoint);
// Calculate new min/max
m_min = max_v<f32>;
m_max = 0.0f; m_max = 0.0f;
m_avg = 0.0f;
m_1p = 0.0f;
if (m_show_min_max || m_show_1p_avg)
{
m_min = max_v<f32>;
std::vector<f32> valid_datapoints;
// Make sure min/max reflects the data being displayed, not the entire datapoints vector // Make sure min/max reflects the data being displayed, not the entire datapoints vector
for (usz i = m_datapoints.size() - m_datapoint_count; i < m_datapoints.size(); i++) for (usz i = m_datapoints.size() - m_datapoint_count; i < m_datapoints.size(); i++)
@ -712,11 +748,35 @@ namespace rsx
m_min = std::min(m_min, dp); m_min = std::min(m_min, dp);
m_max = std::max(m_max, dp); m_max = std::max(m_max, dp);
m_avg += dp;
valid_datapoints.push_back(dp);
} }
// Sanitize min value // Sanitize min value
m_min = std::min(m_min, m_max); m_min = std::min(m_min, m_max);
if (m_show_1p_avg && valid_datapoints.size())
{
// Sort datapoints (we are only interested in the lowest/highest 1%)
const usz i_1p = valid_datapoints.size() / 100;
const usz n_1p = i_1p + 1;
if (m_1p_sort_high)
std::nth_element(valid_datapoints.begin(), valid_datapoints.begin() + i_1p, valid_datapoints.end(), std::greater<f32>());
else
std::nth_element(valid_datapoints.begin(), valid_datapoints.begin() + i_1p, valid_datapoints.end());
// Calculate statistics
m_avg /= valid_datapoints.size();
m_1p = std::accumulate(valid_datapoints.begin(), valid_datapoints.begin() + n_1p, 0.0f) / static_cast<float>(n_1p);
}
}
else
{
m_min = 0.0f;
}
// Cull vector when it gets large // Cull vector when it gets large
if (m_datapoints.size() > m_datapoint_count * 16ull) if (m_datapoints.size() > m_datapoint_count * 16ull)
{ {
@ -727,7 +787,19 @@ namespace rsx
void graph::update() void graph::update()
{ {
m_label.set_text(fmt::format("%s\nmn:%4.1f mx:%4.1f", m_title.c_str(), m_min, m_max)); std::string fps_info = m_title;
if (m_show_1p_avg)
{
fmt::append(fps_info, "\n1%%:%4.1f av:%4.1f", m_1p, m_avg);
}
if (m_show_min_max)
{
fmt::append(fps_info, "\nmn:%4.1f mx:%4.1f", m_min, m_max);
}
m_label.set_text(fps_info);
m_label.set_padding(4, 4, 0, 4); m_label.set_padding(4, 4, 0, 4);
m_label.auto_resize(); m_label.auto_resize();
@ -827,6 +899,7 @@ namespace rsx
perf_overlay->set_frametime_datapoint_count(perf_settings.frametime_datapoint_count); perf_overlay->set_frametime_datapoint_count(perf_settings.frametime_datapoint_count);
perf_overlay->set_framerate_graph_enabled(perf_settings.framerate_graph_enabled.get()); perf_overlay->set_framerate_graph_enabled(perf_settings.framerate_graph_enabled.get());
perf_overlay->set_frametime_graph_enabled(perf_settings.frametime_graph_enabled.get()); perf_overlay->set_frametime_graph_enabled(perf_settings.frametime_graph_enabled.get());
perf_overlay->set_graph_detail_levels(perf_settings.framerate_graph_detail_level.get(), perf_settings.frametime_graph_detail_level.get());
perf_overlay->init(); perf_overlay->init();
} }
else if (perf_overlay) else if (perf_overlay)

View file

@ -89,6 +89,7 @@ namespace rsx
void set_frametime_graph_enabled(bool enabled); void set_frametime_graph_enabled(bool enabled);
void set_framerate_datapoint_count(u32 datapoint_count); void set_framerate_datapoint_count(u32 datapoint_count);
void set_frametime_datapoint_count(u32 datapoint_count); void set_frametime_datapoint_count(u32 datapoint_count);
void set_graph_detail_levels(perf_graph_detail_level framerate_level, perf_graph_detail_level frametime_level);
void set_detail_level(detail_level level); void set_detail_level(detail_level level);
void set_position(screen_quadrant quadrant); void set_position(screen_quadrant quadrant);
void set_update_interval(u32 update_interval); void set_update_interval(u32 update_interval);

View file

@ -190,6 +190,8 @@ struct cfg_root : cfg::node
cfg::uint<2, 6000> framerate_datapoint_count{ this, "Framerate datapoints", 50, true }; cfg::uint<2, 6000> framerate_datapoint_count{ this, "Framerate datapoints", 50, true };
cfg::uint<2, 6000> frametime_datapoint_count{ this, "Frametime datapoints", 170, true }; cfg::uint<2, 6000> frametime_datapoint_count{ this, "Frametime datapoints", 170, true };
cfg::_enum<detail_level> level{ this, "Detail level", detail_level::medium, true }; cfg::_enum<detail_level> level{ this, "Detail level", detail_level::medium, true };
cfg::_enum<perf_graph_detail_level> framerate_graph_detail_level{ this, "Framerate graph detail level", perf_graph_detail_level::show_all, true };
cfg::_enum<perf_graph_detail_level> frametime_graph_detail_level{ this, "Frametime graph detail level", perf_graph_detail_level::show_all, true };
cfg::uint<1, 1000> update_interval{ this, "Metrics update interval (ms)", 350, true }; cfg::uint<1, 1000> update_interval{ this, "Metrics update interval (ms)", 350, true };
cfg::uint<4, 36> font_size{ this, "Font size (px)", 10, true }; cfg::uint<4, 36> font_size{ this, "Font size (px)", 10, true };
cfg::_enum<screen_quadrant> position{ this, "Position", screen_quadrant::top_left, true }; cfg::_enum<screen_quadrant> position{ this, "Position", screen_quadrant::top_left, true };

View file

@ -143,6 +143,23 @@ void fmt_class_string<detail_level>::format(std::string& out, u64 arg)
}); });
} }
template <>
void fmt_class_string<perf_graph_detail_level>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](perf_graph_detail_level value)
{
switch (value)
{
case perf_graph_detail_level::minimal: return "Minimal";
case perf_graph_detail_level::show_min_max: return "Show min and max";
case perf_graph_detail_level::show_one_percent_avg: return "Show 1% and average";
case perf_graph_detail_level::show_all: return "All";
}
return unknown;
});
}
template <> template <>
void fmt_class_string<screen_quadrant>::format(std::string& out, u64 arg) void fmt_class_string<screen_quadrant>::format(std::string& out, u64 arg)
{ {

View file

@ -208,3 +208,11 @@ enum class thread_scheduler_mode
old, old,
alt alt
}; };
enum class perf_graph_detail_level
{
minimal,
show_min_max,
show_one_percent_avg,
show_all
};

View file

@ -53,7 +53,7 @@ bool hid_pad_handler<Device>::Init()
if (res != 0) if (res != 0)
fmt::throw_exception("%s hidapi-init error.threadproc", m_type); fmt::throw_exception("%s hidapi-init error.threadproc", m_type);
for (size_t i = 1; i <= MAX_GAMEPADS; i++) // Controllers 1-n in GUI for (usz i = 1; i <= MAX_GAMEPADS; i++) // Controllers 1-n in GUI
{ {
m_controllers.emplace(m_name_string + std::to_string(i), std::make_shared<Device>()); m_controllers.emplace(m_name_string + std::to_string(i), std::make_shared<Device>());
} }
@ -167,7 +167,7 @@ void hid_pad_handler<Device>::enumerate_devices()
} }
else else
{ {
const size_t count = std::count_if(m_controllers.cbegin(), m_controllers.cend(), [](const auto& c) { return c.second && c.second->hidDevice; }); const usz count = std::count_if(m_controllers.cbegin(), m_controllers.cend(), [](const auto& c) { return c.second && c.second->hidDevice; });
if (count > 0) if (count > 0)
{ {
hid_log.success("%s Controllers found: %d", m_type, count); hid_log.success("%s Controllers found: %d", m_type, count);

View file

@ -499,7 +499,7 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
default: break; default: break;
} }
if (const size_t pos = std::basic_string_view<u32>(res.data(), 2).find_last_not_of(umax); pos != umax) if (const usz pos = std::basic_string_view<u32>(res.data(), 2).find_last_not_of(umax); pos != umax)
m_debugger_list->ShowAddress(res[pos] - std::max(row, 0) * 4, true, true); m_debugger_list->ShowAddress(res[pos] - std::max(row, 0) * 4, true, true);
return; return;

View file

@ -686,7 +686,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
bool cancelled = false; bool cancelled = false;
for (size_t i = 0, count = packages.size(); i < count; i++) for (usz i = 0, count = packages.size(); i < count; i++)
{ {
progress = 0.; progress = 0.;