diff --git a/src/meson.build b/src/meson.build index 394a158f..b1059832 100644 --- a/src/meson.build +++ b/src/meson.build @@ -84,7 +84,8 @@ if is_unixy 'control.cpp', 'device.cpp', 'amdgpu.cpp', - 'intel.cpp' + 'intel.cpp', + 'msm.cpp' ) opengl_files = files( diff --git a/src/msm.cpp b/src/msm.cpp new file mode 100644 index 00000000..c21127f5 --- /dev/null +++ b/src/msm.cpp @@ -0,0 +1,79 @@ +#include +#include +#include + +#include "msm.h" +std::unique_ptr msm; +namespace fs = ghc::filesystem; + +uint64_t MSM::get_gpu_time() { + char line[256]; + uint64_t total_val = 0; + for (auto fd : fdinfo) { + rewind(fd); + fflush(fd); + uint64_t val = 0; + while (fgets(line, sizeof(line), fd)){ + if (sscanf(line, "drm-engine-gpu: %" SCNu64 " ns", &val) == 1) { + total_val += val; + break; + } + } + } + + return total_val; +} + +void MSM::find_fd() { + DIR* dir = opendir("/proc/self/fdinfo"); + if (!dir) { + perror("Failed to open directory"); + } + + for (const auto& entry : fs::directory_iterator("/proc/self/fdinfo")){ + FILE* file = fopen(entry.path().string().c_str(), "r"); + + if (!file) continue; + + char line[256]; + bool found_driver = false; + while (fgets(line, sizeof(line), file)) { + if (strstr(line, "msm") != NULL) + found_driver = true; + + if (found_driver) { + if(strstr(line, "drm-engine-gpu")) { + fdinfo.push_back(file); + break; + } + } + } + + if (!found_driver) + fclose(file); + } + + closedir(dir); +} + +void MSM::get_fdinfo() { + static uint64_t previous_gpu_time, previous_time, now, gpu_time_now; + gpu_time_now = get_gpu_time(); + now = os_time_get_nano(); + + if (previous_time && previous_gpu_time && gpu_time_now > previous_gpu_time){ + float time_since_last = now - previous_time; + float gpu_since_last = gpu_time_now - previous_gpu_time; + auto result = int((gpu_since_last / time_since_last) * 100); + if (result > 100) + result = 100; + + gpu_info_msm.load = result; + previous_gpu_time = gpu_time_now; + previous_time = now; + } else { + previous_gpu_time = gpu_time_now; + previous_time = now; + } +} + diff --git a/src/msm.h b/src/msm.h new file mode 100644 index 00000000..e8c2a1e1 --- /dev/null +++ b/src/msm.h @@ -0,0 +1,34 @@ +#include +#include + +#include "gpu.h" + +class MSM { + private: + struct gpuInfo gpu_info_msm {}; + std::vector fdinfo; + void find_fd(); + uint64_t get_gpu_time(); + void get_fdinfo(); + + public: + MSM() { + find_fd(); + } + + ~MSM() { + for (size_t i = 0; i < fdinfo.size(); i++) { + fclose(fdinfo[i]); + } + fdinfo.clear(); + } + + void update() { + if (!fdinfo.empty()) + get_fdinfo(); + + gpu_info = gpu_info_msm; + } +}; + +extern std::unique_ptr msm; diff --git a/src/overlay.cpp b/src/overlay.cpp index 08f3a1ad..cec8b6cd 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -25,6 +25,7 @@ #include "amdgpu.h" #include "fps_metrics.h" #include "intel.h" +#include "msm.h" #ifdef __linux__ #include @@ -137,6 +138,8 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) #ifdef __linux__ if (vendorID== 0x8086) if (intel) intel->update(); + if (vendorID == 0x5143) + if (msm) msm->update(); #endif } @@ -834,6 +837,19 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para } } + if (vendorID == 0x5143) { + auto dirs = ls(drm.c_str(), "card"); + for (auto& dir : dirs) { + if (dir.find("-") != std::string::npos) { + continue; // filter display adapters + } + path = drm + dir; + drm_dev = dir; + SPDLOG_DEBUG("msm: using drm device {}", drm_dev); + msm = std::make_unique(); + } + } + if (vendorID == 0x1002 || gpu.find("Radeon") != std::string::npos || gpu.find("AMD") != std::string::npos) {