mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 13:13:43 +00:00
perf_overlays: add avg and 1p high/low
This commit is contained in:
parent
f103004aa0
commit
98b668b3a8
@ -1131,9 +1131,15 @@ namespace rsx
|
||||
color4f m_color;
|
||||
f32 m_min{};
|
||||
f32 m_max{};
|
||||
f32 m_avg{};
|
||||
f32 m_1p{};
|
||||
f32 m_guide_interval{};
|
||||
label m_label{};
|
||||
|
||||
bool m_show_min_max{false};
|
||||
bool m_show_1p_avg{false};
|
||||
bool m_1p_sort_high{false};
|
||||
|
||||
public:
|
||||
graph();
|
||||
void set_pos(u16 _x, u16 _y) override;
|
||||
@ -1144,6 +1150,8 @@ namespace rsx
|
||||
void set_count(u32 datapoint_count);
|
||||
void set_color(color4f color);
|
||||
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;
|
||||
u32 get_datapoint_count() const;
|
||||
void record_datapoint(f32 datapoint);
|
||||
|
@ -244,6 +244,9 @@ namespace rsx
|
||||
|
||||
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();
|
||||
force_next_update();
|
||||
|
||||
@ -271,7 +274,7 @@ namespace rsx
|
||||
|
||||
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_color(convert_color_code(m_color_body, m_opacity));
|
||||
m_fps_graph.set_guide_interval(10);
|
||||
@ -289,7 +292,7 @@ namespace rsx
|
||||
|
||||
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_color(convert_color_code(m_color_body, m_opacity));
|
||||
m_frametime_graph.set_guide_interval(8);
|
||||
@ -316,6 +319,18 @@ namespace rsx
|
||||
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)
|
||||
{
|
||||
if (m_detail == level)
|
||||
@ -420,9 +435,10 @@ namespace rsx
|
||||
{
|
||||
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_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)
|
||||
@ -495,7 +511,10 @@ namespace rsx
|
||||
{
|
||||
m_fps = std::max(0.f, static_cast<f32>(m_frames / (elapsed_update / 1000)));
|
||||
if (m_is_initialised && m_framerate_graph_enabled)
|
||||
{
|
||||
m_fps_graph.record_datapoint(m_fps);
|
||||
m_fps_graph.set_title(fmt::format("Framerate: %04.1f", m_fps).c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -680,6 +699,17 @@ namespace rsx
|
||||
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
|
||||
{
|
||||
return h + m_label.h + m_label.padding_top + m_label.padding_bottom;
|
||||
@ -699,23 +729,53 @@ namespace rsx
|
||||
// Record datapoint
|
||||
m_datapoints.push_back(datapoint);
|
||||
|
||||
// Calculate new min/max
|
||||
m_min = max_v<f32>;
|
||||
m_max = 0.0f;
|
||||
m_avg = 0.0f;
|
||||
m_1p = 0.0f;
|
||||
|
||||
// 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++)
|
||||
if (m_show_min_max || m_show_1p_avg)
|
||||
{
|
||||
const f32& dp = m_datapoints[i];
|
||||
m_min = max_v<f32>;
|
||||
|
||||
if (dp < 0) continue; // Skip initial negative values. They don't count.
|
||||
std::vector<f32> valid_datapoints;
|
||||
|
||||
m_min = std::min(m_min, dp);
|
||||
m_max = std::max(m_max, dp);
|
||||
// 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++)
|
||||
{
|
||||
const f32& dp = m_datapoints[i];
|
||||
|
||||
if (dp < 0) continue; // Skip initial negative values. They don't count.
|
||||
|
||||
m_min = std::min(m_min, dp);
|
||||
m_max = std::max(m_max, dp);
|
||||
m_avg += dp;
|
||||
|
||||
valid_datapoints.push_back(dp);
|
||||
}
|
||||
|
||||
// Sanitize min value
|
||||
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;
|
||||
}
|
||||
|
||||
// Sanitize min value
|
||||
m_min = std::min(m_min, m_max);
|
||||
|
||||
// Cull vector when it gets large
|
||||
if (m_datapoints.size() > m_datapoint_count * 16ull)
|
||||
@ -727,7 +787,19 @@ namespace rsx
|
||||
|
||||
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.auto_resize();
|
||||
@ -827,6 +899,7 @@ namespace rsx
|
||||
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_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();
|
||||
}
|
||||
else if (perf_overlay)
|
||||
|
@ -89,6 +89,7 @@ namespace rsx
|
||||
void set_frametime_graph_enabled(bool enabled);
|
||||
void set_framerate_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_position(screen_quadrant quadrant);
|
||||
void set_update_interval(u32 update_interval);
|
||||
|
@ -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> frametime_datapoint_count{ this, "Frametime datapoints", 170, 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<4, 36> font_size{ this, "Font size (px)", 10, true };
|
||||
cfg::_enum<screen_quadrant> position{ this, "Position", screen_quadrant::top_left, true };
|
||||
|
@ -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 <>
|
||||
void fmt_class_string<screen_quadrant>::format(std::string& out, u64 arg)
|
||||
{
|
||||
|
@ -208,3 +208,11 @@ enum class thread_scheduler_mode
|
||||
old,
|
||||
alt
|
||||
};
|
||||
|
||||
enum class perf_graph_detail_level
|
||||
{
|
||||
minimal,
|
||||
show_min_max,
|
||||
show_one_percent_avg,
|
||||
show_all
|
||||
};
|
||||
|
@ -53,7 +53,7 @@ bool hid_pad_handler<Device>::Init()
|
||||
if (res != 0)
|
||||
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>());
|
||||
}
|
||||
@ -167,7 +167,7 @@ void hid_pad_handler<Device>::enumerate_devices()
|
||||
}
|
||||
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)
|
||||
{
|
||||
hid_log.success("%s Controllers found: %d", m_type, count);
|
||||
|
@ -499,7 +499,7 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
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);
|
||||
|
||||
return;
|
||||
|
@ -686,7 +686,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||
|
||||
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.;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user