aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/gpu.lua
blob: 5f289a09a65473ad7b3706f633bf5d96f53bac00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
-- GPU: Arc B580 temperatures 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.
--
-- The integrated AMD GPU does expose gpu_busy_percent and is deliberately not
-- shown: the discrete card is the one in use.

local card = require 'lib.card'
local data = require 'lib.data'

local M = {}

-- chip, file, label, warn, crit
local TEMPS = {
  { 'xe', 'temp2_input', 'PKG',  75, 85 },
  { 'xe', 'temp3_input', 'VRAM', 80, 90 },
}

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

  local label_size = clamp(inner.w * 0.030, 11, 18)
  local big_size   = clamp(inner.w * 0.085, 26, 56)
  local row_size   = clamp(inner.w * 0.030, 11, 17)

  local y = inner.y

  card.font(cr, card.FONT_MONO, label_size, false)
  card.rgba(cr, colors.label)
  card.text(cr, inner.x, y + label_size, 'GPU')
  card.rgba(cr, colors.value)
  card.text_right(cr, inner.x + inner.w, y + label_size, 'ARC B580')

  -- The package temperature is the headline, since there is no load to show.
  local pkg = data.sensor('xe', 'temp2_input')
  card.font(cr, card.FONT_HEAVY, big_size, false)
  card.rgba(cr, pkg and card.threshold(pkg, 75, 85, colors) or colors.label)
  card.text(cr, inner.x, y + label_size + big_size,
    pkg and string.format('%d\u{00B0}', pkg) or '--')

  local ey = y + label_size + big_size + 18
  local step = row_size * 1.9

  card.font(cr, card.FONT_MONO, row_size, false)
  for _, t in ipairs(TEMPS) do
    if ey + step > inner.y + inner.h then break end
    local v = data.sensor(t[1], t[2])
    card.rgba(cr, colors.label)
    card.text(cr, inner.x, ey, t[3])
    card.rgba(cr, v and card.threshold(v, t[4], t[5], colors) or colors.label)
    card.text_right(cr, inner.x + inner.w, ey,
      v and string.format('%d\u{00B0}', v) or '--')
    ey = ey + step
  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
    local rpm = data.sensor_raw('xe', 'fan1_input')
    card.rgba(cr, colors.label)
    card.text(cr, inner.x, ey, 'FAN')
    card.rgba(cr, colors.value)
    card.text_right(cr, inner.x + inner.w, ey,
      rpm and string.format('%d RPM', rpm) or '--')
  end
end

return M