MangoHud/src/nvctrl.cpp

162 lines
4.4 KiB
C++
Raw Normal View History

#include <iostream>
2020-03-20 13:26:37 +00:00
#include <cstring>
#include <sstream>
#include <unordered_map>
#include <memory>
#include <functional>
2020-03-20 11:54:08 +00:00
#include "nvctrl.h"
#include "loaders/loader_nvctrl.h"
#include "loaders/loader_x11.h"
2020-03-20 13:26:37 +00:00
#include "string_utils.h"
2020-05-09 23:36:09 +00:00
#include "overlay.h"
2020-03-20 13:26:37 +00:00
typedef std::unordered_map<std::string, std::string> string_map;
static std::unique_ptr<Display, std::function<void(Display*)>> display;
2020-03-20 11:54:08 +00:00
struct nvctrlInfo nvctrl_info;
bool nvctrlSuccess = false;
static bool find_nv_x11(libnvctrl_loader& nvctrl, Display*& dpy)
{
char buf[8] {};
for (int i = 0; i < 16; i++) {
snprintf(buf, sizeof(buf), ":%d", i);
Display *d = g_x11->XOpenDisplay(buf);
if (d) {
if (nvctrl.XNVCTRLIsNvScreen(d, 0)) {
dpy = d;
std::cerr << "MANGOHUD: XNVCtrl is using display " << buf << std::endl;
return true;
}
g_x11->XCloseDisplay(d);
}
}
return false;
}
2020-03-20 11:54:08 +00:00
bool checkXNVCtrl()
{
if (!g_x11->IsLoaded()) {
std::cerr << "MANGOHUD: XNVCtrl: X11 loader failed to load\n";
return false;
}
auto& nvctrl = get_libnvctrl_loader();
if (!nvctrl.IsLoaded()) {
std::cerr << "MANGOHUD: XNVCtrl loader failed to load\n";
return false;
}
Display *dpy;
nvctrlSuccess = find_nv_x11(nvctrl, dpy);
if (!nvctrlSuccess) {
std::cerr << "MANGOHUD: XNVCtrl didn't find the correct display" << std::endl;
return false;
}
auto local_x11 = g_x11;
display = { dpy,
[local_x11](Display *dpy) {
local_x11->XCloseDisplay(dpy);
}
};
2020-05-09 23:36:09 +00:00
// get device id at init
int64_t pci_id;
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_PCI_ID,
&pci_id);
2020-05-10 00:31:58 +00:00
deviceID = (pci_id & 0xFFFF);
return true;
}
static void parse_token(std::string token, string_map& options) {
2020-03-20 13:26:37 +00:00
std::string param, value;
size_t equal = token.find("=");
if (equal == std::string::npos)
return;
value = token.substr(equal+1);
param = token.substr(0, equal);
trim(param);
trim(value);
//std::cerr << __func__ << ": " << param << "=" << value << std::endl;
if (!param.empty())
options[param] = value;
}
char* get_attr_target_string(libnvctrl_loader& nvctrl, int attr, int target_type, int target_id) {
char* c = nullptr;
if (!nvctrl.XNVCTRLQueryTargetStringAttribute(display.get(), target_type, target_id, 0, attr, &c)) {
std::cerr << "Failed to query attribute '" << attr << "'.\n";
}
return c;
2020-03-20 11:54:08 +00:00
}
void getNvctrlInfo(){
2020-03-20 13:26:37 +00:00
string_map params;
std::string token;
auto& nvctrl = get_libnvctrl_loader();
2020-03-20 11:54:08 +00:00
if (!display)
return;
2020-03-20 13:26:37 +00:00
int enums[] = {
NV_CTRL_STRING_GPU_UTILIZATION,
NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS,
0 // keep null
};
for (size_t i=0; enums[i]; i++) {
char* str = get_attr_target_string(nvctrl, enums[i], NV_CTRL_TARGET_TYPE_GPU, 0);
2020-03-20 13:26:37 +00:00
if (!str)
continue;
std::stringstream ss (str);
while (std::getline(ss, token, ',')) {
parse_token(token, params);
2020-03-20 11:54:08 +00:00
}
2020-03-20 13:26:37 +00:00
free(str);
2020-03-20 11:54:08 +00:00
}
2020-03-20 13:26:37 +00:00
if (!try_stoi(nvctrl_info.load, params["graphics"]))
nvctrl_info.load = 0;
if (!try_stoi(nvctrl_info.CoreClock, params["nvclock"]))
nvctrl_info.CoreClock = 0;
if (!try_stoi(nvctrl_info.MemClock, params["memclock"]))
nvctrl_info.MemClock = 0;
int64_t temp = 0;
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
2020-03-20 11:54:08 +00:00
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_GPU_CORE_TEMPERATURE,
&temp);
nvctrl_info.temp = temp;
2020-03-20 13:26:37 +00:00
int64_t memtotal = 0;
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
2020-03-20 11:54:08 +00:00
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY,
&memtotal);
nvctrl_info.memoryTotal = memtotal;
2020-03-20 13:26:37 +00:00
int64_t memused = 0;
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
2020-03-20 11:54:08 +00:00
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_USED_DEDICATED_GPU_MEMORY,
&memused);
2020-03-20 13:26:37 +00:00
nvctrl_info.memoryUsed = memused;
}