Implement support for Adreno GPUs through the msm kernel interface

Tested in both OpenGL and Vulkan and it gets the GPU load percentage
correctly.
pull/1210/head
Ryan Houdek 4 months ago committed by flightlessmango
parent 511f4fc303
commit 267a431eef

@ -84,7 +84,8 @@ if is_unixy
'control.cpp',
'device.cpp',
'amdgpu.cpp',
'intel.cpp'
'intel.cpp',
'msm.cpp'
)
opengl_files = files(

@ -0,0 +1,79 @@
#include <filesystem.h>
#include <mesa/util/os_time.h>
#include <inttypes.h>
#include "msm.h"
std::unique_ptr<MSM> 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;
}
}

@ -0,0 +1,34 @@
#include <memory>
#include <vector>
#include "gpu.h"
class MSM {
private:
struct gpuInfo gpu_info_msm {};
std::vector<FILE*> 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> msm;

@ -25,6 +25,7 @@
#include "amdgpu.h"
#include "fps_metrics.h"
#include "intel.h"
#include "msm.h"
#ifdef __linux__
#include <libgen.h>
@ -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<MSM>();
}
}
if (vendorID == 0x1002
|| gpu.find("Radeon") != std::string::npos
|| gpu.find("AMD") != std::string::npos) {

Loading…
Cancel
Save