diff options
Diffstat (limited to 'widgets')
| -rw-r--r-- | widgets/gpu.lua | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/widgets/gpu.lua b/widgets/gpu.lua index 7d5f2ed..abac856 100644 --- a/widgets/gpu.lua +++ b/widgets/gpu.lua @@ -1,10 +1,9 @@ --- GPU: Arc B580 temperatures and fan speed. +-- GPU: Arc B580 temperatures, VRAM in use and fan speed. -- -- No utilisation figure, deliberately. The xe driver exposes no --- gpu_busy_percent, intel_gpu_top refuses the device outright ("Detected Xe --- device which is not supported"), and gputop prints per-process rows with --- ANSI escapes, which is not an interface to build a widget on. The card shows --- what the hardware actually reports rather than inventing a number. +-- gpu_busy_percent and intel_gpu_top refuses the device outright ("Detected Xe +-- device which is not supported"). VRAM comes from DRM fdinfo, the per-client +-- counters gputop itself reads (see data.drm_vram). -- -- The integrated AMD GPU does expose gpu_busy_percent and is deliberately not -- shown: the discrete card is the one in use. @@ -14,6 +13,15 @@ local data = require 'lib.data' local M = {} +-- The B580's VRAM. fdinfo reports what clients hold, not the card's size, and +-- xe puts no capacity in sysfs. ponytail: hardcoded like the 'ARC B580' label. +local VRAM_TOTAL = 12 * 1024 ^ 3 + +-- fdinfo is a popen over every fd on the system, so sample it every ~2s, not +-- every frame. +local gate = data.new_gate(1.9) +local vram + -- chip, file, label, warn, crit. Package (temp2) is the headline above, so it -- is not repeated here; these are the rows drawn under it. local TEMPS = { @@ -24,6 +32,8 @@ function M.draw(cr, rect, colors) local inner = card.card(cr, rect, colors) local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end + if gate() then vram = data.drm_vram() end + local pkg = data.sensor('xe', 'temp2_input') local big_txt = pkg and string.format('%d\u{00B0}', pkg) or '--' @@ -32,8 +42,8 @@ function M.draw(cr, rect, colors) -- only where the header or a row would overrun the card. So a tall cell -- gets larger type instead of empty space, and nothing ever collides. local LABEL_F, ROW_F = 0.32, 0.34 - local row_n = #TEMPS + 1 -- VRAM + FAN - local S_h = inner.h * 0.94 / (2.088 + row_n * 0.646) + local row_n = #TEMPS + 2 -- VRAM + MEM + FAN + local S_h = inner.h * 0.94 / (2.088 + row_n * 0.646 + 0.3) -- + MEM bar local groups = { { { card.title_str(card.ICON.gpu, 'GPU'), card.FONT_MONO, LABEL_F }, { big_txt, card.FONT_HEAVY, 1.0 } }, @@ -43,6 +53,8 @@ function M.draw(cr, rect, colors) groups[#groups + 1] = { { t[3], card.FONT_MONO, ROW_F }, { '888\u{00B0}', card.FONT_MONO, ROW_F } } end + groups[#groups + 1] = { { 'MEM', card.FONT_MONO, ROW_F }, + { '100%', card.FONT_MONO, ROW_F } } groups[#groups + 1] = { { 'FAN', card.FONT_MONO, ROW_F }, { '8888 RPM', card.FONT_MONO, ROW_F } } local S = clamp(math.min(S_h, card.fit_unit(cr, inner.w * 0.96, groups, 100)), 10, 72) @@ -80,6 +92,20 @@ function M.draw(cr, rect, colors) ey = ey + step end + -- VRAM as a fraction of the card's, a bar under the row like RAM in system. + local bar_h = S * 0.12 + if ey + step + bar_h + S * 0.1 <= inner.y + inner.h then + local frac = vram and vram / VRAM_TOTAL + local colour = frac and card.threshold(frac * 100, 25, 75, colors) or colors.label + card.rgba(cr, colors.label) + card.text(cr, inner.x, ey, 'MEM') + card.rgba(cr, colour) + card.text_right(cr, inner.x + inner.w, ey, + frac and string.format('%d%%', math.floor(frac * 100 + 0.5)) or '--') + card.bar(cr, inner.x, ey + row_size * 0.6, inner.w, bar_h, frac, colour, colors) + ey = ey + step + bar_h + S * 0.1 + end + -- Fan RPM is not a temperature, so it carries no threshold colour: a fast -- fan is the cooling working, not a fault. if ey + step <= inner.y + inner.h then |
