From 6223a1beb63dfb447b9b0df19fdeab9b0c59c639 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 14 Feb 2023 17:42:11 +0200 Subject: [PATCH 01/31] Add libdrm_amdgpu dependencies Rebase onto master --- meson.build | 2 ++ src/amdgpu_libdrm.cpp | 0 src/amdgpu_libdrm.h | 0 src/meson.build | 23 ++++++++++++++++++++--- 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/amdgpu_libdrm.cpp create mode 100644 src/amdgpu_libdrm.h diff --git a/meson.build b/meson.build index e87bff9784..da7c930b41 100644 --- a/meson.build +++ b/meson.build @@ -88,10 +88,12 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) + libdrm_amdgpu_dep = dependency('drm_amdgpu', required: get_option('with_libdrm_sampling')) else dep_x11 = null_dep dep_wayland_client = null_dep dbus_dep = null_dep + libdrm_amdgpu_dep = null_dep endif if dep_x11.found() diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/meson.build b/src/meson.build index 6849ecbe0d..20a9575f54 100644 --- a/src/meson.build +++ b/src/meson.build @@ -147,6 +147,19 @@ if is_unixy ) endif + if get_option('with_libdrm_sampling').enabled() + libdrm_amdgpu_h_found = cc.has_header('libdrm/amdgpu.h') + if not libdrm_amdgpu_h_found + error('libdrm/amdgpu.h was not found. Disable with \'-Dwith_libdrm_sampling\' if libdrm sampling is not needed (it probably isn\'t)') + endif + + pre_args += '-DHAVE_LIBDRM_SAMPLING' + + vklayer_files += files( + 'amdgpu_libdrm.cpp' + ) + endif + if dbus_dep.found() and get_option('with_dbus').enabled() pre_args += '-DHAVE_DBUS' vklayer_files += files( @@ -187,7 +200,9 @@ mangohud_static_lib = static_library( dep_pthread, dep_vulkan, windows_deps, - json_dep], + json_dep, + libdrm_amdgpu_dep + ], include_directories : [inc_common], link_args : link_args, install_dir : libdir_mangohud, @@ -234,12 +249,13 @@ if get_option('mangoapp') ), c_args : [ pre_args, + no_override_init_args, vulkan_wsi_args - ], + ], cpp_args : [ pre_args, vulkan_wsi_args - ], + ], gnu_symbol_visibility : 'hidden', dependencies : [ dearimgui_dep, @@ -249,6 +265,7 @@ if get_option('mangoapp') dep_x11, glfw3_dep, json_dep, + libdrm_amdgpu_dep ], include_directories : [inc_common], install_tag : 'mangoapp', From c96624737a1e169cab51ba7345ce78204b4634dd Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 01:01:56 +0200 Subject: [PATCH 02/31] Implement basic sampling logic --- src/amdgpu_libdrm.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++ src/amdgpu_libdrm.h | 22 +++++++++++++++++++++ src/overlay.cpp | 5 +++++ 3 files changed, 72 insertions(+) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index e69de29bb2..bf9273a52e 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include "gpu.h" + +#include "amdgpu_libdrm.h" + +std::deque sample_buf(LIBDRM_SAMPLE_BUF_SIZE, {0}); +std::mutex sample_buf_m; + +void libdrm_do_sample(libdrm_sample *sample) { + +} + +void libdrm_thread() { + struct libdrm_sample sample; + libdrm_do_sample(&sample); + + sample_buf_m.lock(); + sample_buf.pop_front(); + sample_buf.push_back(sample); + sample_buf_m.unlock(); + + std::this_thread::sleep_for(std::chrono::milliseconds(LIBDRM_SAMPLE_DELAY)); +} + +void libdrm_get_info() { + static bool init = false; + if (!init) { + std::thread(libdrm_thread).detach(); + init = true; + } + + struct libdrm_stats stats; + + sample_buf_m.lock(); + for (auto sample : sample_buf) { + stats.busy += sample.busy_bit ? 1 : 0; // the ternary is probably not needed + } + sample_buf_m.unlock(); + + gpu_info.load = (int)(((double)stats.busy / LIBDRM_SAMPLE_BUF_SIZE) * 100); +} \ No newline at end of file diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index e69de29bb2..03486dc05a 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -0,0 +1,22 @@ +#pragma once + +#define LIBDRM_SAMPLE_DELAY 5 +#define LIBDRM_SAMPLE_BUF_SIZE 256 + +#define LIBDRM_GRBM_STATUS 0x8010 + +enum LIBDRM_GRBM_BITS { + LIBDRM_GRBM_BUSY_BIT = 1U << 31 +}; + +struct libdrm_sample { + bool busy_bit; +}; + +struct libdrm_stats { + int busy; +}; + +void libdrm_do_sample(); +void libdrm_thread(); +void libdrm_get_info(); diff --git a/src/overlay.cpp b/src/overlay.cpp index 3fca18e7da..4ae7154e5d 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -23,6 +23,7 @@ #include "pci_ids.h" #include "iostats.h" #include "amdgpu.h" +#include "amdgpu_libdrm.h" #ifdef __linux__ @@ -122,6 +123,10 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) if (gpu_metrics_exists) amdgpu_get_metrics(); +#if defined(__linux__) && defined(HAVE_LIBDRM_SAMPLING) + libdrm_get_info(); +#endif + if (vendorID == 0x10de) getNvidiaGpuInfo(params); From fe7e321a43e1a3121d273205dc34ce9d51160b6b Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 13:36:26 +0200 Subject: [PATCH 03/31] Fix buildscript Rebase onto master --- meson.build | 2 +- meson_options.txt | 1 + src/meson.build | 5 ----- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/meson.build b/meson.build index da7c930b41..9117233bfe 100644 --- a/meson.build +++ b/meson.build @@ -88,7 +88,7 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) - libdrm_amdgpu_dep = dependency('drm_amdgpu', required: get_option('with_libdrm_sampling')) + libdrm_amdgpu_dep = cpp.find_library('drm_amdgpu', required: get_option('with_libdrm_sampling')) else dep_x11 = null_dep dep_wayland_client = null_dep diff --git a/meson_options.txt b/meson_options.txt index 4b9778e97c..d2320aa195 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,6 +12,7 @@ option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable option('with_x11', type : 'feature', value : 'enabled') option('with_wayland', type : 'feature', value : 'disabled') option('with_dbus', type : 'feature', value : 'enabled') +option('with_libdrm_sampling', type : 'feature', value : 'enabled') option('loglevel', type: 'combo', choices : ['trace', 'debug', 'info', 'warn', 'err', 'critical', 'off'], value : 'info', description: 'Max log level in non-debug build') option('mangoapp', type: 'boolean', value : false) option('mangohudctl', type: 'boolean', value : false) diff --git a/src/meson.build b/src/meson.build index 20a9575f54..73219b780d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -148,11 +148,6 @@ if is_unixy endif if get_option('with_libdrm_sampling').enabled() - libdrm_amdgpu_h_found = cc.has_header('libdrm/amdgpu.h') - if not libdrm_amdgpu_h_found - error('libdrm/amdgpu.h was not found. Disable with \'-Dwith_libdrm_sampling\' if libdrm sampling is not needed (it probably isn\'t)') - endif - pre_args += '-DHAVE_LIBDRM_SAMPLING' vklayer_files += files( From 19c2cb630cdbbae1c08e438e8fcdd5f1d221c0d5 Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 14:35:45 +0200 Subject: [PATCH 04/31] Finish basic implementation of libdrm sampling --- src/amdgpu_libdrm.cpp | 51 +++++++++++++++++++++++++++++++++++-------- src/amdgpu_libdrm.h | 3 +++ src/overlay.cpp | 6 +++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index bf9273a52e..14d30396a3 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -3,37 +3,54 @@ #include #include #include +#include +#include #include "gpu.h" #include "amdgpu_libdrm.h" +std::string dri_device_path; + std::deque sample_buf(LIBDRM_SAMPLE_BUF_SIZE, {0}); std::mutex sample_buf_m; +amdgpu_device_handle amdgpu_handle; + void libdrm_do_sample(libdrm_sample *sample) { + uint32_t registers; + amdgpu_read_mm_registers(amdgpu_handle, LIBDRM_GRBM_STATUS / 4, 1, 0xffffffff, 0, ®isters); + if (registers & LIBDRM_GRBM_BUSY_BIT) sample->busy_bit = true; } void libdrm_thread() { - struct libdrm_sample sample; - libdrm_do_sample(&sample); - - sample_buf_m.lock(); - sample_buf.pop_front(); - sample_buf.push_back(sample); - sample_buf_m.unlock(); + while (true) { + struct libdrm_sample sample {0}; + libdrm_do_sample(&sample); + + sample_buf_m.lock(); + sample_buf.pop_front(); + sample_buf.push_back(sample); + sample_buf_m.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(LIBDRM_SAMPLE_DELAY)); + std::this_thread::sleep_for(std::chrono::milliseconds(LIBDRM_SAMPLE_DELAY)); + } } void libdrm_get_info() { static bool init = false; if (!init) { + if (libdrm_initialize()) { + // TODO: handle error + SPDLOG_ERROR("Could not initialize libdrm"); + return; + } std::thread(libdrm_thread).detach(); init = true; + SPDLOG_INFO("Initialized libdrm sampling"); } - struct libdrm_stats stats; + struct libdrm_stats stats {0}; sample_buf_m.lock(); for (auto sample : sample_buf) { @@ -42,4 +59,20 @@ void libdrm_get_info() { sample_buf_m.unlock(); gpu_info.load = (int)(((double)stats.busy / LIBDRM_SAMPLE_BUF_SIZE) * 100); +} + +int libdrm_initialize() { + int fd = open(dri_device_path.c_str(), O_RDWR); + if (fd < 0) { + SPDLOG_ERROR("DRI device open failed"); + return -1; + } + + uint32_t libdrm_minor, libdrm_major; + if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { + SPDLOG_ERROR("amdgpu_device_initialize failed"); + return -1; + } + + return 0; } \ No newline at end of file diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index 03486dc05a..335170fc96 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -17,6 +17,9 @@ struct libdrm_stats { int busy; }; +extern std::string dri_device_path; + void libdrm_do_sample(); void libdrm_thread(); void libdrm_get_info(); +int libdrm_initialize(); diff --git a/src/overlay.cpp b/src/overlay.cpp index 4ae7154e5d..02c5dbb829 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -793,6 +793,12 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para break; } +#ifdef HAVE_LIBDRM_SAMPLING + dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); + SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); + // TODO: handle case in which /dev/dri/cardX does not exist +#endif + // don't bother then if (metrics_path.empty() && !amdgpu.busy && vendorID != 0x8086) { params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = false; From 16f65f9020642a319fac5e121a81de7af361eb3f Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 14:43:16 +0200 Subject: [PATCH 05/31] Implemented basic libdrm error handling --- src/amdgpu_libdrm.cpp | 3 ++- src/amdgpu_libdrm.h | 1 + src/overlay.cpp | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 14d30396a3..de356636a2 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -10,6 +10,7 @@ #include "amdgpu_libdrm.h" std::string dri_device_path; +bool libdrm_sampling_possible = true; std::deque sample_buf(LIBDRM_SAMPLE_BUF_SIZE, {0}); std::mutex sample_buf_m; @@ -41,7 +42,7 @@ void libdrm_get_info() { static bool init = false; if (!init) { if (libdrm_initialize()) { - // TODO: handle error + libdrm_sampling_possible = false; SPDLOG_ERROR("Could not initialize libdrm"); return; } diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index 335170fc96..d0dc8fb109 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -18,6 +18,7 @@ struct libdrm_stats { }; extern std::string dri_device_path; +extern bool libdrm_sampling_possible; void libdrm_do_sample(); void libdrm_thread(); diff --git a/src/overlay.cpp b/src/overlay.cpp index 02c5dbb829..cad73b1cfc 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -124,7 +124,8 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) amdgpu_get_metrics(); #if defined(__linux__) && defined(HAVE_LIBDRM_SAMPLING) - libdrm_get_info(); + if (libdrm_sampling_possible) + libdrm_get_info(); #endif if (vendorID == 0x10de) @@ -796,7 +797,6 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para #ifdef HAVE_LIBDRM_SAMPLING dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); - // TODO: handle case in which /dev/dri/cardX does not exist #endif // don't bother then From dfcd0d0ce3b5dad24622a561b59d9c4d933a0ea3 Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 14:54:05 +0200 Subject: [PATCH 06/31] Added 'libdrm_sampling' parameter to toggle libdrm sampling from the config --- src/overlay.cpp | 8 +++++--- src/overlay_params.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/overlay.cpp b/src/overlay.cpp index cad73b1cfc..de5c4e235b 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -124,7 +124,7 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) amdgpu_get_metrics(); #if defined(__linux__) && defined(HAVE_LIBDRM_SAMPLING) - if (libdrm_sampling_possible) + if (params.enabled[OVERLAY_PARAM_ENABLED_libdrm_sampling] && libdrm_sampling_possible) libdrm_get_info(); #endif @@ -795,8 +795,10 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para } #ifdef HAVE_LIBDRM_SAMPLING - dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); - SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); + if (params.enabled[OVERLAY_PARAM_ENABLED_libdrm_sampling]) { + dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); + SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); + } #endif // don't bother then diff --git a/src/overlay_params.h b/src/overlay_params.h index da32af5868..77f86ebdc7 100644 --- a/src/overlay_params.h +++ b/src/overlay_params.h @@ -89,6 +89,7 @@ typedef unsigned long KeySym; OVERLAY_PARAM_BOOL(hud_no_margin) \ OVERLAY_PARAM_BOOL(hud_compact) \ OVERLAY_PARAM_BOOL(exec_name) \ + OVERLAY_PARAM_BOOL(libdrm_sampling) \ OVERLAY_PARAM_CUSTOM(fps_sampling_period) \ OVERLAY_PARAM_CUSTOM(output_folder) \ OVERLAY_PARAM_CUSTOM(output_file) \ From f6033124cb2ae68e0236005fea44b00823f7085a Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 15 Feb 2023 14:58:15 +0200 Subject: [PATCH 07/31] Add 'libdrm_sampling' to the workarounds section in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e1507d715f..7183104ea9 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,7 @@ Options starting with "gl_*" are for OpenGL. - `gl_size_query = viewport` : Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable. - `gl_bind_framebuffer = 0..N` : (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III. - `gl_dont_flip = 1` : Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx. +- `libdrm_sampling` : Use libdrm_amdgpu to calculate GPU utilization. Helps with some problematic Vega GPUs. ## MangoHud FPS logging From 1c01bf92502b1d1dbb2a783098902a8f7c676d30 Mon Sep 17 00:00:00 2001 From: bsolos Date: Fri, 17 Feb 2023 15:37:18 +0200 Subject: [PATCH 08/31] Add '# libdrm_sampling' to MangoHud.conf --- data/MangoHud.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/MangoHud.conf b/data/MangoHud.conf index b4eed108fe..c053669801 100644 --- a/data/MangoHud.conf +++ b/data/MangoHud.conf @@ -215,6 +215,9 @@ frame_timing ### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx # gl_dont_flip=1 +### Use libdrm_amdgpu to calculate GPU utilization. Helps with some problematic Vega GPUs. +# libdrm_sampling + ################ INTERACTION ################# ### Change toggle keybinds for the hud & logging From 9f9869f0663653ac7eb4cac5c4ec679f9f911e5a Mon Sep 17 00:00:00 2001 From: bsolos Date: Fri, 17 Feb 2023 17:43:12 +0200 Subject: [PATCH 09/31] Check for OVERLAY_PARAM_ENABLED_libdrm_sampling only in init_gpu_stats --- src/amdgpu_libdrm.cpp | 4 ++-- src/amdgpu_libdrm.h | 2 +- src/overlay.cpp | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index de356636a2..464f85a174 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -10,7 +10,7 @@ #include "amdgpu_libdrm.h" std::string dri_device_path; -bool libdrm_sampling_possible = true; +bool do_libdrm_sampling = false; std::deque sample_buf(LIBDRM_SAMPLE_BUF_SIZE, {0}); std::mutex sample_buf_m; @@ -42,7 +42,7 @@ void libdrm_get_info() { static bool init = false; if (!init) { if (libdrm_initialize()) { - libdrm_sampling_possible = false; + do_libdrm_sampling = false; SPDLOG_ERROR("Could not initialize libdrm"); return; } diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index d0dc8fb109..60a89be799 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -18,7 +18,7 @@ struct libdrm_stats { }; extern std::string dri_device_path; -extern bool libdrm_sampling_possible; +extern bool do_libdrm_sampling; void libdrm_do_sample(); void libdrm_thread(); diff --git a/src/overlay.cpp b/src/overlay.cpp index de5c4e235b..0849add8a6 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -124,7 +124,7 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) amdgpu_get_metrics(); #if defined(__linux__) && defined(HAVE_LIBDRM_SAMPLING) - if (params.enabled[OVERLAY_PARAM_ENABLED_libdrm_sampling] && libdrm_sampling_possible) + if (do_libdrm_sampling) libdrm_get_info(); #endif @@ -796,6 +796,7 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para #ifdef HAVE_LIBDRM_SAMPLING if (params.enabled[OVERLAY_PARAM_ENABLED_libdrm_sampling]) { + do_libdrm_sampling = true; dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); } From c92c5a402bd1ca624c89a9ce97c61f1b2b297760 Mon Sep 17 00:00:00 2001 From: bsolos Date: Fri, 17 Feb 2023 17:52:12 +0200 Subject: [PATCH 10/31] Only use other GPU load caclculation options if libdrm sampling is disabled/impossible --- src/amdgpu.cpp | 10 +++++++++- src/gpu.cpp | 21 ++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index 865f773110..a144cf1fd2 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -7,6 +7,7 @@ #include "overlay.h" #include "hud_elements.h" #include "logging.h" +#include "amdgpu_libdrm.h" std::string metrics_path = ""; struct amdgpu_common_metrics amdgpu_common_metrics; @@ -171,7 +172,14 @@ void amdgpu_get_metrics(){ } amdgpu_common_metrics_m.lock(); - gpu_info.load = amdgpu_common_metrics.gpu_load_percent; + +#ifdef HAVE_LIBDRM_SAMPLING + if (!do_libdrm_sampling) { +#endif + gpu_info.load = amdgpu_common_metrics.gpu_load_percent; +#ifdef HAVE_LIBDRM_SAMPLING + } +#endif gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w; gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz; diff --git a/src/gpu.cpp b/src/gpu.cpp index 549f6fdf45..b3303adb82 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -7,6 +7,7 @@ #include #include "nvctrl.h" #include "timing.hpp" +#include "amdgpu_libdrm.h" #ifdef HAVE_NVML #include "nvidia_info.h" #endif @@ -74,14 +75,20 @@ nvapi_util(); void getAmdGpuInfo(){ int64_t value = 0; if (metrics_path.empty()){ - if (amdgpu.busy) { - rewind(amdgpu.busy); - fflush(amdgpu.busy); - int value = 0; - if (fscanf(amdgpu.busy, "%d", &value) != 1) - value = 0; - gpu_info.load = value; +#ifdef HAVE_LIBDRM_SAMPLING + if (!do_libdrm_sampling) { +#endif + if (amdgpu.busy) { + rewind(amdgpu.busy); + fflush(amdgpu.busy); + int value = 0; + if (fscanf(amdgpu.busy, "%d", &value) != 1) + value = 0; + gpu_info.load = value; + } +#ifdef HAVE_LIBDRM_SAMPLING } +#endif if (amdgpu.core_clock) { rewind(amdgpu.core_clock); From aeaec2524536b38e98dc63c172c30a4b605b0a34 Mon Sep 17 00:00:00 2001 From: bsolos Date: Sun, 19 Feb 2023 20:29:17 +0200 Subject: [PATCH 11/31] Attempt to stabilize the sampling rate --- src/amdgpu_libdrm.cpp | 8 +++++++- src/amdgpu_libdrm.h | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 464f85a174..01342e34fe 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -26,6 +26,8 @@ void libdrm_do_sample(libdrm_sample *sample) { void libdrm_thread() { while (true) { + auto start_time = std::chrono::system_clock::now().time_since_epoch(); + struct libdrm_sample sample {0}; libdrm_do_sample(&sample); @@ -34,7 +36,11 @@ void libdrm_thread() { sample_buf.push_back(sample); sample_buf_m.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(LIBDRM_SAMPLE_DELAY)); + auto end_time = std::chrono::system_clock::now().time_since_epoch(); + auto sleep_duration = std::chrono::microseconds(LIBDRM_SAMPLE_DELAY) - (end_time - start_time); + if (sleep_duration > std::chrono::nanoseconds(0)) { + std::this_thread::sleep_for(sleep_duration); + } } } diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index 60a89be799..848173480b 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -1,7 +1,7 @@ #pragma once -#define LIBDRM_SAMPLE_DELAY 5 -#define LIBDRM_SAMPLE_BUF_SIZE 256 +#define LIBDRM_SAMPLE_DELAY 3500 +#define LIBDRM_SAMPLE_BUF_SIZE 512 #define LIBDRM_GRBM_STATUS 0x8010 From 4698bc505eb7694d4e0467d976349be74d5c3377 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:05:21 +0200 Subject: [PATCH 12/31] Replaced cpp.find_library('drm_amdgpu',...) with dependency('libdrm_amdgpu',...) --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 9117233bfe..f13d73b77e 100644 --- a/meson.build +++ b/meson.build @@ -88,7 +88,7 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) - libdrm_amdgpu_dep = cpp.find_library('drm_amdgpu', required: get_option('with_libdrm_sampling')) + libdrm_amdgpu_dep = dependency('libdrm_amdgpu', required: get_option('with_libdrm_sampling')) else dep_x11 = null_dep dep_wayland_client = null_dep From 9443da72052f74276dc0dccf8fa7e41be2ec39ae Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:11:11 +0200 Subject: [PATCH 13/31] Unconditionally build with libdrm_sampling --- meson.build | 2 +- meson_options.txt | 1 - src/amdgpu.cpp | 4 ---- src/gpu.cpp | 20 +++++++------------- src/meson.build | 9 +-------- src/overlay.cpp | 4 ---- 6 files changed, 9 insertions(+), 31 deletions(-) diff --git a/meson.build b/meson.build index f13d73b77e..35d25a5ed2 100644 --- a/meson.build +++ b/meson.build @@ -88,7 +88,7 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) - libdrm_amdgpu_dep = dependency('libdrm_amdgpu', required: get_option('with_libdrm_sampling')) + libdrm_amdgpu_dep = dependency('libdrm_amdgpu', required: true) else dep_x11 = null_dep dep_wayland_client = null_dep diff --git a/meson_options.txt b/meson_options.txt index d2320aa195..4b9778e97c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,7 +12,6 @@ option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable option('with_x11', type : 'feature', value : 'enabled') option('with_wayland', type : 'feature', value : 'disabled') option('with_dbus', type : 'feature', value : 'enabled') -option('with_libdrm_sampling', type : 'feature', value : 'enabled') option('loglevel', type: 'combo', choices : ['trace', 'debug', 'info', 'warn', 'err', 'critical', 'off'], value : 'info', description: 'Max log level in non-debug build') option('mangoapp', type: 'boolean', value : false) option('mangohudctl', type: 'boolean', value : false) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index a144cf1fd2..989460be08 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -173,13 +173,9 @@ void amdgpu_get_metrics(){ amdgpu_common_metrics_m.lock(); -#ifdef HAVE_LIBDRM_SAMPLING if (!do_libdrm_sampling) { -#endif gpu_info.load = amdgpu_common_metrics.gpu_load_percent; -#ifdef HAVE_LIBDRM_SAMPLING } -#endif gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w; gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz; diff --git a/src/gpu.cpp b/src/gpu.cpp index b3303adb82..60acdedea6 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -75,20 +75,14 @@ nvapi_util(); void getAmdGpuInfo(){ int64_t value = 0; if (metrics_path.empty()){ -#ifdef HAVE_LIBDRM_SAMPLING - if (!do_libdrm_sampling) { -#endif - if (amdgpu.busy) { - rewind(amdgpu.busy); - fflush(amdgpu.busy); - int value = 0; - if (fscanf(amdgpu.busy, "%d", &value) != 1) - value = 0; - gpu_info.load = value; - } -#ifdef HAVE_LIBDRM_SAMPLING + if (!do_libdrm_sampling && amdgpu.busy) { + rewind(amdgpu.busy); + fflush(amdgpu.busy); + int value = 0; + if (fscanf(amdgpu.busy, "%d", &value) != 1) + value = 0; + gpu_info.load = value; } -#endif if (amdgpu.core_clock) { rewind(amdgpu.core_clock); diff --git a/src/meson.build b/src/meson.build index 73219b780d..304887db7c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -89,6 +89,7 @@ if is_unixy 'battery.cpp', 'control.cpp', 'gamepad.cpp', + 'amdgpu_libdrm.cpp' ) opengl_files = files( @@ -147,14 +148,6 @@ if is_unixy ) endif - if get_option('with_libdrm_sampling').enabled() - pre_args += '-DHAVE_LIBDRM_SAMPLING' - - vklayer_files += files( - 'amdgpu_libdrm.cpp' - ) - endif - if dbus_dep.found() and get_option('with_dbus').enabled() pre_args += '-DHAVE_DBUS' vklayer_files += files( diff --git a/src/overlay.cpp b/src/overlay.cpp index 0849add8a6..43b5d49b20 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -123,10 +123,8 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) if (gpu_metrics_exists) amdgpu_get_metrics(); -#if defined(__linux__) && defined(HAVE_LIBDRM_SAMPLING) if (do_libdrm_sampling) libdrm_get_info(); -#endif if (vendorID == 0x10de) getNvidiaGpuInfo(params); @@ -794,13 +792,11 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para break; } -#ifdef HAVE_LIBDRM_SAMPLING if (params.enabled[OVERLAY_PARAM_ENABLED_libdrm_sampling]) { do_libdrm_sampling = true; dri_device_path = string("/dev/dri") + path.substr(path.find_last_of("/")); SPDLOG_INFO("Using DRI device for libdrm sampling: '{}'", dri_device_path); } -#endif // don't bother then if (metrics_path.empty() && !amdgpu.busy && vendorID != 0x8086) { From 5c7c5b104f4264311204c6ce72adaa525f34a8cf Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:19:06 +0200 Subject: [PATCH 14/31] Remove unnecessary declarations from amdgpu_libdrm.h and mark them as static in the .cpp Rebase onto master --- src/amdgpu_libdrm.cpp | 36 ++++++++++++++++++------------------ src/amdgpu_libdrm.h | 3 --- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 01342e34fe..887d49d5cd 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -17,14 +17,14 @@ std::mutex sample_buf_m; amdgpu_device_handle amdgpu_handle; -void libdrm_do_sample(libdrm_sample *sample) { +static void libdrm_do_sample(libdrm_sample *sample) { uint32_t registers; amdgpu_read_mm_registers(amdgpu_handle, LIBDRM_GRBM_STATUS / 4, 1, 0xffffffff, 0, ®isters); if (registers & LIBDRM_GRBM_BUSY_BIT) sample->busy_bit = true; } -void libdrm_thread() { +static void libdrm_thread() { while (true) { auto start_time = std::chrono::system_clock::now().time_since_epoch(); @@ -44,6 +44,22 @@ void libdrm_thread() { } } +static int libdrm_initialize() { + int fd = open(dri_device_path.c_str(), O_RDWR); + if (fd < 0) { + SPDLOG_ERROR("DRI device open failed"); + return -1; + } + + uint32_t libdrm_minor, libdrm_major; + if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { + SPDLOG_ERROR("amdgpu_device_initialize failed"); + return -1; + } + + return 0; +} + void libdrm_get_info() { static bool init = false; if (!init) { @@ -67,19 +83,3 @@ void libdrm_get_info() { gpu_info.load = (int)(((double)stats.busy / LIBDRM_SAMPLE_BUF_SIZE) * 100); } - -int libdrm_initialize() { - int fd = open(dri_device_path.c_str(), O_RDWR); - if (fd < 0) { - SPDLOG_ERROR("DRI device open failed"); - return -1; - } - - uint32_t libdrm_minor, libdrm_major; - if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { - SPDLOG_ERROR("amdgpu_device_initialize failed"); - return -1; - } - - return 0; -} \ No newline at end of file diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index 848173480b..ed591e8401 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -20,7 +20,4 @@ struct libdrm_stats { extern std::string dri_device_path; extern bool do_libdrm_sampling; -void libdrm_do_sample(); -void libdrm_thread(); void libdrm_get_info(); -int libdrm_initialize(); From 7f8c05cef0ae90162ac85d586d083ae5a7389d58 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:45:36 +0200 Subject: [PATCH 15/31] Remove an unnecessary check in amdgpu_get_metrics --- src/amdgpu.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index 989460be08..0961e12fed 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -173,10 +173,7 @@ void amdgpu_get_metrics(){ amdgpu_common_metrics_m.lock(); - if (!do_libdrm_sampling) { - gpu_info.load = amdgpu_common_metrics.gpu_load_percent; - } - + gpu_info.load = amdgpu_common_metrics.gpu_load_percent; gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w; gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz; gpu_info.MemClock = amdgpu_common_metrics.current_uclk_mhz; From 4e6a492f70c8caf0a52fba877862a70ce1243118 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:47:50 +0200 Subject: [PATCH 16/31] Undo all changes in amdgpu.cpp --- src/amdgpu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index 0961e12fed..31d7accb89 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -7,7 +7,6 @@ #include "overlay.h" #include "hud_elements.h" #include "logging.h" -#include "amdgpu_libdrm.h" std::string metrics_path = ""; struct amdgpu_common_metrics amdgpu_common_metrics; @@ -172,8 +171,8 @@ void amdgpu_get_metrics(){ } amdgpu_common_metrics_m.lock(); - gpu_info.load = amdgpu_common_metrics.gpu_load_percent; + gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w; gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz; gpu_info.MemClock = amdgpu_common_metrics.current_uclk_mhz; From 0bf914e0f98a2c4f6518ef4db698c988438060b7 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 17:59:20 +0200 Subject: [PATCH 17/31] Open the render device node instead of the card node --- meson.build | 2 ++ src/amdgpu_libdrm.cpp | 8 ++++++++ src/meson.build | 2 ++ 3 files changed, 12 insertions(+) diff --git a/meson.build b/meson.build index 35d25a5ed2..2480f24f5d 100644 --- a/meson.build +++ b/meson.build @@ -88,11 +88,13 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) + libdrm_dep = dependency('libdrm', required: true) libdrm_amdgpu_dep = dependency('libdrm_amdgpu', required: true) else dep_x11 = null_dep dep_wayland_client = null_dep dbus_dep = null_dep + libdrm_dep = null_dep libdrm_amdgpu_dep = null_dep endif diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 887d49d5cd..1b56cfc07e 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,13 @@ static int libdrm_initialize() { return -1; } + char *renderD = drmGetRenderDeviceNameFromFd(fd); + fd = open(renderD, O_RDWR); + if (fd < 0) { + SPDLOG_ERROR("Render device open failed"); + return -1; + } + uint32_t libdrm_minor, libdrm_major; if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { SPDLOG_ERROR("amdgpu_device_initialize failed"); diff --git a/src/meson.build b/src/meson.build index 304887db7c..e07e21b443 100644 --- a/src/meson.build +++ b/src/meson.build @@ -189,6 +189,7 @@ mangohud_static_lib = static_library( dep_vulkan, windows_deps, json_dep, + libdrm_dep, libdrm_amdgpu_dep ], include_directories : [inc_common], @@ -253,6 +254,7 @@ if get_option('mangoapp') dep_x11, glfw3_dep, json_dep, + libdrm_dep, libdrm_amdgpu_dep ], include_directories : [inc_common], From 57c4da455af6f362c9480e0ffc5fd93e2eb47169 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 18:55:11 +0200 Subject: [PATCH 18/31] Remove the accidental LF from amdgpu.cpp --- src/amdgpu.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index 31d7accb89..4fe15f64ee 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -172,7 +172,6 @@ void amdgpu_get_metrics(){ amdgpu_common_metrics_m.lock(); gpu_info.load = amdgpu_common_metrics.gpu_load_percent; - gpu_info.powerUsage = amdgpu_common_metrics.average_gfx_power_w; gpu_info.CoreClock = amdgpu_common_metrics.current_gfxclk_mhz; gpu_info.MemClock = amdgpu_common_metrics.current_uclk_mhz; From db32a41e76e3e3e2e8f61c1be7c92486955485e5 Mon Sep 17 00:00:00 2001 From: bsolos Date: Mon, 6 Mar 2023 19:57:07 +0200 Subject: [PATCH 19/31] Use drmGetDevices2 to find the renderD node for the DRI device --- src/amdgpu_libdrm.cpp | 37 +++++++++++++++++++++++++++++++------ src/amdgpu_libdrm.h | 2 ++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 1b56cfc07e..f676a32853 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -46,16 +46,41 @@ static void libdrm_thread() { } static int libdrm_initialize() { - int fd = open(dri_device_path.c_str(), O_RDWR); - if (fd < 0) { - SPDLOG_ERROR("DRI device open failed"); + drmDevicePtr devices[LIBDRM_MAX_DEVICES]; + int device_count = drmGetDevices2(0, devices, LIBDRM_MAX_DEVICES); + if (device_count < 0) { + SPDLOG_ERROR("drmGetDevices2 failed"); + return -1; + } + + char *renderd_node = nullptr; + for (int i = 0; i < device_count; i++) { + bool use_this_device = false; + + for (int j = 0; j < DRM_NODE_MAX; j++) { + if (devices[i]->nodes[j] == dri_device_path) { + use_this_device = true; + } + + if (strstr(devices[i]->nodes[j], "renderD") != NULL) { + renderd_node = devices[i]->nodes[j]; + } + } + + if (use_this_device) { + break; + } + renderd_node = nullptr; + } + + if (renderd_node == nullptr) { + SPDLOG_ERROR("No renderD node found for '{}'", dri_device_path); return -1; } - char *renderD = drmGetRenderDeviceNameFromFd(fd); - fd = open(renderD, O_RDWR); + int fd = open(renderd_node, O_RDWR); if (fd < 0) { - SPDLOG_ERROR("Render device open failed"); + SPDLOG_ERROR("renderD node open failed: '{}'", dri_device_path); return -1; } diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index ed591e8401..82dde75d89 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -1,5 +1,7 @@ #pragma once +#define LIBDRM_MAX_DEVICES 32 + #define LIBDRM_SAMPLE_DELAY 3500 #define LIBDRM_SAMPLE_BUF_SIZE 512 From 7099429ecd4240fe1b388af781a0f516f713b903 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 11:02:20 +0200 Subject: [PATCH 20/31] Find the renderD node more efficiently --- src/amdgpu_libdrm.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index f676a32853..21f8f82058 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -55,22 +55,14 @@ static int libdrm_initialize() { char *renderd_node = nullptr; for (int i = 0; i < device_count; i++) { - bool use_this_device = false; - - for (int j = 0; j < DRM_NODE_MAX; j++) { - if (devices[i]->nodes[j] == dri_device_path) { - use_this_device = true; - } - - if (strstr(devices[i]->nodes[j], "renderD") != NULL) { - renderd_node = devices[i]->nodes[j]; - } + if (!(devices[i]->available_nodes & 0b101)) { + continue; } - if (use_this_device) { + if (devices[i]->nodes[DRM_NODE_PRIMARY] == dri_device_path) { + renderd_node = devices[i]->nodes[DRM_NODE_RENDER]; break; } - renderd_node = nullptr; } if (renderd_node == nullptr) { @@ -90,6 +82,8 @@ static int libdrm_initialize() { return -1; } + + return 0; } From 0ecf9dd8bd94d0483d5955e1420a2a4302713bde Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 11:05:07 +0200 Subject: [PATCH 21/31] Fixed the available_nodes check --- src/amdgpu_libdrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 21f8f82058..8b03c33c84 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -55,7 +55,7 @@ static int libdrm_initialize() { char *renderd_node = nullptr; for (int i = 0; i < device_count; i++) { - if (!(devices[i]->available_nodes & 0b101)) { + if (devices[i]->available_nodes & 0b101 != 0b101) { continue; } From e00678956a64032a7f9b779367bedbeeb6b7f4d2 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 11:07:02 +0200 Subject: [PATCH 22/31] Wrap the & operation in parentheses --- src/amdgpu_libdrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 8b03c33c84..258f255c97 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -55,7 +55,7 @@ static int libdrm_initialize() { char *renderd_node = nullptr; for (int i = 0; i < device_count; i++) { - if (devices[i]->available_nodes & 0b101 != 0b101) { + if ((devices[i]->available_nodes & 0b101) != 0b101) { continue; } From effac716fa7de7ae5d53a964469c382c59f7f467 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 13:15:09 +0200 Subject: [PATCH 23/31] Minor style changes --- src/amdgpu_libdrm.cpp | 2 -- src/meson.build | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 258f255c97..c87ed8f7d4 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -82,8 +82,6 @@ static int libdrm_initialize() { return -1; } - - return 0; } diff --git a/src/meson.build b/src/meson.build index e07e21b443..b7802ac745 100644 --- a/src/meson.build +++ b/src/meson.build @@ -89,7 +89,7 @@ if is_unixy 'battery.cpp', 'control.cpp', 'gamepad.cpp', - 'amdgpu_libdrm.cpp' + 'amdgpu_libdrm.cpp', ) opengl_files = files( @@ -190,7 +190,7 @@ mangohud_static_lib = static_library( windows_deps, json_dep, libdrm_dep, - libdrm_amdgpu_dep + libdrm_amdgpu_dep, ], include_directories : [inc_common], link_args : link_args, @@ -255,7 +255,7 @@ if get_option('mangoapp') glfw3_dep, json_dep, libdrm_dep, - libdrm_amdgpu_dep + libdrm_amdgpu_dep, ], include_directories : [inc_common], install_tag : 'mangoapp', From e8f8bb479c2db2126cd03f13238f6b7543af0bd7 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 13:17:14 +0200 Subject: [PATCH 24/31] Move information used only by amdgpu_libdrm.cpp to the .cpp --- src/amdgpu_libdrm.cpp | 19 +++++++++++++++++++ src/amdgpu_libdrm.h | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index c87ed8f7d4..3c8a15f0ec 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -10,6 +10,25 @@ #include "amdgpu_libdrm.h" +#define LIBDRM_MAX_DEVICES 32 + +#define LIBDRM_SAMPLE_DELAY 3500 +#define LIBDRM_SAMPLE_BUF_SIZE 512 + +#define LIBDRM_GRBM_STATUS 0x8010 + +enum LIBDRM_GRBM_BITS { + LIBDRM_GRBM_BUSY_BIT = 1U << 31 +}; + +struct libdrm_sample { + bool busy_bit; +}; + +struct libdrm_stats { + int busy; +}; + std::string dri_device_path; bool do_libdrm_sampling = false; diff --git a/src/amdgpu_libdrm.h b/src/amdgpu_libdrm.h index 82dde75d89..aad4bf855a 100644 --- a/src/amdgpu_libdrm.h +++ b/src/amdgpu_libdrm.h @@ -1,24 +1,5 @@ #pragma once -#define LIBDRM_MAX_DEVICES 32 - -#define LIBDRM_SAMPLE_DELAY 3500 -#define LIBDRM_SAMPLE_BUF_SIZE 512 - -#define LIBDRM_GRBM_STATUS 0x8010 - -enum LIBDRM_GRBM_BITS { - LIBDRM_GRBM_BUSY_BIT = 1U << 31 -}; - -struct libdrm_sample { - bool busy_bit; -}; - -struct libdrm_stats { - int busy; -}; - extern std::string dri_device_path; extern bool do_libdrm_sampling; From 4f2d394a9565c0f7ca51b6175c2b2bfdbc4742f6 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 13:47:27 +0200 Subject: [PATCH 25/31] Free resources on error in libdrm_initialize --- src/amdgpu_libdrm.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 3c8a15f0ec..afc6498bf0 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "gpu.h" #include "amdgpu_libdrm.h" @@ -86,18 +87,22 @@ static int libdrm_initialize() { if (renderd_node == nullptr) { SPDLOG_ERROR("No renderD node found for '{}'", dri_device_path); + drmFreeDevices(devices, device_count); return -1; } int fd = open(renderd_node, O_RDWR); if (fd < 0) { SPDLOG_ERROR("renderD node open failed: '{}'", dri_device_path); + drmFreeDevices(devices, device_count); return -1; } uint32_t libdrm_minor, libdrm_major; if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { SPDLOG_ERROR("amdgpu_device_initialize failed"); + drmFreeDevices(devices, device_count); + close(fd); return -1; } From 42a92c7d71711dc2d1ae40e83d0dee824db2ab97 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 13:50:39 +0200 Subject: [PATCH 26/31] Remove redundant 'required: true' from meson.build --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 2480f24f5d..2b18b96f97 100644 --- a/meson.build +++ b/meson.build @@ -88,8 +88,8 @@ if is_unixy dep_wayland_client = dependency('wayland-client', required: get_option('with_wayland'), version : '>=1.11') dbus_dep = dependency('dbus-1', required: get_option('with_dbus')).partial_dependency(compile_args : true, includes : true) - libdrm_dep = dependency('libdrm', required: true) - libdrm_amdgpu_dep = dependency('libdrm_amdgpu', required: true) + libdrm_dep = dependency('libdrm') + libdrm_amdgpu_dep = dependency('libdrm_amdgpu') else dep_x11 = null_dep dep_wayland_client = null_dep From 00a203dff131187bdbf8a226b194455c36bfda34 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 14:46:13 +0200 Subject: [PATCH 27/31] Make the renderd_node search code more readable --- src/amdgpu_libdrm.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index afc6498bf0..17d0035339 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -75,7 +75,8 @@ static int libdrm_initialize() { char *renderd_node = nullptr; for (int i = 0; i < device_count; i++) { - if ((devices[i]->available_nodes & 0b101) != 0b101) { + constexpr int required_nodes = (1 << DRM_NODE_PRIMARY) | (1 << DRM_NODE_RENDER); + if ((devices[i]->available_nodes & required_nodes) != required_nodes) { continue; } From 17c920fc90cb2e5e6158573310627d1d5c2ac980 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 15:26:34 +0200 Subject: [PATCH 28/31] Rename 'amdgpu.(cpp|h)' to 'amdgpu_metrics.(cpp|h)' --- src/{amdgpu.cpp => amdgpu_metrics.cpp} | 2 +- src/{amdgpu.h => amdgpu_metrics.h} | 0 src/gpu.cpp | 2 +- src/meson.build | 2 +- src/overlay.cpp | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename src/{amdgpu.cpp => amdgpu_metrics.cpp} (99%) rename src/{amdgpu.h => amdgpu_metrics.h} (100%) diff --git a/src/amdgpu.cpp b/src/amdgpu_metrics.cpp similarity index 99% rename from src/amdgpu.cpp rename to src/amdgpu_metrics.cpp index 4fe15f64ee..2d2a5c519c 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu_metrics.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "amdgpu.h" +#include "amdgpu_metrics.h" #include "gpu.h" #include "cpu.h" #include "overlay.h" diff --git a/src/amdgpu.h b/src/amdgpu_metrics.h similarity index 100% rename from src/amdgpu.h rename to src/amdgpu_metrics.h diff --git a/src/gpu.cpp b/src/gpu.cpp index 60acdedea6..957ce70d41 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -12,7 +12,7 @@ #include "nvidia_info.h" #endif -#include "amdgpu.h" +#include "amdgpu_metrics.h" using namespace std::chrono_literals; diff --git a/src/meson.build b/src/meson.build index b7802ac745..e448bc7dbd 100644 --- a/src/meson.build +++ b/src/meson.build @@ -59,7 +59,7 @@ vklayer_files = files( 'vulkan.cpp', 'blacklist.cpp', 'file_utils.cpp', - 'amdgpu.cpp', + 'amdgpu_metrics.cpp', 'intel.cpp' ) opengl_files = [] diff --git a/src/overlay.cpp b/src/overlay.cpp index 43b5d49b20..bcee4d3c01 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -22,7 +22,7 @@ #include "file_utils.h" #include "pci_ids.h" #include "iostats.h" -#include "amdgpu.h" +#include "amdgpu_metrics.h" #include "amdgpu_libdrm.h" From bf4ee876501c3a6191e5354aca520f2baa4cde50 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 15:27:43 +0200 Subject: [PATCH 29/31] Drop 'libdrm/' from the include --- src/amdgpu_libdrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 17d0035339..4044d027bb 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include From cb54fbe278342c95a80e262ae7fb2b4545219406 Mon Sep 17 00:00:00 2001 From: bsolos Date: Tue, 7 Mar 2023 18:36:50 +0200 Subject: [PATCH 30/31] Resolve some rebasing artifacts --- src/meson.build | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/meson.build b/src/meson.build index e448bc7dbd..73fee49c8e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -238,13 +238,12 @@ if get_option('mangoapp') ), c_args : [ pre_args, - no_override_init_args, vulkan_wsi_args - ], + ], cpp_args : [ pre_args, vulkan_wsi_args - ], + ], gnu_symbol_visibility : 'hidden', dependencies : [ dearimgui_dep, From 8adaf7a5821d35388b6a5843eb61c88961f78485 Mon Sep 17 00:00:00 2001 From: bsolos Date: Wed, 8 Mar 2023 15:57:50 +0200 Subject: [PATCH 31/31] Do cleanup properly in libdrm_initialize --- src/amdgpu_libdrm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/amdgpu_libdrm.cpp b/src/amdgpu_libdrm.cpp index 4044d027bb..bb6b551a15 100644 --- a/src/amdgpu_libdrm.cpp +++ b/src/amdgpu_libdrm.cpp @@ -93,20 +93,20 @@ static int libdrm_initialize() { } int fd = open(renderd_node, O_RDWR); + drmFreeDevices(devices, device_count); if (fd < 0) { SPDLOG_ERROR("renderD node open failed: '{}'", dri_device_path); - drmFreeDevices(devices, device_count); return -1; } uint32_t libdrm_minor, libdrm_major; if (amdgpu_device_initialize(fd, &libdrm_major, &libdrm_minor, &amdgpu_handle)) { SPDLOG_ERROR("amdgpu_device_initialize failed"); - drmFreeDevices(devices, device_count); close(fd); return -1; } + close(fd); // amdgpu_device_initialize should F_DUPFD it internally, so there is no need to keep fd open return 0; }