aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-04 18:52:40 +0200
committerDanilo M. <danix@danix.xyz>2026-10-04 18:52:40 +0200
commit416fa4876018e5fbb9c3f537ea9c353d1d8b9982 (patch)
treeba72117f5a7a8dda2cbe65614b410e6ba2bd4d09 /lib
parent96ac1ee65da31055704e0a14cafacc33914d7e86 (diff)
downloadconky-theme-udt-416fa4876018e5fbb9c3f537ea9c353d1d8b9982.tar.gz
conky-theme-udt-416fa4876018e5fbb9c3f537ea9c353d1d8b9982.zip
feat(gpu): show VRAM in use as a bar with a percentage
Sum drm-resident-vram0 from DRM fdinfo, the same per-client counters gputop reads, counting each drm-client-id once since a client repeats its totals on every fd it holds. One grep over /proc/*/fdinfo, about 10ms warm, sampled through new_gate every ~2s. The 12 GiB total is hardcoded: xe exposes no VRAM capacity in sysfs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/data.lua41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/data.lua b/lib/data.lua
index 7ae96a7..d02d0f7 100644
--- a/lib/data.lua
+++ b/lib/data.lua
@@ -690,4 +690,45 @@ function M.nvtable_parse(text)
return seen and out or nil
end
+-- VRAM in use on an xe device, in bytes, from DRM fdinfo: the same source
+-- gputop reads. Input is `grep -H` output, one 'path:key:<tab>value' line per
+-- field, so fields are grouped by the fd file they came from.
+--
+-- One client (drm-client-id) is usually open on several fds, each repeating
+-- the client's full totals, so clients are counted once, not fds. Buffers
+-- shared between clients are still counted in each, as gputop does.
+local UNIT = { B = 1, KiB = 1024, MiB = 1024 ^ 2, GiB = 1024 ^ 3 }
+
+function M.drm_vram_parse(text)
+ if type(text) ~= 'string' then return nil end
+ local fds = {}
+ for path, key, val in text:gmatch('([^\n]-):(drm%-[%w%-]+):%s*([^\n]*)') do
+ local fd = fds[path] or {}
+ fds[path] = fd
+ fd[key] = val
+ end
+ local seen, total = {}, nil
+ for _, fd in pairs(fds) do
+ local id = fd['drm-client-id']
+ local n, unit = (fd['drm-resident-vram0'] or ''):match('^(%d+)%s*(%a*)')
+ if fd['drm-driver'] == 'xe' and id and n and not seen[id] then
+ seen[id] = true
+ total = (total or 0) + tonumber(n) * (UNIT[unit ~= '' and unit or 'B'] or 1)
+ end
+ end
+ return total
+end
+
+-- ponytail: a popen per call, ~10ms warm; callers gate it. Only fds of
+-- processes readable by conky's user are seen, so another user's GPU client
+-- (a system service) is not counted.
+function M.drm_vram()
+ local p = io.popen("grep -sH -e '^drm-driver' -e '^drm-client-id'"
+ .. " -e '^drm-resident-vram0' /proc/[0-9]*/fdinfo/* 2>/dev/null")
+ if not p then return nil end
+ local out = p:read('*a')
+ p:close()
+ return M.drm_vram_parse(out)
+end
+
return M