Skip to content

Commit

Permalink
Allow to specify gpu with pci bus id by setting env var `MANGOHUD_PCI…
Browse files Browse the repository at this point in the history
…_DEV=xxxx:xx:xx:x` where x's are "domain:bus:slot.function"
  • Loading branch information
jackun committed Apr 10, 2020
1 parent e5a256b commit a9311bb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 38 deletions.
9 changes: 7 additions & 2 deletions src/file_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,18 @@ bool dir_exists(const std::string& path)
return !stat(path.c_str(), &s) && S_ISDIR(s.st_mode);
}

std::string get_exe_path()
std::string readlink(const char * link)
{
char result[PATH_MAX] {};
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
ssize_t count = readlink(link, result, PATH_MAX);
return std::string(result, (count > 0) ? count : 0);
}

std::string get_exe_path()
{
return readlink("/proc/self/exe");
}

bool get_wine_exe_name(std::string& name, bool keep_ext)
{
std::string line;
Expand Down
1 change: 1 addition & 0 deletions src/file_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ bool find_folder(const std::string& root, const std::string& prefix, std::string
std::vector<std::string> ls(const char* root, const char* prefix = nullptr, LS_FLAGS flags = LS_DIRS);
bool file_exists(const std::string& path);
bool dir_exists(const std::string& path);
std::string readlink(const char * link);
std::string get_exe_path();
bool get_wine_exe_name(std::string& name, bool keep_ext = false);
std::string get_home_dir();
Expand Down
6 changes: 2 additions & 4 deletions src/nvidia_info.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <stdbool.h>
#include <stdio.h>
#include <nvml.h>

extern nvmlReturn_t result;
Expand All @@ -9,5 +7,5 @@ extern struct nvmlUtilization_st nvidiaUtilization;
extern struct nvmlMemory_st nvidiaMemory;
extern bool nvmlSuccess;

bool checkNVML(void);
bool getNVMLInfo(void);
bool checkNVML(const char* pciBusId);
bool getNVMLInfo(void);
21 changes: 15 additions & 6 deletions src/nvml.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "loaders/loader_nvml.h"
#include "nvidia_info.h"
#include <iostream>

libnvml_loader nvml("libnvidia-ml.so.1");

Expand All @@ -10,24 +11,32 @@ unsigned int nvidiaTemp, nvidiaCoreClock, nvidiaMemClock;
struct nvmlUtilization_st nvidiaUtilization;
struct nvmlMemory_st nvidiaMemory {};

bool checkNVML(){
bool checkNVML(const char* pciBusId){
if (nvml.IsLoaded()){
result = nvml.nvmlInit();
if (NVML_SUCCESS != result) {
printf("MANGOHUD: Nvidia module not loaded\n");
std::cerr << "MANGOHUD: Nvidia module not loaded\n";
} else {
nvmlSuccess = true;
return true;
nvmlReturn_t ret = NVML_ERROR_UNKNOWN;
if (pciBusId)
ret = nvml.nvmlDeviceGetHandleByPciBusId(pciBusId, &nvidiaDevice);

if (ret != NVML_SUCCESS) {
std::cerr << "MANGOHUD: Getting handle by PCI bus ID failed! Using index 0.\n";
ret = nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice);
}

nvmlSuccess = (ret == NVML_SUCCESS);
return nvmlSuccess;
}
} else {
printf("Failed to load NVML!\n");
std::cerr << "MANGOHUD: Failed to load NVML\n";
}
return false;
}

bool getNVMLInfo(){
nvmlReturn_t response;
nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice);
response = nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization);
nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp);
nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory);
Expand Down
83 changes: 57 additions & 26 deletions src/overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,16 +706,39 @@ void init_cpu_stats(overlay_params& params)
&& enabled[OVERLAY_PARAM_ENABLED_cpu_temp];
}

struct PCI_BUS {
int domain;
int bus;
int slot;
int func;
};

void init_gpu_stats(uint32_t& vendorID, overlay_params& params)
{
if (!params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats])
return;

