Merge branch 'xnvctrl' into develop

pull/109/head
FlightlessMango 4 years ago
commit c9558eec50

@ -7,18 +7,22 @@ FILE *amdGpuFile = nullptr, *amdTempFile = nullptr, *amdGpuVramTotalFile = nullp
pthread_t cpuThread, gpuThread, cpuInfoThread; pthread_t cpuThread, gpuThread, cpuInfoThread;
void *getNvidiaGpuInfo(void *){ void *getNvidiaGpuInfo(void *){
if (!nvmlSuccess)
checkNvidia();
if (nvmlSuccess){ if (nvmlSuccess){
getNvidiaInfo(); getNVMLInfo();
gpu_info.load = nvidiaUtilization.gpu; gpu_info.load = nvidiaUtilization.gpu;
gpu_info.temp = nvidiaTemp; gpu_info.temp = nvidiaTemp;
gpu_info.memoryUsed = nvidiaMemory.used / (1024.f * 1024.f * 1024.f); gpu_info.memoryUsed = nvidiaMemory.used / (1024.f * 1024.f * 1024.f);
gpu_info.CoreClock = nvidiaCoreClock; gpu_info.CoreClock = nvidiaCoreClock;
gpu_info.MemClock = nvidiaMemClock * 2; gpu_info.MemClock = nvidiaMemClock;
} else if (nvctrlSuccess) {
getNvctrlInfo();
gpu_info.load = nvctrl_info.load;
gpu_info.temp = nvctrl_info.temp;
gpu_info.memoryUsed = nvctrl_info.memoryUsed / (1024.f);
gpu_info.CoreClock = nvctrl_info.CoreClock;
gpu_info.MemClock = nvctrl_info.MemClock;
} }
pthread_detach(gpuThread); pthread_detach(gpuThread);
return NULL; return NULL;
} }

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "nvidia_info.h" #include "nvidia_info.h"
#include "nvctrl.h"
using namespace std; using namespace std;
extern FILE *amdGpuFile, *amdTempFile, *amdGpuVramTotalFile, *amdGpuVramUsedFile, *amdGpuCoreClockFile, *amdGpuMemoryClockFile; extern FILE *amdGpuFile, *amdTempFile, *amdGpuVramTotalFile, *amdGpuVramUsedFile, *amdGpuCoreClockFile, *amdGpuMemoryClockFile;

@ -0,0 +1,95 @@
// This is generated file. Do not modify directly.
// Path to the code generator: /home/crz/git/MangoHud/generate_library_loader.py .
#include "loader_nvctrl.h"
// Put these sanity checks here so that they fire at most once
// (to avoid cluttering the build output).
#if !defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) && !defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED)
#error neither LIBRARY_LOADER_NVCTRL_H_DLOPEN nor LIBRARY_LOADER_NVCTRL_H_DT_NEEDED defined
#endif
#if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) && defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED)
#error both LIBRARY_LOADER_NVCTRL_H_DLOPEN and LIBRARY_LOADER_NVCTRL_H_DT_NEEDED defined
#endif
libnvctrl_loader::libnvctrl_loader() : loaded_(false) {
}
libnvctrl_loader::~libnvctrl_loader() {
CleanUp(loaded_);
}
bool libnvctrl_loader::Load(const std::string& library_name) {
if (loaded_) {
return false;
}
#if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN)
library_ = dlopen(library_name.c_str(), RTLD_LAZY);
if (!library_)
return false;
XNVCTRLIsNvScreen =
reinterpret_cast<decltype(this->XNVCTRLIsNvScreen)>(
dlsym(library_, "XNVCTRLIsNvScreen"));
if (!XNVCTRLIsNvScreen) {
CleanUp(true);
return false;
}
XNVCTRLQueryVersion =
reinterpret_cast<decltype(this->XNVCTRLQueryVersion)>(
dlsym(library_, "XNVCTRLQueryVersion"));
if (!XNVCTRLQueryVersion) {
CleanUp(true);
return false;
}
XNVCTRLQueryAttribute =
reinterpret_cast<decltype(this->XNVCTRLQueryAttribute)>(
dlsym(library_, "XNVCTRLQueryAttribute"));
if (!XNVCTRLQueryAttribute) {
CleanUp(true);
return false;
}
XNVCTRLQueryTargetStringAttribute =
reinterpret_cast<decltype(this->XNVCTRLQueryTargetStringAttribute)>(
dlsym(library_, "XNVCTRLQueryTargetStringAttribute"));
if (!XNVCTRLQueryTargetStringAttribute) {
CleanUp(true);
return false;
}
XNVCTRLQueryTargetAttribute64 =
reinterpret_cast<decltype(this->XNVCTRLQueryTargetAttribute64)>(
dlsym(library_, "XNVCTRLQueryTargetAttribute64"));
if (!XNVCTRLQueryTargetAttribute64) {
CleanUp(true);
return false;
}
#endif
#if defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED)
XNVCTRLQueryVersion = &::XNVCTRLQueryVersion;
XNVCTRLQueryAttribute = &::XNVCTRLQueryAttribute;
#endif
loaded_ = true;
return true;
}
void libnvctrl_loader::CleanUp(bool unload) {
#if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN)
if (unload) {
dlclose(library_);
library_ = NULL;
}
#endif
loaded_ = false;
XNVCTRLQueryVersion = NULL;
XNVCTRLQueryAttribute = NULL;
}

