From bcffcdf19f4d2cb774b916f43493ec7c051ac92a Mon Sep 17 00:00:00 2001 From: romner Date: Sun, 14 May 2023 16:53:06 +0200 Subject: [PATCH] Make GPU window's size dynamic and integrate it with the rest of btop --- src/btop.cpp | 40 ++--- src/btop_draw.cpp | 324 +++++++++++++++++++++---------------- src/btop_shared.hpp | 10 ++ src/btop_tools.cpp | 3 + src/linux/btop_collect.cpp | 11 ++ 5 files changed, 226 insertions(+), 162 deletions(-) diff --git a/src/btop.cpp b/src/btop.cpp index dd189ea..ba8a24e 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -526,6 +526,26 @@ namespace Runner { } } + //? GPU + if (v_contains(conf.boxes, "gpu")) { + try { + if (Global::debug) debug_timer("gpu", collect_begin); + + //? Start collect + auto gpu = Gpu::collect(conf.no_update); + + if (Global::debug) debug_timer("gpu", draw_begin); + + //? Draw box + if (not pause_output) output += Gpu::draw(gpu, conf.force_redraw, conf.no_update); + + if (Global::debug) debug_timer("gpu", draw_done); + } + catch (const std::exception& e) { + throw std::runtime_error("Gpu:: -> " + string{e.what()}); + } + } + //? MEM if (v_contains(conf.boxes, "mem")) { try { @@ -586,26 +606,6 @@ namespace Runner { } } - //? GPU - if (v_contains(conf.boxes, "gpu")) { - try { - if (Global::debug) debug_timer("gpu", collect_begin); - - //? Start collect - auto gpu = Gpu::collect(conf.no_update); - - if (Global::debug) debug_timer("gpu", draw_begin); - - //? Draw box - if (not pause_output) output += Gpu::draw(gpu, conf.force_redraw, conf.no_update); - - if (Global::debug) debug_timer("gpu", draw_done); - } - catch (const std::exception& e) { - throw std::runtime_error("Gpu:: -> " + string{e.what()}); - } - } - } catch (const std::exception& e) { Global::exit_error_msg = "Exception in runner thread -> " + string{e.what()}; diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 1137fa1..55b1b10 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -727,6 +727,141 @@ namespace Cpu { } +namespace Gpu { + int width_p = 100, height_p = 32; + int min_width = 41, min_height = 9; + int x = 1, y = 1, width = 41, height; + int b_columns, b_column_size; + int b_x, b_y, b_width, b_height; + int bproc_x, bproc_y, bproc_width, bproc_height; + bool shown = true, redraw = true, mid_line = false; + int graph_up_height; + Draw::Graph graph_upper; + Draw::Graph graph_lower; + Draw::Graph temp_graph; + Draw::Graph mem_used_graph; + Draw::Graph mem_util_graph; + Draw::Meter gpu_meter; + Draw::Meter pwr_meter; + string box; + + string draw(const gpu_info& gpu, bool force_redraw, bool data_same) { + if (Runner::stopping) return ""; + if (force_redraw) redraw = true; + bool show_temps = (Config::getB("check_temp")); + auto tty_mode = Config::getB("tty_mode"); + auto& temp_scale = Config::getS("temp_scale"); + auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_cpu")); // TODO graph_symbol_gpu + auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); + auto single_graph = Config::getB("cpu_single_graph"); + string out; + out.reserve(width * height); + + + //* Redraw elements not needed to be updated every cycle + if (redraw) { + graph_up_height = single_graph ? height - 2 : ceil((double)(height - 2) / 2); + const int graph_low_height = height - 2 - graph_up_height - (mid_line ? 1 : 0); + out += box; + + graph_upper = Draw::Graph{x + width - b_width - 3, graph_up_height, "cpu", gpu.gpu_percent, graph_symbol, false, true}; // TODO cpu -> gpu + if (not single_graph) { + graph_lower = Draw::Graph{ + x + width - b_width - 3, + graph_low_height, "cpu", + gpu.gpu_percent, + graph_symbol, + Config::getB("cpu_invert_lower"), true + }; + } + + gpu_meter = Draw::Meter{b_width - (show_temps ? 24 : 11), "cpu"}; + temp_graph = Draw::Graph{6, 1, "temp", gpu.temp, graph_symbol, false, false, gpu.temp_max, -23}; + + pwr_meter = Draw::Meter{b_width - 24, "cached"}; + + 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% I/O + mem_used_graph = Draw::Graph{b_width/2 - 2, 4, "used", gpu.mem_used_percent, graph_symbol}; + } + + + //* General GPU info + + //? Gpu graph, clock speed & meter + out += Fx::ub + Mv::to(y + 1, x + 1) + graph_upper(gpu.gpu_percent, (data_same or redraw)); + if (not single_graph) + out += Mv::to(y + graph_up_height + 1 + mid_line, x + 1) + graph_lower(gpu.gpu_percent, (data_same or redraw)); + + if (Config::getB("show_cpu_freq")) { // TODO show_gpu_freq + string clock_speed_string = to_string(gpu.gpu_clock_speed); + out += Mv::to(b_y, b_x + b_width - 12) + 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; + } + + out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "GPU " + gpu_meter(gpu.gpu_percent.back()) + + Theme::g("cpu").at(gpu.gpu_percent.back()) + rjust(to_string(gpu.gpu_percent.back()), 4) + Theme::c("main_fg") + '%'; + + //? Temperature graph + if (show_temps) { + const auto [temp, unit] = celsius_to(gpu.temp.back(), temp_scale); + out += ' ' + Theme::c("inactive_fg") + graph_bg * 6 + Mv::l(6) + Theme::g("temp").at(clamp(gpu.temp.back() * 100 / gpu.temp_max, 0ll, 100ll)) + + temp_graph(gpu.temp, data_same or redraw); + out += rjust(to_string(temp), 4) + Theme::c("main_fg") + unit; + } + out += Theme::c("div_line") + Symbols::v_line; + + //? Power usage meter, power state + out += Mv::to(b_y + 2, b_x + 1) + Theme::c("main_fg") + Fx::b + "PWR " + pwr_meter(gpu.pwr_percent.back()) + + Theme::g("cached").at(gpu.pwr_percent.back()) + rjust(to_string(gpu.pwr_usage/1000), 4) + Theme::c("main_fg") + 'W' + + " P-state: " + (gpu.pwr_state > 9 ? "" : " ") + 'P' + Theme::g("cached").at(gpu.pwr_state) + to_string(gpu.pwr_state); + + //? Memory section header & clock speed + string used_memory_string = floating_humanizer(gpu.mem_used); + out += Mv::to(b_y + 3, b_x) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line + Symbols::title_left + Fx::b + Theme::c("title") + "vram" + + Theme::c("div_line") + Fx::ub + Symbols::title_right + Symbols::h_line*(b_width/2-8) + Symbols::div_up + Symbols::h_line + + Theme::c("title") + "Used:" + Theme::c("div_line") + Symbols::h_line*(b_width/2+b_width%2-9-used_memory_string.size()) + Theme::c("title") + used_memory_string + Theme::c("div_line") + Symbols::h_line + Symbols::div_right; + if (Config::getB("show_cpu_freq")) { // TODO show_gpu_freq + 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()) + + Symbols::title_left + Fx::b + Theme::c("title") + clock_speed_string + " Mhz" + Fx::ub + Theme::c("div_line") + Symbols::title_right; + } + + //? Memory usage borders + out += Mv::to(b_y + 5, b_x) + Theme::c("div_line") + Symbols::div_left+Symbols::h_line + Theme::c("title") + "I/O:" + Theme::c("div_line") + Symbols::h_line*(b_width/2-6) + + Symbols::div_right + Mv::u(1)+Mv::l(1) + Symbols::v_line + Mv::l(1)+Mv::d(2) + (Symbols::v_line + Mv::l(1)+Mv::d(1))*2; + + //? Total memory usage + out += Mv::to(b_y + 4, b_x + 2) + Theme::c("main_fg") + Fx::b + "Total:" + rjust(floating_humanizer(gpu.mem_total), b_width/2-9) + Fx::ub; + + //? Memory usage graphs & percentage + out += Mv::to(b_y+6, b_x+1) + Theme::c("inactive_fg") + mem_util_graph(gpu.mem_utilization_percent, (data_same or redraw)) + + Mv::u(3) + Mv::r(1) + mem_used_graph(gpu.mem_used_percent, (data_same or redraw)); + out += Mv::to(b_y+6, b_x+1) + rjust(to_string(gpu.mem_utilization_percent.back()), 3) + '%' + Mv::u(2) + Mv::r(b_width/2-3) + rjust(to_string(gpu.mem_used_percent.back()), 3) + '%'; + + //? Processes section header + //out += Mv::to(b_y+8, b_x) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line + Symbols::title_left + Theme::c("main_fg") + Fx::b + "gpu-proc" + Fx::ub + Theme::c("div_line") + // + Symbols::title_right + Symbols::h_line*(b_width/2-12) + Symbols::div_down + Symbols::h_line*(b_width/2-2) + Symbols::div_right; + + //? PCIe link throughput + string tx_string = floating_humanizer(gpu.pcie_tx, 0, 1, 0, 1); + string rx_string = floating_humanizer(gpu.pcie_rx, 0, 1, 0, 1); + out += Mv::to(b_y + b_height - 1, b_x+2) + Theme::c("div_line") + + Symbols::title_left_down + Theme::c("title") + Fx::b + "TX:" + Fx::ub + Theme::c("div_line") + Symbols::title_right_down + Symbols::h_line*(b_width/2-9-tx_string.size()) + + Symbols::title_left_down + Theme::c("title") + Fx::b + tx_string + Fx::ub + Theme::c("div_line") + Symbols::title_right_down + Symbols::div_down + + Symbols::title_left_down + Theme::c("title") + Fx::b + "RX:" + Fx::ub + Theme::c("div_line") + Symbols::title_right_down + Symbols::h_line*(b_width/2+b_width%2-9-rx_string.size()) + + Symbols::title_left_down + Theme::c("title") + Fx::b + rx_string + Fx::ub + Theme::c("div_line") + Symbols::title_right_down + Symbols::round_right_down; + + //* GPU graphics process list + //! TODO + + //* GPU compute process list + //! TODO + + redraw = false; + return out + Fx::reset; + } +} + namespace Mem { int width_p = 45, height_p = 36; int min_width = 36, min_height = 10; @@ -1576,115 +1711,6 @@ namespace Proc { } -namespace Gpu { - int width_p = 100, height_p = 32; - int min_width = 60, min_height = 8; - int x = 1, y = 1, width = 20, height; - int b_columns, b_column_size; - int b_x, b_y, b_width, b_height; - bool shown = true, redraw = true, mid_line = false; - int graph_height; - Draw::Graph graph_upper; - Draw::Graph temp_graph; - Draw::Graph mem_used_graph; - Draw::Graph mem_util_graph; - Draw::Meter gpu_meter; - Draw::Meter pwr_meter; - string box; - - string draw(const gpu_info& gpu, bool force_redraw, bool data_same) { - if (Runner::stopping) return ""; - if (force_redraw) redraw = true; - bool show_temps = (Config::getB("check_temp")); - auto tty_mode = Config::getB("tty_mode"); - auto& temp_scale = Config::getS("temp_scale"); - auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_cpu")); // TODO graph_symbol_gpu - auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); - string out; - out.reserve(width * height); - - //* Redraw elements not needed to be updated every cycle - if (redraw) { - out += box; - - graph_upper = Draw::Graph{x + width - b_width - 3, height-2, "cpu", gpu.gpu_percent, graph_symbol, false, true}; // TODO cpu -> gpu - gpu_meter = Draw::Meter{b_width - (show_temps ? 24 : 11), "cpu"}; - temp_graph = Draw::Graph{6, 1, "temp", gpu.temp, graph_symbol, false, false, gpu.temp_max, -23}; - - pwr_meter = Draw::Meter{b_width - 24, "cached"}; - - 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% I/O - mem_used_graph = Draw::Graph{b_width/2 - 2, 4, "used", gpu.mem_used_percent, graph_symbol}; - } - - //? Core text and graphs - try { - //? Gpu graph, clock speed & meter - out += Fx::ub + Mv::to(y + 1, x + 1) + graph_upper(gpu.gpu_percent, (data_same or redraw)); - - if (Config::getB("show_cpu_freq")) { // TODO show_gpu_freq - string clock_speed_string = to_string(gpu.gpu_clock_speed); - out += Mv::to(b_y, b_x + b_width - 12) + 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; - } - - out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "GPU " + gpu_meter(gpu.gpu_percent.back()) - + Theme::g("cpu").at(gpu.gpu_percent.back()) + rjust(to_string(gpu.gpu_percent.back()), 4) + Theme::c("main_fg") + '%'; - - //? Temperature graph - if (show_temps) { - const auto [temp, unit] = celsius_to(gpu.temp.back(), temp_scale); - out += ' ' + Theme::c("inactive_fg") + graph_bg * 6 + Mv::l(6) + Theme::g("temp").at(clamp(gpu.temp.back() * 100 / gpu.temp_max, 0ll, 100ll)) - + temp_graph(gpu.temp, data_same or redraw); - out += rjust(to_string(temp), 4) + Theme::c("main_fg") + unit; - } - out += Theme::c("div_line") + Symbols::v_line; - - //? Power usage meter, power state - out += Mv::to(b_y + 2, b_x + 1) + Theme::c("main_fg") + Fx::b + "PWR " + pwr_meter(gpu.pwr_percent.back()) - + Theme::g("cached").at(gpu.pwr_percent.back()) + rjust(to_string(gpu.pwr_usage/1000), 4) + Theme::c("main_fg") + 'W' - + " P-state: " + (gpu.pwr_state > 9 ? "" : " ") + 'P' + Theme::g("cached").at(gpu.pwr_state) + to_string(gpu.pwr_state); - - //? Memory section header & clock speed - string used_memory_string = floating_humanizer(gpu.mem_used); - out += Mv::to(b_y + 3, b_x) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line + Symbols::title_left + Fx::b + Theme::c("title") + "vram" - + Theme::c("div_line") + Fx::ub + Symbols::title_right + Symbols::h_line*(b_width/2-8) + Symbols::div_up + Symbols::h_line - + Theme::c("title") + "Used:" + Theme::c("div_line") + Symbols::h_line*(b_width/2-9-used_memory_string.size()) + Theme::c("title") + used_memory_string + Theme::c("div_line") + Symbols::h_line + Symbols::div_right; - if (Config::getB("show_cpu_freq")) { // TODO show_gpu_freq - 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()) - + Symbols::title_left + Fx::b + Theme::c("title") + clock_speed_string + " Mhz" + Fx::ub + Theme::c("div_line") + Symbols::title_right; - } - - //? Memory usage borders - out += Mv::to(b_y + 5, b_x) + Theme::c("div_line") + Symbols::div_left+Symbols::h_line + Theme::c("title") + "I/O:" + Theme::c("div_line") + Symbols::h_line*(b_width/2-6) - + Symbols::div_right + Mv::u(1)+Mv::l(1) + Symbols::v_line + Mv::l(1)+Mv::d(2) + (Symbols::v_line + Mv::l(1)+Mv::d(1))*2; - - //? Total memory usage - out += Mv::to(b_y + 4, b_x + 2) + Theme::c("main_fg") + Fx::b + "Total:" + rjust(floating_humanizer(gpu.mem_total), b_width/2-9) + Fx::ub; - - //? Memory usage graphs & percentage - out += Mv::to(b_y+6, b_x+1) + Theme::c("inactive_fg") + mem_util_graph(gpu.mem_utilization_percent, (data_same or redraw)) - + Mv::u(3) + Mv::r(1) + mem_used_graph(gpu.mem_used_percent, (data_same or redraw)); - out += Mv::to(b_y+6, b_x+1) + rjust(to_string(gpu.mem_utilization_percent.back()), 3) + '%' + Mv::u(2) + Mv::r(b_width/2-3) + rjust(to_string(gpu.mem_used_percent.back()), 3) + '%'; - - //? Processes section header - out += Mv::to(b_y+8, b_x) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line + Symbols::title_left + Theme::c("main_fg") + Fx::b + "gpu-proc" + Fx::ub + Theme::c("div_line") - + Symbols::title_right + Symbols::h_line*(b_width/2-12) + Symbols::div_down + Symbols::h_line*(b_width/2-2) + Symbols::div_right; - - //? PCIe link throughput - out += Mv::to(b_y + b_height - 1, b_x+2) + Symbols::title_left_down + Theme::c("main_fg") + "TX: " + floating_humanizer(gpu.pcie_tx, 0, 1, 0, 1) + Theme::c("div_line") - + Symbols::title_right_down + Symbols::title_left_down + Theme::c("main_fg") + "RX: " + floating_humanizer(gpu.pcie_rx, 0, 1, 0, 1) + Theme::c("div_line") + Symbols::title_right_down + Symbols::h_line*10; - - } catch (const std::exception& e) { - throw std::runtime_error("graphs: " + string{e.what()}); - } - - redraw = false; - return out + Fx::reset; - } -} - namespace Draw { void calcSizes() { atomic_wait(Runner::active); @@ -1695,10 +1721,10 @@ namespace Draw { auto proc_left = Config::getB("proc_left"); Cpu::box.clear(); + Gpu::box.clear(); Mem::box.clear(); Net::box.clear(); Proc::box.clear(); - Gpu::box.clear(); Global::clock.clear(); Global::overlay.clear(); Runner::pause_output = false; @@ -1709,24 +1735,29 @@ namespace Draw { Input::mouse_mappings.clear(); - Cpu::x = Mem::x = Net::x = Proc::y = Gpu::x = 1; - Cpu::y = Mem::y = Net::y = Proc::y = Gpu::y = 1; - Cpu::width = Mem::width = Net::width = Proc::width = Gpu::width = 0; - Cpu::height = Mem::height = Net::height = Proc::height = Gpu::height = 0; - Cpu::redraw = Mem::redraw = Net::redraw = Proc::redraw = Gpu::redraw = true; + Cpu::x = Gpu::x = Mem::x = Net::x = Proc::y = 1; + Cpu::y = Gpu::y = Mem::y = Net::y = Proc::y = 1; + Cpu::width = Gpu::width = Mem::width = Net::width = Proc::width = 0; + Cpu::height = Gpu::height = Mem::height = Net::height = Proc::height = 0; + Cpu::redraw = Gpu::redraw = Mem::redraw = Net::redraw = Proc::redraw = true; Cpu::shown = s_contains(boxes, "cpu"); + Gpu::shown = s_contains(boxes, "gpu"); Mem::shown = s_contains(boxes, "mem"); Net::shown = s_contains(boxes, "net"); Proc::shown = s_contains(boxes, "proc"); - Gpu::shown = s_contains(boxes, "gpu"); //* Calculate and draw cpu box outlines if (Cpu::shown) { using namespace Cpu; bool show_temp = (Config::getB("check_temp") and got_sensors); width = round((double)Term::width * width_p / 100); - height = max(8, (int)ceil((double)Term::height * (trim(boxes) == "cpu" ? 100 : height_p) / 100)); + if (Gpu::shown && !(Mem::shown || Net::shown || Proc::shown)) { + height = Term::height/2; + } else { + height = max(8, (int)ceil((double)Term::height * (trim(boxes) == "cpu" ? 100 : height_p/(Gpu::shown+1) + Gpu::shown*5) / 100)); + } + x = 1; y = cpu_bottom ? Term::height - height + 1 : 1; @@ -1760,6 +1791,33 @@ namespace Draw { box += createBox(b_x, b_y, b_width, b_height, "", false, cpu_title); } + //* Calculate and draw gpu box outlines + if (Gpu::shown) { + using namespace Gpu; + width = Term::width; + height = max(Gpu::min_height, Cpu::shown ? Cpu::height : (int)ceil((double)Term::height * (trim(boxes) == "gpu" ? 100 : height_p) / 100)); + x = 1; y = 1 + Cpu::shown*Cpu::height; + box = createBox(x, y, width, height, Theme::c("cpu_box"), true, "gpu", "", 5); // TODO gpu_box + + b_height = 9; + b_width = clamp(width/2, min_width, b_height*6); + + // bproc_width = b_width; + // bproc_height = height-11; + + //? Main statistics box + b_x = x + width - b_width - 1; + b_y = y + ceil((double)(height - 2) / 2) - ceil((double)(b_height/*+bproc_height*/) / 2) + 1; + + box += createBox(b_x, b_y, b_width, b_height, "", false, gpu_name); + + //? TODO: Processes box + /*bproc_x = x + width - bproc_width - 1; + bproc_y = b_y + b_height; + + box += createBox(bproc_x, bproc_y, bproc_width, bproc_height, "", false, "gpu-proc");*/ + } + //* Calculate and draw mem box outlines if (Mem::shown) { using namespace Mem; @@ -1768,13 +1826,12 @@ namespace Draw { auto mem_graphs = Config::getB("mem_graphs"); width = round((double)Term::width * (Proc::shown ? width_p : 100) / 100); - height = ceil((double)Term::height * (100 - Cpu::height_p * Cpu::shown - Net::height_p * Net::shown) / 100) + 1; - if (height + Cpu::height > Term::height) height = Term::height - Cpu::height; + height = ceil((double)Term::height * (100 - Net::height_p * Net::shown*4 / ((Gpu::shown && Cpu::shown) + 4)) / 100) - Cpu::height - Gpu::height; x = (proc_left and Proc::shown) ? Term::width - width + 1: 1; if (mem_below_net and Net::shown) - y = Term::height - height + 1 - (cpu_bottom ? Cpu::height : 0); + y = Term::height - height + 1 - (cpu_bottom ? Cpu::height + Gpu::height : 0); else - y = cpu_bottom ? 1 : Cpu::height + 1; + y = cpu_bottom ? 1 : Cpu::height + Gpu::height + 1; if (show_disks) { mem_width = ceil((double)(width - 3) / 2); @@ -1823,10 +1880,10 @@ namespace Draw { if (Net::shown) { using namespace Net; width = round((double)Term::width * (Proc::shown ? width_p : 100) / 100); - height = Term::height - Cpu::height - Mem::height; + height = Term::height - Cpu::height - Gpu::height - Mem::height; x = (proc_left and Proc::shown) ? Term::width - width + 1 : 1; if (mem_below_net and Mem::shown) - y = cpu_bottom ? 1 : Cpu::height + 1; + y = cpu_bottom ? 1 : Cpu::height + Gpu::height + 1; else y = Term::height - height + 1 - (cpu_bottom ? Cpu::height : 0); @@ -1845,28 +1902,11 @@ namespace Draw { if (Proc::shown) { using namespace Proc; width = Term::width - (Mem::shown ? Mem::width : (Net::shown ? Net::width : 0)); - height = Term::height - Cpu::height; + height = Term::height - Cpu::height - Gpu::height; x = proc_left ? 1 : Term::width - width + 1; - y = (cpu_bottom and Cpu::shown) ? 1 : Cpu::height + 1; + y = (cpu_bottom and Cpu::shown) ? 1 : Cpu::height + Gpu::height + 1; select_max = height - 3; box = createBox(x, y, width, height, Theme::c("proc_box"), true, "proc", "", 4); } - - //* Calculate and draw gpu box outlines - if (Gpu::shown) { - using namespace Gpu; - width = Term::width; - height = Term::height; - x = 1; y = 1; - box = createBox(x, y, width, height, Theme::c("cpu_box"), true, "gpu", "", 5); // TODO gpu_box - - b_width = width/2 - width%2; // TODO - b_height = height-2; - - b_x = x + width - b_width - 1; - b_y = y + ceil((double)(height - 2) / 2) - ceil((double)b_height / 2) + 1; - - box += createBox(b_x, b_y, b_width, b_height, "", false, gpu_name); - } } } diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 5c121be..5aff032 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -322,6 +322,13 @@ namespace Gpu { const array mem_names { "used"s, "free"s }; + //* Container for process information + struct proc_info { + unsigned int pid; + unsigned long long mem; + }; + + //* Per-device container for GPU info struct gpu_info { deque gpu_percent = {}; unsigned int gpu_clock_speed = 0; // MHz @@ -343,6 +350,9 @@ namespace Gpu { unsigned int pcie_tx = 0; // KB/s unsigned int pcie_rx = 0; + + vector graphics_processes = {}; + vector compute_processes = {}; }; namespace Nvml { diff --git a/src/btop_tools.cpp b/src/btop_tools.cpp index 5789737..7f0d943 100644 --- a/src/btop_tools.cpp +++ b/src/btop_tools.cpp @@ -103,15 +103,18 @@ namespace Term { bool mem = boxes.find("mem") != string::npos; bool net = boxes.find("net") != string::npos; bool proc = boxes.find("proc") != string::npos; + bool gpu = boxes.find("gpu") != string::npos; int width = 0; if (mem) width = Mem::min_width; else if (net) width = Mem::min_width; width += (proc ? Proc::min_width : 0); if (cpu and width < Cpu::min_width) width = Cpu::min_width; + if (gpu and width < Gpu::min_width) width = Gpu::min_width; int height = (cpu ? Cpu::min_height : 0); if (proc) height += Proc::min_height; else height += (mem ? Mem::min_height : 0) + (net ? Net::min_height : 0); + if (gpu) height += Gpu::min_height; return { width, height }; } diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index b40ab73..fcb1275 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -2238,6 +2238,17 @@ namespace Gpu { Logger::error(std::string("NVML: Failed to get PCIe RX throughput: ") + nvmlErrorString(result)); } + //? TODO: Processes using GPU + /*unsigned int proc_info_len; + nvmlProcessInfo_t* proc_info = 0; + result = nvmlDeviceGetComputeRunningProcesses_v3(device, &proc_info_len, proc_info); + if (result != NVML_SUCCESS) { + Logger::error(std::string("NVML: Failed to get compute processes: ") + nvmlErrorString(result)); + } else { + for (unsigned int i = 0; i < proc_info_len; ++i) + current_gpu.graphics_processes.push_back({proc_info[i].pid, proc_info[i].usedGpuMemory}); + }*/ + return true; } }