PCI_BUS pci;
bool pci_bus_parsed = false;
const char* env_pci_dev = getenv("MANGOHUD_PCI_DEV");

// for now just checks if pci bus parses correctly, if at all necessary
if (env_pci_dev) {
if (sscanf(env_pci_dev, "%04x:%02x:%02x.%x",
&pci.domain, &pci.bus,
&pci.slot, &pci.func) == 4) {
pci_bus_parsed = true;
} else {
std::cerr << "MANGOHUD: Failed to parse PCI device ID: " << env_pci_dev << "\n";
std::cerr << "MANGOHUD: It has to be formatted as 'xxxx:xx:xx.x' (domain:bus:slot.func)\n";
}
}

// NVIDIA or Intel but maybe has Optimus
if (vendorID == 0x8086
|| vendorID == 0x10de) {

bool nvSuccess = (checkNVML() && getNVMLInfo());
bool nvSuccess = (checkNVML(env_pci_dev) && getNVMLInfo());

#ifdef HAVE_XNVCTRL
if (!nvSuccess)
Expand Down Expand Up @@ -743,37 +766,45 @@ void init_gpu_stats(uint32_t& vendorID, overlay_params& params)

string line = read_line(path + "/device/vendor");
trim(line);
if (line != "0x1002")
if (line != "0x1002" || !file_exists(path + "/device/gpu_busy_percent"))
continue;

path += "/device";
if (pci_bus_parsed && env_pci_dev) {
string pci_device = readlink(path.c_str());
#ifndef NDEBUG
std::cerr << "PCI device symlink: " << pci_device << "\n";
#endif
if (!ends_with(pci_device, env_pci_dev)) {
std::cerr << "MANGOHUD: skipping GPU, no PCI ID match\n";
continue;
}
}

#ifndef NDEBUG
std::cerr << "using amdgpu path: " << path << std::endl;
#endif

if (file_exists(path + "/device/gpu_busy_percent")) {
if (!amdGpuFile)
amdGpuFile = fopen((path + "/device/gpu_busy_percent").c_str(), "r");
if (!amdGpuVramTotalFile)
amdGpuVramTotalFile = fopen((path + "/device/mem_info_vram_total").c_str(), "r");
if (!amdGpuVramUsedFile)
amdGpuVramUsedFile = fopen((path + "/device/mem_info_vram_used").c_str(), "r");

path = path + "/device/hwmon/";
string tempFolder;
if (find_folder(path, "hwmon", tempFolder)) {
if (!amdGpuCoreClockFile)
amdGpuCoreClockFile = fopen((path + tempFolder + "/freq1_input").c_str(), "r");
if (!amdGpuMemoryClockFile)
amdGpuMemoryClockFile = fopen((path + tempFolder + "/freq2_input").c_str(), "r");
path = path + tempFolder + "/temp1_input";

if (!amdTempFile)
amdTempFile = fopen(path.c_str(), "r");

params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = true;
vendorID = 0x1002;
break;
}
if (!amdGpuFile)
amdGpuFile = fopen((path + "/gpu_busy_percent").c_str(), "r");
if (!amdGpuVramTotalFile)
amdGpuVramTotalFile = fopen((path + "/mem_info_vram_total").c_str(), "r");
if (!amdGpuVramUsedFile)
amdGpuVramUsedFile = fopen((path + "/mem_info_vram_used").c_str(), "r");

path += "/hwmon/";
string tempFolder;
if (find_folder(path, "hwmon", tempFolder)) {
if (!amdGpuCoreClockFile)
amdGpuCoreClockFile = fopen((path + tempFolder + "/freq1_input").c_str(), "r");
if (!amdGpuMemoryClockFile)
amdGpuMemoryClockFile = fopen((path + tempFolder + "/freq2_input").c_str(), "r");
if (!amdTempFile)
amdTempFile = fopen((path + tempFolder + "/temp1_input").c_str(), "r");

params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = true;
vendorID = 0x1002;
break;
}
}

Expand Down

0 comments on commit a9311bb

Please sign in to comment.