@ -0,0 +1,44 @@
// This is generated file. Do not modify directly.
// Path to the code generator: /home/crz/git/MangoHud/generate_library_loader.py .
#ifndef LIBRARY_LOADER_NVCTRL_H
#define LIBRARY_LOADER_NVCTRL_H
#define Bool bool
#include <X11/Xlib.h>
#include "NVCtrl/NVCtrlLib.h"
#define LIBRARY_LOADER_NVCTRL_H_DLOPEN
#include <string>
#include <dlfcn.h>
class libnvctrl_loader {
public:
libnvctrl_loader();
libnvctrl_loader(const std::string& library_name) { Load(library_name); }
~libnvctrl_loader();
bool Load(const std::string& library_name);
bool IsLoaded() { return loaded_; }
decltype(&::XNVCTRLIsNvScreen) XNVCTRLIsNvScreen;
decltype(&::XNVCTRLQueryVersion) XNVCTRLQueryVersion;
decltype(&::XNVCTRLQueryAttribute) XNVCTRLQueryAttribute;
decltype(&::XNVCTRLQueryTargetStringAttribute) XNVCTRLQueryTargetStringAttribute;
decltype(&::XNVCTRLQueryTargetAttribute64) XNVCTRLQueryTargetAttribute64;
private:
void CleanUp(bool unload);
#if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN)
void* library_;
#endif
bool loaded_;
// Disallow copy constructor and assignment operator.
libnvctrl_loader(const libnvctrl_loader&);
void operator=(const libnvctrl_loader&);
};
#endif // LIBRARY_LOADER_NVCTRL_H

