From 27bb118d9a9b67729e8ac26ee29f0ecd2bac8805 Mon Sep 17 00:00:00 2001 From: scorpion-26 <58082714+scorpion-26@users.noreply.github.com> Date: Mon, 30 Jan 2023 17:23:28 +0100 Subject: [PATCH] Initial AMD GPU implementation Partially implements https://github.com/scorpion-26/gBar/issues/5 The spammy logs will remain, until it is confirmed, that it works. --- meson.build | 4 +++ meson_options.txt | 1 + src/AMDGPU.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++ src/Bar.cpp | 6 ++-- src/Config.h | 5 +++ src/System.cpp | 68 +++++++++++++++++++++++++++++++--------- src/System.h | 2 +- 7 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 src/AMDGPU.h diff --git a/meson.build b/meson.build index 7d42657..54d1781 100644 --- a/meson.build +++ b/meson.build @@ -25,6 +25,10 @@ if get_option('WithNvidia') add_global_arguments('-DWITH_NVIDIA', language: 'cpp') headers += 'src/NvidiaGPU.h' endif +if get_option('WithAMD') + add_global_arguments('-DWITH_AMD', language: 'cpp') + headers += 'src/AMDGPU.h' +endif if get_option('WithBlueZ') add_global_arguments('-DWITH_BLUEZ', language: 'cpp') endif diff --git a/meson_options.txt b/meson_options.txt index 5407866..43924da 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,5 +1,6 @@ option('WithHyprland', type: 'boolean', value : true) option('WithNvidia', type: 'boolean', value : true) +option('WithAMD', type: 'boolean', value : true) option('WithBlueZ', type: 'boolean', value : true) # You shouldn't enable this, unless you know what you are doing! diff --git a/src/AMDGPU.h b/src/AMDGPU.h new file mode 100644 index 0000000..be57140 --- /dev/null +++ b/src/AMDGPU.h @@ -0,0 +1,79 @@ +#include "Common.h" +#include "Config.h" + +#include + +#ifdef WITH_AMD +namespace AMDGPU +{ + static const char* utilizationFile = "/sys/class/drm/card0/device/gpu_busy_percent"; + static const char* vramTotalFile = "/sys/class/drm/card0/device/mem_info_vram_total"; + static const char* vramUsedFile = "/sys/class/drm/card0/device/mem_info_vram_used"; + + inline void Init() + { + // Test for drm device files + std::ifstream test(utilizationFile); + if (!test.is_open()) + { + LOG("AMD GPU not found, disabling AMD GPU"); + RuntimeConfig::Get().hasAMD = false; + } + } + + inline uint32_t GetUtilization() + { + if (!RuntimeConfig::Get().hasAMD) + { + LOG("Error: Called AMD GetUtilization, but AMD GPU wasn't found!"); + return {}; + } + + std::ifstream file(utilizationFile); + std::string line; + std::getline(file, line); + LOG("AMD GetUtilization: " << line); + return atoi(line.c_str()); + } + + inline uint32_t GetTemperature() + { + if (!RuntimeConfig::Get().hasAMD) + { + LOG("Error: Called AMD GetTemperature, but AMD GPU wasn't found!"); + return {}; + } + // TODO! + return 0; + } + + struct VRAM + { + uint32_t totalB; + uint32_t usedB; + }; + + inline VRAM GetVRAM() + { + if (!RuntimeConfig::Get().hasAMD) + { + LOG("Error: Called AMD GetVRAM, but AMD GPU wasn't found!"); + return {}; + } + VRAM mem{}; + + std::ifstream file(vramTotalFile); + std::string line; + std::getline(file, line); + LOG("AMD GetVRAM(total): " << line); + mem.totalB = atoi(line.c_str()); + + file = std::ifstream(vramUsedFile); + std::getline(file, line); + LOG("AMD GetVRAM(total): " << line); + mem.usedB = atoi(line.c_str()); + + return mem; + } +} +#endif diff --git a/src/Bar.cpp b/src/Bar.cpp index ca111e4..64b6ab3 100644 --- a/src/Bar.cpp +++ b/src/Bar.cpp @@ -52,7 +52,7 @@ namespace Bar return TimerResult::Ok; } -#ifdef WITH_NVIDIA +#if defined WITH_NVIDIA || defined WITH_AMD static Text* gpuText; static TimerResult UpdateGPU(CairoSensor& sensor) { @@ -272,8 +272,8 @@ namespace Bar void WidgetSensors(Widget& parent) { Sensor(parent, DynCtx::UpdateDisk, "disk-util-progress", "disk-data-text", DynCtx::diskText); -#ifdef WITH_NVIDIA - if (RuntimeConfig::Get().hasNvidia) +#if defined WITH_NVIDIA || defined WITH_AMD + if (RuntimeConfig::Get().hasNvidia || RuntimeConfig::Get().hasAMD) { Sensor(parent, DynCtx::UpdateVRAM, "vram-util-progress", "vram-data-text", DynCtx::vramText); Sensor(parent, DynCtx::UpdateGPU, "gpu-util-progress", "gpu-data-text", DynCtx::gpuText); diff --git a/src/Config.h b/src/Config.h index 0860381..0f81ad2 100644 --- a/src/Config.h +++ b/src/Config.h @@ -28,6 +28,11 @@ public: #else bool hasNvidia = false; #endif +#ifdef WITH_AMD + bool hasAMD = true; +#else + bool hasAMD = false; +#endif #ifdef WITH_HYPRLAND bool hasHyprland = true; diff --git a/src/System.cpp b/src/System.cpp index 048cc61..e2fe8b6 100644 --- a/src/System.cpp +++ b/src/System.cpp @@ -1,6 +1,7 @@ #include "System.h" #include "Common.h" #include "NvidiaGPU.h" +#include "AMDGPU.h" #include "PulseAudio.h" #include "Hyprland.h" #include "Config.h" @@ -133,23 +134,55 @@ namespace System return out; } -#ifdef WITH_NVIDIA +#if defined WITH_NVIDIA || defined WITH_AMD GPUInfo GetGPUInfo() { - NvidiaGPU::GPUUtilization util = NvidiaGPU::GetUtilization(); - GPUInfo out; - out.utilisation = util.gpu; - out.coreTemp = NvidiaGPU::GetTemperature(); - return out; +#ifdef WITH_NVIDIA + if (RuntimeConfig::Get().hasNvidia) + { + NvidiaGPU::GPUUtilization util = NvidiaGPU::GetUtilization(); + GPUInfo out; + out.utilisation = util.gpu; + out.coreTemp = NvidiaGPU::GetTemperature(); + return out; + } +#endif +#ifdef WITH_AMD + if (RuntimeConfig::Get().hasAMD) + { + uint32_t util = AMDGPU::GetUtilization(); + GPUInfo out; + out.utilisation = util; + out.coreTemp = AMDGPU::GetTemperature(); + return out; + } +#endif + return {}; } VRAMInfo GetVRAMInfo() { - NvidiaGPU::VRAM vram = NvidiaGPU::GetVRAM(); - VRAMInfo out; - out.totalGiB = (double)vram.totalB / (1024 * 1024 * 1024); - out.usedGiB = out.totalGiB - ((double)vram.freeB / (1024 * 1024 * 1024)); - return out; +#ifdef WITH_NVIDIA + if (RuntimeConfig::Get().hasNvidia) + { + NvidiaGPU::VRAM vram = NvidiaGPU::GetVRAM(); + VRAMInfo out; + out.totalGiB = (double)vram.totalB / (1024 * 1024 * 1024); + out.usedGiB = out.totalGiB - ((double)vram.freeB / (1024 * 1024 * 1024)); + return out; + } +#endif +#ifdef WITH_AMD + if (RuntimeConfig::Get().hasAMD) + { + AMDGPU::VRAM vram = AMDGPU::GetVRAM(); + VRAMInfo out; + out.totalGiB = (double)vram.totalB / (1024 * 1024 * 1024); + out.usedGiB = (double)vram.usedB / (1024 * 1024 * 1024); + return out; + } +#endif + return {}; } #endif @@ -413,13 +446,16 @@ namespace System { return Hyprland::Goto(workspace); } - std::string GetWorkspaceSymbol(int index) { - if (index < 0 || index > 9) { + std::string GetWorkspaceSymbol(int index) + { + if (index < 0 || index > 9) + { LOG("Workspace Symbol Index Out Of Bounds: " + std::to_string(index)); return ""; } - if (Config::Get().workspaceSymbols[index].empty()) { + if (Config::Get().workspaceSymbols[index].empty()) + { return Config::Get().defaultWorkspaceSymbol + " "; } @@ -469,6 +505,10 @@ namespace System NvidiaGPU::Init(); #endif +#ifdef WITH_AMD + AMDGPU::Init(); +#endif + #ifdef WITH_HYPRLAND Hyprland::Init(); #endif diff --git a/src/System.h b/src/System.h index 2a5f73d..bd25a54 100644 --- a/src/System.h +++ b/src/System.h @@ -19,7 +19,7 @@ namespace System }; RAMInfo GetRAMInfo(); -#ifdef WITH_NVIDIA +#if defined WITH_NVIDIA || defined WITH_AMD struct GPUInfo { double utilisation;