mirror of
https://github.com/aristocratos/btop.git
synced 2025-12-23 22:29:08 -05:00
Merge pull request #1165 from sam-kirby/feat/encdec
Add encode and decode meters on Nvidia GPUs
This commit is contained in:
@@ -947,6 +947,7 @@ namespace Gpu {
|
||||
vector<Draw::Graph> mem_used_graph_vec = {}, mem_util_graph_vec = {};
|
||||
vector<Draw::Meter> gpu_meter_vec = {};
|
||||
vector<Draw::Meter> pwr_meter_vec = {};
|
||||
vector<Draw::Meter> enc_meter_vec = {};
|
||||
vector<string> box = {};
|
||||
|
||||
string draw(const gpu_info& gpu, unsigned long index, bool force_redraw, bool data_same) {
|
||||
@@ -964,6 +965,7 @@ namespace Gpu {
|
||||
auto& mem_util_graph = mem_util_graph_vec[index];
|
||||
auto& gpu_meter = gpu_meter_vec[index];
|
||||
auto& pwr_meter = pwr_meter_vec[index];
|
||||
auto& enc_meter = enc_meter_vec[index];
|
||||
|
||||
if (force_redraw) redraw[index] = true;
|
||||
bool show_temps = gpu.supported_functions.temp_info and (Config::getB("check_temp"));
|
||||
@@ -1002,6 +1004,8 @@ namespace Gpu {
|
||||
mem_util_graph = Draw::Graph{b_width/2 - 1, 2, "free", gpu.mem_utilization_percent, graph_symbol, 0, 0, 100, 4}; // offset so the graph isn't empty at 0-5% utilization
|
||||
if (gpu.supported_functions.mem_used and gpu.supported_functions.mem_total)
|
||||
mem_used_graph = Draw::Graph{b_width/2 - 2, 2 + 2*(gpu.supported_functions.mem_utilization), "used", safeVal(gpu.gpu_percent, "gpu-vram-totals"s), graph_symbol};
|
||||
if (gpu.supported_functions.encoder_utilization)
|
||||
enc_meter = Draw::Meter{b_width/2 - 10, "cpu"};
|
||||
}
|
||||
|
||||
|
||||
@@ -1041,8 +1045,17 @@ namespace Gpu {
|
||||
out += std::string(" P-state: ") + (gpu.pwr_state > 9 ? "" : " ") + 'P' + Theme::g("cached").at(clamp(gpu.pwr_state, 0ll, 100ll)) + to_string(gpu.pwr_state);
|
||||
}
|
||||
|
||||
//? Encode and Decode meters
|
||||
bool drawnEncDec = gpu.supported_functions.encoder_utilization and gpu.supported_functions.decoder_utilization;
|
||||
if (drawnEncDec) {
|
||||
out += Mv::to(b_y + 3, b_x +1) + Theme::c("main_fg") + Fx::b + "ENC " + enc_meter(gpu.encoder_utilization)
|
||||
+ Theme::g("cpu").at(clamp(gpu.encoder_utilization, 0ll, 100ll)) + rjust(to_string(gpu.encoder_utilization), 4) + Theme::c("main_fg") + '%'
|
||||
+ Theme::c("div_line") + Symbols::v_line + Theme::c("main_fg") + Fx::b + "DEC " + enc_meter(gpu.decoder_utilization)
|
||||
+ Theme::g("cpu").at(clamp(gpu.decoder_utilization, 0ll, 100ll)) + rjust(to_string(gpu.decoder_utilization), 4) + Theme::c("main_fg") + '%';
|
||||
}
|
||||
|
||||
if (gpu.supported_functions.mem_total or gpu.supported_functions.mem_used) {
|
||||
out += Mv::to(b_y + 3, b_x);
|
||||
out += Mv::to(b_y + (drawnEncDec ? 4 : 3), b_x);
|
||||
if (gpu.supported_functions.mem_total and gpu.supported_functions.mem_used) {
|
||||
string used_memory_string = floating_humanizer(gpu.mem_used);
|
||||
|
||||
@@ -1067,7 +1080,7 @@ namespace Gpu {
|
||||
//? Memory clock speed
|
||||
if (gpu.supported_functions.mem_clock) {
|
||||
string clock_speed_string = to_string(gpu.mem_clock_speed);
|
||||
out += Mv::to(b_y + 3, b_x + b_width/2 - 11) + Theme::c("div_line") + Symbols::h_line*(5-clock_speed_string.size())
|
||||
out += Mv::to(b_y + (drawnEncDec ? 4 : 3), b_x + b_width/2 - 11) + Theme::c("div_line") + Symbols::h_line*(5-clock_speed_string.size())
|
||||
+ Symbols::title_left + Fx::b + Theme::c("title") + clock_speed_string + " MHz" + Fx::ub + Theme::c("div_line") + Symbols::title_right;
|
||||
}
|
||||
} else {
|
||||
@@ -2100,6 +2113,7 @@ namespace Draw {
|
||||
mem_used_graph_vec.resize(shown); mem_util_graph_vec.resize(shown);
|
||||
gpu_meter_vec.resize(shown);
|
||||
pwr_meter_vec.resize(shown);
|
||||
enc_meter_vec.resize(shown);
|
||||
redraw.resize(shown);
|
||||
for (auto i = 0; i < shown; ++i) {
|
||||
redraw[i] = true;
|
||||
@@ -2120,7 +2134,7 @@ namespace Draw {
|
||||
box[i] = createBox(x_vec[i], y_vec[i], width, height, Theme::c("cpu_box"), true, std::string("gpu") + (char)(shown_panels[i]+'0'), "", (shown_panels[i]+5)%10); // TODO gpu_box
|
||||
|
||||
b_height_vec[i] = 2 + gpu_b_height_offsets[shown_panels[i]];
|
||||
b_width = clamp(width/2, min_width, 64);
|
||||
b_width = clamp(width/2, min_width, 65);
|
||||
|
||||
//? Main statistics box
|
||||
b_x_vec[i] = x_vec[i] + width - b_width - 1;
|
||||
|
||||
@@ -139,7 +139,9 @@ namespace Gpu {
|
||||
temp_info = true,
|
||||
mem_total = true,
|
||||
mem_used = true,
|
||||
pcie_txrx = true;
|
||||
pcie_txrx = true,
|
||||
encoder_utilization = true,
|
||||
decoder_utilization = true;
|
||||
};
|
||||
|
||||
//* Per-device container for GPU info
|
||||
@@ -166,6 +168,9 @@ namespace Gpu {
|
||||
long long pcie_tx = 0; // KB/s
|
||||
long long pcie_rx = 0;
|
||||
|
||||
long long encoder_utilization = 0;
|
||||
long long decoder_utilization = 0;
|
||||
|
||||
gpu_info_supported supported_functions;
|
||||
|
||||
// vector<proc_info> graphics_processes = {}; // TODO
|
||||
|
||||
@@ -151,6 +151,8 @@ namespace Gpu {
|
||||
nvmlReturn_t (*nvmlDeviceGetTemperature)(nvmlDevice_t, nvmlTemperatureSensors_t, unsigned int*);
|
||||
nvmlReturn_t (*nvmlDeviceGetMemoryInfo)(nvmlDevice_t, nvmlMemory_t*);
|
||||
nvmlReturn_t (*nvmlDeviceGetPcieThroughput)(nvmlDevice_t, nvmlPcieUtilCounter_t, unsigned int*);
|
||||
nvmlReturn_t (*nvmlDeviceGetEncoderUtilization)(nvmlDevice_t, unsigned int*, unsigned int*);
|
||||
nvmlReturn_t (*nvmlDeviceGetDecoderUtilization)(nvmlDevice_t, unsigned int*, unsigned int*);
|
||||
|
||||
//? Data
|
||||
void* nvml_dl_handle;
|
||||
@@ -308,6 +310,7 @@ namespace Shared {
|
||||
for (size_t i = 0; i < gpu_b_height_offsets.size(); ++i)
|
||||
gpu_b_height_offsets[i] = gpus[i].supported_functions.gpu_utilization
|
||||
+ gpus[i].supported_functions.pwr_usage
|
||||
+ (gpus[i].supported_functions.encoder_utilization or gpus[i].supported_functions.decoder_utilization)
|
||||
+ (gpus[i].supported_functions.mem_total or gpus[i].supported_functions.mem_used)
|
||||
* (1 + 2*(gpus[i].supported_functions.mem_total and gpus[i].supported_functions.mem_used) + 2*gpus[i].supported_functions.mem_utilization);
|
||||
}
|
||||
@@ -1062,6 +1065,8 @@ namespace Gpu {
|
||||
LOAD_SYM(nvmlDeviceGetTemperature);
|
||||
LOAD_SYM(nvmlDeviceGetMemoryInfo);
|
||||
LOAD_SYM(nvmlDeviceGetPcieThroughput);
|
||||
LOAD_SYM(nvmlDeviceGetEncoderUtilization);
|
||||
LOAD_SYM(nvmlDeviceGetDecoderUtilization);
|
||||
|
||||
#undef LOAD_SYM
|
||||
|
||||
@@ -1117,7 +1122,7 @@ namespace Gpu {
|
||||
result = nvmlDeviceGetHandleByIndex(i, devices.data() + i);
|
||||
if (result != NVML_SUCCESS) {
|
||||
Logger::warning(std::string("NVML: Failed to get device handle: ") + nvmlErrorString(result));
|
||||
gpus[i].supported_functions = {false, false, false, false, false, false, false, false};
|
||||
gpus[i].supported_functions = {false, false, false, false, false, false, false, false, false, false};
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1264,6 +1269,30 @@ namespace Gpu {
|
||||
}
|
||||
}
|
||||
|
||||
// nvTimer.stop_rename_reset("Nv enc");
|
||||
//? Encoder info
|
||||
if (gpus_slice[i].supported_functions.encoder_utilization) {
|
||||
unsigned int utilization;
|
||||
unsigned int samplingPeriodUs;
|
||||
result = nvmlDeviceGetEncoderUtilization(devices[i], &utilization, &samplingPeriodUs);
|
||||
if (result != NVML_SUCCESS) {
|
||||
Logger::warning(std::string("NVML: Failed to get encoder utilization: ") + nvmlErrorString(result));
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.encoder_utilization = false;
|
||||
} else gpus_slice[i].encoder_utilization = (long long)utilization;
|
||||
}
|
||||
|
||||
// nvTimer.stop_rename_reset("Nv dec");
|
||||
//? Decoder info
|
||||
if (gpus_slice[i].supported_functions.decoder_utilization) {
|
||||
unsigned int utilization;
|
||||
unsigned int samplingPeriodUs;
|
||||
result = nvmlDeviceGetDecoderUtilization(devices[i], &utilization, &samplingPeriodUs);
|
||||
if (result != NVML_SUCCESS) {
|
||||
Logger::warning(std::string("NVML: Failed to get decoder utilization: ") + nvmlErrorString(result));
|
||||
if constexpr(is_init) gpus_slice[i].supported_functions.decoder_utilization = false;
|
||||
} else gpus_slice[i].decoder_utilization = (long long)utilization;
|
||||
}
|
||||
|
||||
//? TODO: Processes using GPU
|
||||
/*unsigned int proc_info_len;
|
||||
nvmlProcessInfo_t* proc_info = 0;
|
||||
@@ -1437,6 +1466,10 @@ namespace Gpu {
|
||||
if (result != RSMI_STATUS_SUCCESS)
|
||||
Logger::warning("ROCm SMI: Failed to get maximum GPU temperature, defaulting to 110°C");
|
||||
else gpus_slice[i].temp_max = (long long)temp_max;
|
||||
|
||||
//? Disable encoder and decoder utilisation on AMD
|
||||
gpus_slice[i].supported_functions.encoder_utilization = false;
|
||||
gpus_slice[i].supported_functions.decoder_utilization = false;
|
||||
}
|
||||
|
||||
//? GPU utilization
|
||||
@@ -1668,7 +1701,9 @@ namespace Gpu {
|
||||
.temp_info = false,
|
||||
.mem_total = false,
|
||||
.mem_used = false,
|
||||
.pcie_txrx = false
|
||||
.pcie_txrx = false,
|
||||
.encoder_utilization = false,
|
||||
.decoder_utilization = false
|
||||
};
|
||||
|
||||
gpus_slice->pwr_max_usage = 10'000; //? 10W
|
||||
|
||||
Reference in New Issue
Block a user