diff --git a/README.md b/README.md index 3741e4e2..38f82a09 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ You can also customize the hud by using the `MANGOHUD_CONFIG` environment variab You can also specify configuration file with `MANGOHUD_CONFIGFILE=/path/to/config` for applications whose names are hard to guess (java, python etc). A partial list of parameters are below. See the config file for a complete list. +Parameters that are enabled by default have to be explicitly disabled. These (currently) are `fps`, `frame_timing`, `cpu_stats` (cpu load), `gpu_stats` (gpu load). | Variable | Description | |------------------------------------|---------------------------------------------------------------------------------------| @@ -133,7 +134,7 @@ A partial list of parameters are below. See the config file for a complete list. | `core_load` | Displays load & frequency per core | | `gpu_core_clock`
`gpu_mem_clock`| Displays GPU core/memory frequency | | `ram`
`vram` | Displays system RAM/VRAM usage | -| `full` | Enables all of the above config options | +| `full` | Enables most of the toggleable parameters (currently excludes `histogram`) | | `font_size=` | Customizeable font size (default=24) | | `font_size_text=` | Customizeable font size for other text like media metadata (default=24) | | `font_scale=` | Set global font scale (default=1.0) | @@ -146,7 +147,7 @@ A partial list of parameters are below. See the config file for a complete list. | `no_display` | Hide the hud by default | | `toggle_hud=`
`toggle_logging=` | Modifiable toggle hotkeys. Default are `Shift_R+F12` and `Shift_L+F2`, respectively. | | `reload_cfg=` | Change keybind for reloading the config. Default = `Shift_L+F4` | -| `time`
`time_format=%T` | Displays local time. See [std::put_time](https://en.cppreference.com/w/cpp/io/manip/put_time) for formatting help. NOTE: Sometimes apps (or AMDVLK) may set `TZ` environment variable to `GMT+0` | +| `time`
`time_format=%T` | Displays local time. See [std::put_time](https://en.cppreference.com/w/cpp/io/manip/put_time) for formatting help. NOTE: Sometimes apps (or AMDVLK (should be fixed in latest)) may set `TZ` (timezone) environment variable to UTC/GMT | | `gpu_color`
`gpu_color`
`vram_color`
`ram_color`
`io_color`
`engine_color`
`frametime_color`
`background_color`
`text_color`
`media_player_color` | Change default colors: `gpu_color=RRGGBB`| | `alpha` | Set the opacity of all text and frametime graph `0.0-1.0` | | `background_alpha` | Set the opacity of the background `0.0-1.0` | @@ -172,6 +173,7 @@ A partial list of parameters are below. See the config file for a complete list. | `engine_version` | Display OpenGL or vulkan and vulkan-based render engine's version | | `permit_upload` | Allow uploading of logs to Flightlessmango.com | | `upload_log` | Change keybind for uploading log | +| `benchmark_percentiles` | Configure which framerate percentiles are shown in the logging summary. Default is `97+AVG+1+0.1` | Example: `MANGOHUD_CONFIG=cpu_temp,gpu_temp,position=top-right,height=500,font_size=32` diff --git a/bin/MangoHud.conf b/bin/MangoHud.conf index 4ab60e1e..9038a494 100644 --- a/bin/MangoHud.conf +++ b/bin/MangoHud.conf @@ -130,3 +130,6 @@ background_alpha=0.5 # output_file ### Permit uploading logs directly to Flightlessmango.com # permit_upload=1 +### Define a '+'-separated list of percentiles shown in the benchmark results. +### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1 +# benchmark_percentiles= \ No newline at end of file diff --git a/build.sh b/build.sh index a6ed768b..30325000 100755 --- a/build.sh +++ b/build.sh @@ -69,7 +69,7 @@ dependencies() { DEPS="{glibc-devel.i686,libstdc++-devel.i686,libX11-devel.i686}" dep_install ;; - *"buntu"|"Linux Mint"|"Debian GNU/Linux"|"Zorin OS"|"Pop!_OS"|"elementary OS") + *"buntu"|"Linux Mint"|"Debian GNU/Linux"|"Zorin OS"|"Pop!_OS"|"elementary OS"|"KDE neon") MANAGER_QUERY="dpkg-query -s" MANAGER_INSTALL="apt install" DEPS="{gcc,g++,gcc-multilib,g++-multilib,ninja-build,python3-pip,python3-setuptools,python3-wheel,pkg-config,mesa-common-dev,libx11-dev,libxnvctrl-dev,libdbus-1-dev}" @@ -79,7 +79,7 @@ dependencies() { $SU_CMD pip3 install 'meson>=0.54' mako fi if [[ ! -f /usr/local/bin/glslangValidator ]]; then - wget https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip + wget https://github.com/KhronosGroup/glslang/releases/download/SDK-candidate-26-Jul-2020/glslang-master-linux-Release.zip unzip glslang-master-linux-Release.zip bin/glslangValidator $SU_CMD install -m755 bin/glslangValidator /usr/local/bin/ rm bin/glslangValidator glslang-master-linux-Release.zip diff --git a/src/logging.cpp b/src/logging.cpp index f433dc2a..143801aa 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -119,7 +119,7 @@ void Logger::stop_logging() { m_logging_on = false; m_log_end = Clock::now(); - std::thread(calculate_benchmark_data).detach(); + std::thread(calculate_benchmark_data, m_params).detach(); if(not m_params->output_file.empty()) { m_log_files.emplace_back(m_params->output_file + get_log_suffix()); diff --git a/src/overlay.cpp b/src/overlay.cpp index 2d5e9466..de63a0c1 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -766,6 +766,7 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par #endif if (pressed && (now - logger->last_log_end() > 11s)) { last_f2_press = now; + if (logger->is_active()) { logger->stop_logging(); } else { @@ -826,27 +827,43 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par } } -void calculate_benchmark_data(){ - vector sorted; - sorted = benchmark.fps_data; +void calculate_benchmark_data(void *params_void){ + overlay_params *params = reinterpret_cast(params_void); + + vector sorted = benchmark.fps_data; sort(sorted.begin(), sorted.end()); - // 97th percentile - int index = sorted.size() * 0.97; - benchmark.ninety = sorted[index]; - // avg + benchmark.percentile_data.clear(); + benchmark.total = 0.f; for (auto fps_ : sorted){ benchmark.total = benchmark.total + fps_; } - benchmark.avg = benchmark.total / sorted.size(); - // 1% min - benchmark.total = 0.f; - for (size_t i = 0; i < sorted.size() * 0.01; i++){ - benchmark.total = sorted[i]; + + size_t max_label_size = 0; + + for (std::string percentile : params->benchmark_percentiles) { + float result; + + // special case handling for a mean-based average + if (percentile == "AVG") { + result = benchmark.total / sorted.size(); + } else { + // the percentiles are already validated when they're parsed from the config. + float fraction = parse_float(percentile) / 100; + + result = sorted[(fraction * sorted.size()) - 1]; + percentile += "%"; + } + + if (percentile.length() > max_label_size) + max_label_size = percentile.length(); + + benchmark.percentile_data.push_back({percentile, result}); + } + + for (auto& entry : benchmark.percentile_data) { + entry.first.append(max_label_size - entry.first.length(), ' '); } - benchmark.oneP = benchmark.total; - // 0.1% min - benchmark.pointOneP = sorted[sorted.size() * 0.001]; } void update_hud_info(struct swapchain_stats& sw_stats, struct overlay_params& params, uint32_t vendorID){ @@ -1061,14 +1078,13 @@ static void render_mpris_metadata(struct overlay_params& params, mutexed_metadat void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, unsigned height, Clock::time_point now){ // TODO, FIX LOG_DURATION FOR BENCHMARK - int benchHeight = 6 * params.font_size * params.font_scale + 10.0f + 58; + int benchHeight = (2 + benchmark.percentile_data.size()) * params.font_size + 10.0f + 58; ImGui::SetNextWindowSize(ImVec2(window_size.x, benchHeight), ImGuiCond_Always); if (height - (window_size.y + data.main_window_pos.y + 5) < benchHeight) ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y - benchHeight - 5), ImGuiCond_Always); else ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y + window_size.y + 5), ImGuiCond_Always); - vector> benchmark_data = {{"97% ", benchmark.ninety}, {"AVG ", benchmark.avg}, {"1% ", benchmark.oneP}, {"0.1%", benchmark.pointOneP}}; float display_time = std::chrono::duration(now - logger->last_log_end()).count(); static float display_for = 10.0f; float alpha; @@ -1106,7 +1122,7 @@ void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVe snprintf(duration, sizeof(duration), "Duration: %.1fs", std::chrono::duration(logger->last_log_end() - logger->last_log_begin()).count()); ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(duration).x / 2)); ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s", duration); - for (auto& data_ : benchmark_data){ + for (auto& data_ : benchmark.percentile_data){ char buffer[20]; snprintf(buffer, sizeof(buffer), "%s %.1f", data_.first.c_str(), data_.second); ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(buffer).x / 2)); diff --git a/src/overlay.h b/src/overlay.h index 871c8fcc..9a6b2025 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -69,12 +69,9 @@ struct fps_limit { }; struct benchmark_stats { - float ninety; - float avg; - float oneP; - float pointOneP; float total; std::vector fps_data; + std::vector> percentile_data; }; extern struct fps_limit fps_limit_stats; @@ -91,8 +88,8 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par void init_system_info(void); void FpsLimiter(struct fps_limit& stats); void get_device_name(int32_t vendorID, int32_t deviceID, struct swapchain_stats& sw_stats); -void calculate_benchmark_data(void); +void calculate_benchmark_data(void *params_void); void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font); void convert_colors(bool do_conv, struct swapchain_stats& sw_stats, struct overlay_params& params); -#endif //MANGOHUD_OVERLAY_H +#endif //MANGOHUD_OVERLAY_H \ No newline at end of file diff --git a/src/overlay_params.cpp b/src/overlay_params.cpp index bf1e772b..8c97b0eb 100644 --- a/src/overlay_params.cpp +++ b/src/overlay_params.cpp @@ -209,6 +209,48 @@ parse_media_player_order(const char *str) return order; } + +static std::vector +parse_benchmark_percentiles(const char *str) +{ + std::vector percentiles; + std::stringstream percent_strings(str); + std::string value; + + while (std::getline(percent_strings, value, '+')) { + trim(value); + + if (value == "AVG") { + percentiles.push_back(value); + continue; + } + + float as_float; + size_t float_len = 0; + + try { + as_float = parse_float(value, &float_len); + } catch (const std::invalid_argument&) { + std::cerr << "MANGOHUD: invalid benchmark percentile: '" << value << "'\n"; + continue; + } + + if (float_len != value.length()) { + std::cerr << "MANGOHUD: invalid benchmark percentile: '" << value << "'\n"; + continue; + } + + if (as_float > 100 || as_float < 0) { + std::cerr << "MANGOHUD: benchmark percentile is not between 0 and 100 (" << value << ")\n"; + continue; + } + + percentiles.push_back(value); + } + + return percentiles; +} + static uint32_t parse_font_glyph_ranges(const char *str) { @@ -239,6 +281,7 @@ parse_font_glyph_ranges(const char *str) fg |= FG_LATIN_EXT_B; } return fg; + } #define parse_width(s) parse_unsigned(s) @@ -438,6 +481,7 @@ parse_overlay_config(struct overlay_params *params, params->media_player_order = { MP_ORDER_TITLE, MP_ORDER_ARTIST, MP_ORDER_ALBUM }; params->permit_upload = 0; params->render_mango = 0; + params->benchmark_percentiles = { "97", "AVG", "1", "0.1" }; #ifdef HAVE_X11 params->toggle_hud = { XK_Shift_R, XK_F12 }; diff --git a/src/overlay_params.h b/src/overlay_params.h index 7488136c..3f463800 100644 --- a/src/overlay_params.h +++ b/src/overlay_params.h @@ -97,6 +97,7 @@ typedef unsigned long KeySym; OVERLAY_PARAM_CUSTOM(log_interval) \ OVERLAY_PARAM_CUSTOM(permit_upload) \ OVERLAY_PARAM_CUSTOM(render_mango) \ + OVERLAY_PARAM_CUSTOM(benchmark_percentiles) \ OVERLAY_PARAM_CUSTOM(help) enum overlay_param_position { @@ -174,6 +175,7 @@ struct overlay_params { std::string cpu_text, gpu_text; unsigned log_interval; std::vector media_player_order; + std::vector benchmark_percentiles; std::string font_file, font_file_text; uint32_t font_glyph_ranges;