From 8ee0ec2c3f5f9caa263c4fca6d7350db300bd8b6 Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 12:53:43 +0100 Subject: [PATCH 01/10] NVCtrl loader --- src/loaders/loader_nvctrl.cpp | 88 +++++++++++++++++++++++++++++++++++ src/loaders/loader_nvctrl.h | 43 +++++++++++++++++ src/meson.build | 1 + 3 files changed, 132 insertions(+) create mode 100644 src/loaders/loader_nvctrl.cpp create mode 100644 src/loaders/loader_nvctrl.h diff --git a/src/loaders/loader_nvctrl.cpp b/src/loaders/loader_nvctrl.cpp new file mode 100644 index 00000000..6194fb21 --- /dev/null +++ b/src/loaders/loader_nvctrl.cpp @@ -0,0 +1,88 @@ +// 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; + + + XNVCTRLQueryVersion = + reinterpret_castXNVCTRLQueryVersion)>( + dlsym(library_, "XNVCTRLQueryVersion")); + if (!XNVCTRLQueryVersion) { + CleanUp(true); + return false; + } + + XNVCTRLQueryAttribute = + reinterpret_castXNVCTRLQueryAttribute)>( + dlsym(library_, "XNVCTRLQueryAttribute")); + if (!XNVCTRLQueryAttribute) { + CleanUp(true); + return false; + } + + XNVCTRLQueryTargetStringAttribute = + reinterpret_castXNVCTRLQueryTargetStringAttribute)>( + dlsym(library_, "XNVCTRLQueryTargetStringAttribute")); + if (!XNVCTRLQueryTargetStringAttribute) { + CleanUp(true); + return false; + } + + XNVCTRLQueryTargetAttribute = + reinterpret_castXNVCTRLQueryTargetAttribute)>( + dlsym(library_, "XNVCTRLQueryTargetAttribute")); + if (!XNVCTRLQueryTargetAttribute) { + 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; + +} diff --git a/src/loaders/loader_nvctrl.h b/src/loaders/loader_nvctrl.h new file mode 100644 index 00000000..ea833e67 --- /dev/null +++ b/src/loaders/loader_nvctrl.h @@ -0,0 +1,43 @@ +// 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 +#include "NVCtrl/NVCtrlLib.h" +#define LIBRARY_LOADER_NVCTRL_H_DLOPEN + + +#include +#include + +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(&::XNVCTRLQueryVersion) XNVCTRLQueryVersion; + decltype(&::XNVCTRLQueryAttribute) XNVCTRLQueryAttribute; + decltype(&::XNVCTRLQueryTargetStringAttribute) XNVCTRLQueryTargetStringAttribute; + decltype(&::XNVCTRLQueryTargetAttribute) XNVCTRLQueryTargetAttribute; + + 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 diff --git a/src/meson.build b/src/meson.build index 157a7dc1..7c2aba28 100644 --- a/src/meson.build +++ b/src/meson.build @@ -44,6 +44,7 @@ vklayer_files = files( 'font_unispace.c', 'cpu.cpp', 'loaders/loader_nvml.cpp', + 'loaders/loader_nvctrl.cpp', 'nvml.cpp', 'file_utils.cpp', 'memory.cpp', From aaaf30b807f09d24250069fb622aaf904fa542ae Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 12:54:08 +0100 Subject: [PATCH 02/10] NVctrl fetching --- src/nvctrl.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/nvctrl.h | 12 ++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/nvctrl.cpp create mode 100644 src/nvctrl.h diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp new file mode 100644 index 00000000..63806906 --- /dev/null +++ b/src/nvctrl.cpp @@ -0,0 +1,81 @@ +#include +#include +#include "nvctrl.h" +#include "loaders/loader_nvctrl.h" +#include + +Display *display = XOpenDisplay(NULL); +libnvctrl_loader nvctrl("libXNVCtrl.so"); + +struct nvctrlInfo nvctrl_info; + +char* get_attr_target_string(int attr, int target_type, int target_id) { + char* c; + + if (!nvctrl.XNVCTRLQueryTargetStringAttribute(display, target_type, target_id, 0, attr, &c)) { + fprintf(stderr, "Failed to query attribute."); + + } + return c; +} + +void getNvctrlInfo(){ + char* utilization = get_attr_target_string(NV_CTRL_STRING_GPU_UTILIZATION, NV_CTRL_TARGET_TYPE_GPU, 0); + char* s = utilization; + strtok(s, ","); + while (s != NULL) + { + std::string str = s; + if (str.find("graphics") != std::string::npos){ + str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); + nvctrl_info.load = std::stoi(str); + } + s = strtok (NULL, ","); + } + + char* freq = get_attr_target_string(NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, NV_CTRL_TARGET_TYPE_GPU, 0); + char* freq_str = freq; + strtok(freq_str, ","); + while (freq_str != NULL) + { + std::string str = freq_str; + if (str.find("nvclock=") != std::string::npos){ + str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); + nvctrl_info.CoreClock = std::stoi(str); + } + if (str.find("memclock=") != std::string::npos){ + str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); + nvctrl_info.MemClock = std::stoi(str); + } + freq_str = strtok (NULL, ","); + } + printf("coreclock: %i\n", nvctrl_info.CoreClock); + printf("memclock: %i\n", nvctrl_info.MemClock); + + int temp; + nvctrl.XNVCTRLQueryTargetAttribute(display, + NV_CTRL_TARGET_TYPE_GPU, + 0, + 0, + NV_CTRL_GPU_CORE_TEMPERATURE, + &temp); + nvctrl_info.temp = temp; + + int memtotal; + nvctrl.XNVCTRLQueryTargetAttribute(display, + NV_CTRL_TARGET_TYPE_GPU, + 0, + 0, + NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, + &memtotal); + nvctrl_info.memoryTotal = memtotal; + + int memused; + nvctrl.XNVCTRLQueryTargetAttribute(display, + NV_CTRL_TARGET_TYPE_GPU, + 0, + 0, + NV_CTRL_USED_DEDICATED_GPU_MEMORY, + &memused); + nvctrl_info.memoryUsed = memused; +} \ No newline at end of file diff --git a/src/nvctrl.h b/src/nvctrl.h new file mode 100644 index 00000000..6aee9df4 --- /dev/null +++ b/src/nvctrl.h @@ -0,0 +1,12 @@ +struct nvctrlInfo{ + int load; + int temp; + float memoryUsed; + float memoryTotal; + int MemClock; + int CoreClock; +}; + +extern struct nvctrlInfo nvctrl_info; +void getNvctrlInfo(void); +char *get_attr_target_string(int attr, int target_type, int target_id); \ No newline at end of file From f81af99ee5f8676947229152c6e3826df8d908cc Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 12:54:20 +0100 Subject: [PATCH 03/10] NVCtrl meson build --- src/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meson.build b/src/meson.build index 7c2aba28..48528f72 100644 --- a/src/meson.build +++ b/src/meson.build @@ -53,6 +53,7 @@ vklayer_files = files( 'gpu.cpp', 'notify.cpp', 'elfhacks.cpp', + 'nvctrl.cpp', ) opengl_files = files( From e7b5a18d87aaa40447634939bd73654d6c6b805d Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 12:54:54 +0100 Subject: [PATCH 04/10] If NVML fails fallback to NVctrl --- src/gpu.cpp | 14 +++++++++----- src/gpu.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gpu.cpp b/src/gpu.cpp index 3faaf602..5d9de921 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -7,18 +7,22 @@ FILE *amdGpuFile = nullptr, *amdTempFile = nullptr, *amdGpuVramTotalFile = nullp pthread_t cpuThread, gpuThread, cpuInfoThread; void *getNvidiaGpuInfo(void *){ - if (!nvmlSuccess) - checkNvidia(); - if (nvmlSuccess){ getNvidiaInfo(); gpu_info.load = nvidiaUtilization.gpu; gpu_info.temp = nvidiaTemp; gpu_info.memoryUsed = nvidiaMemory.used / (1024.f * 1024.f * 1024.f); gpu_info.CoreClock = nvidiaCoreClock; - gpu_info.MemClock = nvidiaMemClock * 2; + gpu_info.MemClock = nvidiaMemClock; + } else { + 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); return NULL; } diff --git a/src/gpu.h b/src/gpu.h index 1d10df4c..47ee7bb3 100644 --- a/src/gpu.h +++ b/src/gpu.h @@ -3,6 +3,7 @@ #include #include #include "nvidia_info.h" +#include "nvctrl.h" using namespace std; extern FILE *amdGpuFile, *amdTempFile, *amdGpuVramTotalFile, *amdGpuVramUsedFile, *amdGpuCoreClockFile, *amdGpuMemoryClockFile; From 2c979e52e6390b988aa4da228ea3f9ca140a3d98 Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 13:06:24 +0100 Subject: [PATCH 05/10] Set nvmlSuccess to false if NVML gpu load is unsupported --- src/nvml.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nvml.cpp b/src/nvml.cpp index 7ff8a655..79bd90c2 100644 --- a/src/nvml.cpp +++ b/src/nvml.cpp @@ -26,10 +26,13 @@ bool checkNvidia(){ } void getNvidiaInfo(){ + nvmlReturn_t response; nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice); - nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization); + response = nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization); nvml.nvmlDeviceGetTemperature(nvidiaDevice, NVML_TEMPERATURE_GPU, &nvidiaTemp); nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock); + if (response == 3) + nvmlSuccess = false; } \ No newline at end of file From f2b770abac56bc4025a5cae4b0dd5e273383e18f Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 13:23:24 +0100 Subject: [PATCH 06/10] Use XNVCTRLQueryTargetAttribute64 instead --- src/loaders/loader_nvctrl.cpp | 8 ++++---- src/loaders/loader_nvctrl.h | 2 +- src/nvctrl.cpp | 17 ++++++++++------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/loaders/loader_nvctrl.cpp b/src/loaders/loader_nvctrl.cpp index 6194fb21..97a771f2 100644 --- a/src/loaders/loader_nvctrl.cpp +++ b/src/loaders/loader_nvctrl.cpp @@ -54,10 +54,10 @@ bool libnvctrl_loader::Load(const std::string& library_name) { return false; } - XNVCTRLQueryTargetAttribute = - reinterpret_castXNVCTRLQueryTargetAttribute)>( - dlsym(library_, "XNVCTRLQueryTargetAttribute")); - if (!XNVCTRLQueryTargetAttribute) { + XNVCTRLQueryTargetAttribute64 = + reinterpret_castXNVCTRLQueryTargetAttribute64)>( + dlsym(library_, "XNVCTRLQueryTargetAttribute64")); + if (!XNVCTRLQueryTargetAttribute64) { CleanUp(true); return false; } diff --git a/src/loaders/loader_nvctrl.h b/src/loaders/loader_nvctrl.h index ea833e67..f365ef70 100644 --- a/src/loaders/loader_nvctrl.h +++ b/src/loaders/loader_nvctrl.h @@ -24,7 +24,7 @@ class libnvctrl_loader { decltype(&::XNVCTRLQueryVersion) XNVCTRLQueryVersion; decltype(&::XNVCTRLQueryAttribute) XNVCTRLQueryAttribute; decltype(&::XNVCTRLQueryTargetStringAttribute) XNVCTRLQueryTargetStringAttribute; - decltype(&::XNVCTRLQueryTargetAttribute) XNVCTRLQueryTargetAttribute; + decltype(&::XNVCTRLQueryTargetAttribute64) XNVCTRLQueryTargetAttribute64; private: void CleanUp(bool unload); diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp index 63806906..c3c7250f 100644 --- a/src/nvctrl.cpp +++ b/src/nvctrl.cpp @@ -52,8 +52,8 @@ void getNvctrlInfo(){ printf("coreclock: %i\n", nvctrl_info.CoreClock); printf("memclock: %i\n", nvctrl_info.MemClock); - int temp; - nvctrl.XNVCTRLQueryTargetAttribute(display, + int64_t temp; + nvctrl.XNVCTRLQueryTargetAttribute64(display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, @@ -61,8 +61,8 @@ void getNvctrlInfo(){ &temp); nvctrl_info.temp = temp; - int memtotal; - nvctrl.XNVCTRLQueryTargetAttribute(display, + int64_t memtotal; + nvctrl.XNVCTRLQueryTargetAttribute64(display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, @@ -70,12 +70,15 @@ void getNvctrlInfo(){ &memtotal); nvctrl_info.memoryTotal = memtotal; - int memused; - nvctrl.XNVCTRLQueryTargetAttribute(display, + int64_t memused; + nvctrl.XNVCTRLQueryTargetAttribute64(display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, NV_CTRL_USED_DEDICATED_GPU_MEMORY, &memused); - nvctrl_info.memoryUsed = memused; + nvctrl_info.memoryUsed = memused; + + free(utilization); + free(freq); } \ No newline at end of file From 79add746b539c09ec2af1325837c08949f3c6df4 Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Fri, 20 Mar 2020 13:23:39 +0100 Subject: [PATCH 07/10] Removed debugging messages --- src/nvctrl.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp index c3c7250f..5d2d1c15 100644 --- a/src/nvctrl.cpp +++ b/src/nvctrl.cpp @@ -49,8 +49,6 @@ void getNvctrlInfo(){ } freq_str = strtok (NULL, ","); } - printf("coreclock: %i\n", nvctrl_info.CoreClock); - printf("memclock: %i\n", nvctrl_info.MemClock); int64_t temp; nvctrl.XNVCTRLQueryTargetAttribute64(display, @@ -78,7 +76,7 @@ void getNvctrlInfo(){ NV_CTRL_USED_DEDICATED_GPU_MEMORY, &memused); nvctrl_info.memoryUsed = memused; - + free(utilization); free(freq); } \ No newline at end of file From c16f4b427577744d16f834eca6df33750777273b Mon Sep 17 00:00:00 2001 From: jackun Date: Fri, 20 Mar 2020 15:25:45 +0200 Subject: [PATCH 08/10] try_stoi: spam in debug build only --- src/string_utils.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/string_utils.h b/src/string_utils.h index 1f1bf8e3..e0dc1cef 100644 --- a/src/string_utils.h +++ b/src/string_utils.h @@ -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); return true; } catch (std::invalid_argument& e) { +#ifndef NDEBUG std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl; +#endif } 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); return true; } catch (std::invalid_argument& e) { +#ifndef NDEBUG std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl; +#endif } return false; } From b059fa26bcab4974f7fa19de89a5aa1f7d2a6abb Mon Sep 17 00:00:00 2001 From: jackun Date: Fri, 20 Mar 2020 15:26:37 +0200 Subject: [PATCH 09/10] xnvctrl: parse tokenized attributes --- src/nvctrl.cpp | 94 +++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp index 5d2d1c15..49aa9421 100644 --- a/src/nvctrl.cpp +++ b/src/nvctrl.cpp @@ -1,56 +1,75 @@ #include -#include +#include +#include +#include #include "nvctrl.h" #include "loaders/loader_nvctrl.h" -#include +#include "string_utils.h" + +typedef std::unordered_map string_map; Display *display = XOpenDisplay(NULL); libnvctrl_loader nvctrl("libXNVCtrl.so"); struct nvctrlInfo nvctrl_info; +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; + char* c = nullptr; if (!nvctrl.XNVCTRLQueryTargetStringAttribute(display, target_type, target_id, 0, attr, &c)) { - fprintf(stderr, "Failed to query attribute."); + fprintf(stderr, "Failed to query attribute '%d'.\n", attr); } return c; } void getNvctrlInfo(){ - char* utilization = get_attr_target_string(NV_CTRL_STRING_GPU_UTILIZATION, NV_CTRL_TARGET_TYPE_GPU, 0); - char* s = utilization; - strtok(s, ","); - while (s != NULL) - { - std::string str = s; - if (str.find("graphics") != std::string::npos){ - str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); - nvctrl_info.load = std::stoi(str); - } - s = strtok (NULL, ","); - } + string_map params; + std::string token; - char* freq = get_attr_target_string(NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, NV_CTRL_TARGET_TYPE_GPU, 0); - char* freq_str = freq; - strtok(freq_str, ","); - while (freq_str != NULL) - { - std::string str = freq_str; - if (str.find("nvclock=") != std::string::npos){ - str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); - nvctrl_info.CoreClock = std::stoi(str); - } - if (str.find("memclock=") != std::string::npos){ - str = std::regex_replace(str, std::regex(R"([^0-9.])"), ""); - nvctrl_info.MemClock = std::stoi(str); + 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); } - freq_str = strtok (NULL, ","); + free(str); } - int64_t temp; + 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, @@ -59,8 +78,8 @@ void getNvctrlInfo(){ &temp); nvctrl_info.temp = temp; - int64_t memtotal; - nvctrl.XNVCTRLQueryTargetAttribute64(display, + int64_t memtotal = 0; + nvctrl.XNVCTRLQueryTargetAttribute64(display, NV_CTRL_TARGET_TYPE_GPU, 0, 0, @@ -68,15 +87,12 @@ void getNvctrlInfo(){ &memtotal); nvctrl_info.memoryTotal = memtotal; - int64_t memused; - nvctrl.XNVCTRLQueryTargetAttribute64(display, + 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; - - free(utilization); - free(freq); + nvctrl_info.memoryUsed = memused; } \ No newline at end of file From fbae1dfcc045169265fd8e013472fdff3154af65 Mon Sep 17 00:00:00 2001 From: jackun Date: Fri, 20 Mar 2020 16:33:43 +0200 Subject: [PATCH 10/10] More checks for XNVCtrl support. Favor NVML but fallback to XNVCtrl if supported. --- src/gpu.cpp | 4 ++-- src/loaders/loader_nvctrl.cpp | 7 +++++++ src/loaders/loader_nvctrl.h | 1 + src/nvctrl.cpp | 10 ++++++++++ src/nvctrl.h | 2 ++ src/nvidia_info.h | 4 ++-- src/nvml.cpp | 6 +++--- src/overlay.cpp | 9 ++++++++- 8 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/gpu.cpp b/src/gpu.cpp index 5d9de921..191ae67a 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -8,13 +8,13 @@ pthread_t cpuThread, gpuThread, cpuInfoThread; void *getNvidiaGpuInfo(void *){ if (nvmlSuccess){ - getNvidiaInfo(); + getNVMLInfo(); gpu_info.load = nvidiaUtilization.gpu; gpu_info.temp = nvidiaTemp; gpu_info.memoryUsed = nvidiaMemory.used / (1024.f * 1024.f * 1024.f); gpu_info.CoreClock = nvidiaCoreClock; gpu_info.MemClock = nvidiaMemClock; - } else { + } else if (nvctrlSuccess) { getNvctrlInfo(); gpu_info.load = nvctrl_info.load; gpu_info.temp = nvctrl_info.temp; diff --git a/src/loaders/loader_nvctrl.cpp b/src/loaders/loader_nvctrl.cpp index 97a771f2..2a75d8ca 100644 --- a/src/loaders/loader_nvctrl.cpp +++ b/src/loaders/loader_nvctrl.cpp @@ -29,6 +29,13 @@ bool libnvctrl_loader::Load(const std::string& library_name) { if (!library_) return false; + XNVCTRLIsNvScreen = + reinterpret_castXNVCTRLIsNvScreen)>( + dlsym(library_, "XNVCTRLIsNvScreen")); + if (!XNVCTRLIsNvScreen) { + CleanUp(true); + return false; + } XNVCTRLQueryVersion = reinterpret_castXNVCTRLQueryVersion)>( diff --git a/src/loaders/loader_nvctrl.h b/src/loaders/loader_nvctrl.h index f365ef70..d16b4029 100644 --- a/src/loaders/loader_nvctrl.h +++ b/src/loaders/loader_nvctrl.h @@ -21,6 +21,7 @@ class 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; diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp index 49aa9421..5c6e1411 100644 --- a/src/nvctrl.cpp +++ b/src/nvctrl.cpp @@ -12,6 +12,16 @@ 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; diff --git a/src/nvctrl.h b/src/nvctrl.h index 6aee9df4..3de9052f 100644 --- a/src/nvctrl.h +++ b/src/nvctrl.h @@ -8,5 +8,7 @@ struct nvctrlInfo{ }; 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); \ No newline at end of file diff --git a/src/nvidia_info.h b/src/nvidia_info.h index a3e47cc8..b914e42f 100644 --- a/src/nvidia_info.h +++ b/src/nvidia_info.h @@ -9,5 +9,5 @@ extern struct nvmlUtilization_st nvidiaUtilization; extern struct nvmlMemory_st nvidiaMemory; extern bool nvmlSuccess; -bool checkNvidia(void); -void getNvidiaInfo(void); \ No newline at end of file +bool checkNVML(void); +void getNVMLInfo(void); \ No newline at end of file diff --git a/src/nvml.cpp b/src/nvml.cpp index 79bd90c2..66429dc0 100644 --- a/src/nvml.cpp +++ b/src/nvml.cpp @@ -10,7 +10,7 @@ unsigned int nvidiaTemp, nvidiaCoreClock, nvidiaMemClock; struct nvmlUtilization_st nvidiaUtilization; struct nvmlMemory_st nvidiaMemory {}; -bool checkNvidia(){ +bool checkNVML(){ if (nvml.IsLoaded()){ result = nvml.nvmlInit(); if (NVML_SUCCESS != result) { @@ -25,7 +25,7 @@ bool checkNvidia(){ return false; } -void getNvidiaInfo(){ +void getNVMLInfo(){ nvmlReturn_t response; nvml.nvmlDeviceGetHandleByIndex(0, &nvidiaDevice); response = nvml.nvmlDeviceGetUtilizationRates(nvidiaDevice, &nvidiaUtilization); @@ -33,6 +33,6 @@ void getNvidiaInfo(){ nvml.nvmlDeviceGetMemoryInfo(nvidiaDevice, &nvidiaMemory); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_GRAPHICS, &nvidiaCoreClock); nvml.nvmlDeviceGetClockInfo(nvidiaDevice, NVML_CLOCK_MEM, &nvidiaMemClock); - if (response == 3) + if (response == NVML_ERROR_NOT_SUPPORTED) nvmlSuccess = false; } \ No newline at end of file diff --git a/src/overlay.cpp b/src/overlay.cpp index 871062fc..76a8d24d 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -782,7 +782,14 @@ void init_gpu_stats(uint32_t& vendorID, overlay_params& params) // NVIDIA or Intel but maybe has Optimus if (vendorID == 0x8086 || 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; } }