@ -44,6 +44,7 @@ vklayer_files = files(
'font_unispace.c', 'font_unispace.c',
'cpu.cpp', 'cpu.cpp',
'loaders/loader_nvml.cpp', 'loaders/loader_nvml.cpp',
'loaders/loader_nvctrl.cpp',
'nvml.cpp', 'nvml.cpp',
'file_utils.cpp', 'file_utils.cpp',
'memory.cpp', 'memory.cpp',
@ -52,6 +53,7 @@ vklayer_files = files(
'gpu.cpp', 'gpu.cpp',
'notify.cpp', 'notify.cpp',
'elfhacks.cpp', 'elfhacks.cpp',
'nvctrl.cpp',
) )
opengl_files = files( opengl_files = files(

@ -0,0 +1,108 @@
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <unordered_map>
#include "nvctrl.h"
#include "loaders/loader_nvctrl.h"
#include "string_utils.h"
typedef std::unordered_map<std::string, std::string> string_map;
Display *display = XOpenDisplay(NULL);
libnvctrl_loader nvctrl("libXNVCtrl.so");
struct nvctrlInfo nvctrl_info;
bool nvctrlSuccess = false;
bool checkXNVCtrl()
{
if (nvctrl.IsLoaded()) {
nvctrlSuccess = nvctrl.XNVCTRLIsNvScreen(display, 0);
return nvctrlSuccess;
}
return false;
}
void parse_token(std::string token, string_map& options) {
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(int attr, int target_type, int target_id) {
char* c = nullptr;
if (!nvctrl.XNVCTRLQueryTargetStringAttribute(display, target_type, target_id, 0, attr, &c)) {
fprintf(stderr, "Failed to query attribute '%d'.\n", attr);
}
return c;
}
void getNvctrlInfo(){
string_map params;
std::string token;
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(enums[i], NV_CTRL_TARGET_TYPE_GPU, 0);
if (!str)
continue;
std::stringstream ss (str);
while (std::getline(ss, token, ',')) {
parse_token(token, params);
}
free(str);
}
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,
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_GPU_CORE_TEMPERATURE,
&temp);
nvctrl_info.temp = temp;
int64_t memtotal = 0;
nvctrl.XNVCTRLQueryTargetAttribute64(display,
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY,
&memtotal);
nvctrl_info.memoryTotal = memtotal;
int64_t memused = 0;
nvctrl.XNVCTRLQueryTargetAttribute64(display,
NV_CTRL_TARGET_TYPE_GPU,
0,
0,
NV_CTRL_USED_DEDICATED_GPU_MEMORY,
&memused);
nvctrl_info.memoryUsed = memused;
}

@ -0,0 +1,14 @@
struct nvctrlInfo{
int load;
int temp;
float memoryUsed;
float memoryTotal;
int MemClock;
int CoreClock;
};
extern struct nvctrlInfo nvctrl_info;
extern bool nvctrlSuccess;
bool checkXNVCtrl(void);
void getNvctrlInfo(void);
char *get_attr_target_string(int attr, int target_type, int target_id);

@ -9,5 +9,5 @@ extern struct nvmlUtilization_st nvidiaUtilization;
extern struct nvmlMemory_st nvidiaMemory; extern struct nvmlMemory_st nvidiaMemory;
extern bool nvmlSuccess; extern bool nvmlSuccess;
bool checkNvidia(void); bool checkNVML(void);
void getNvidiaInfo(void); void getNVMLInfo(void);

@ -10,7 +10,7 @@ unsigned int nvidiaTemp, nvidiaCoreClock, nvidiaMemClock;
struct nvmlUtilization_st nvidiaUtilization; struct nvmlUtilization_st nvidiaUtilization;
struct nvmlMemory_st nvidiaMemory {}; struct nvmlMemory_st nvidiaMemory {};
bool checkNvidia(){ bool checkNVML(){
if (nvml.IsLoaded()){ if (nvml.IsLoaded()){
result = nvml.nvmlInit(); result = nvml.nvmlInit();
if (NVML_SUCCESS != result) { if (NVML_SUCCESS != result) {
@ -25,11 +25,14 @@ bool checkNvidia(){
return false; return false;
} }
void getNvidiaInfo(){ void getNVMLInfo(){
nvmlReturn_t response;
nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice); nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice);
nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization); response = nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization);
nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp); nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp);
nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory); nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory);
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock);
nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock);
if (response == NVML_ERROR_NOT_SUPPORTED)
nvmlSuccess = false;
} }

@ -782,7 +782,14 @@ void init_gpu_stats(uint32_t& vendorID, overlay_params& params)
// NVIDIA or Intel but maybe has Optimus // NVIDIA or Intel but maybe has Optimus
if (vendorID == 0x8086 if (vendorID == 0x8086
|| vendorID == 0x10de) { || vendorID == 0x10de) {
if ((params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = checkNvidia())) {
if (checkNVML())
getNVMLInfo();
if (!nvmlSuccess)
checkXNVCtrl();
if ((params.enabled[OVERLAY_PARAM_ENABLED_gpu_stats] = (nvmlSuccess || nvctrlSuccess))) {
vendorID = 0x10de; vendorID = 0x10de;
} }
} }

@ -84,7 +84,9 @@ static bool try_stoi(int& val, const std::string& str, std::size_t* pos = 0, int
val = std::stoi(str, pos, base); val = std::stoi(str, pos, base);
return true; return true;
} catch (std::invalid_argument& e) { } catch (std::invalid_argument& e) {
#ifndef NDEBUG
std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl; std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl;
#endif
} }
return false; return false;
} }
@ -95,7 +97,9 @@ static bool try_stoull(unsigned long long& val, const std::string& str, std::siz
val = std::stoull(str, pos, base); val = std::stoull(str, pos, base);
return true; return true;
} catch (std::invalid_argument& e) { } catch (std::invalid_argument& e) {
#ifndef NDEBUG
std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl; std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl;
#endif
} }
return false; return false;
} }

Loading…
Cancel
Save