Detect Intel integrated graphics, which nvidia-smi cannot see

HOST2 has UHD Graphics 730 and reported no GPU at all. An iGPU has no VRAM,
no sensor of its own and no encode/decode split, so it is drawn from the
per-engine busy figures Intel actually publishes and the fields it lacks are
null rather than a confident zero.
This commit is contained in:
Gmer4Lfe
2026-08-21 08:23:14 -04:00
parent 4a29e7bc99
commit 00fdee5649
2 changed files with 135 additions and 9 deletions
+29 -8
View File
@@ -1789,11 +1789,23 @@ function vvPollMonitor(live) {
p.gpu_uuid ? p.gpu_uuid === gpu.uuid : (gpu.index ?? 0) === 0
);
const isIntel = gpu.vendor === 'intel';
const vramPct = gpu.memory_total > 0 ? Math.round(gpu.memory_used / gpu.memory_total * 100) : 0;
const utilPct = gpu.utilization ?? 0;
const temp = gpu.temperature ?? 0;
const tempColor = temp >= 85 ? '#f44336' : temp >= 70 ? '#ff9800' : '#4caf50';
const powerStr = gpu.power_w != null ? gpu.power_w + ' W' : '—';
// Package power when the GPU rail reads nothing, which is what Alder Lake reports. Labelled
// "Pkg" in that case rather than passed off as the GPU's own draw.
const powerStr = gpu.power_w != null ? gpu.power_w + ' W'
: (isIntel && gpu.package_w != null) ? gpu.package_w + ' W' : '—';
// Video first — it is the engine a hardware transcode uses, and this is a media server.
const engineOrder = ['Video', 'VideoEnhance', 'Render/3D', 'Blitter'];
const engines = gpu.engines ?? {};
const engineMeters = engineOrder
.filter(n => engines[n] != null)
.map(n => vvMeter(n === 'VideoEnhance' ? 'VideoEnh' : n, engines[n], `${engines[n]}%`))
.join('');
const procCount = gpuProcs.length;
const procColor = procCount > 0 ? '#4caf50' : '#555';
@@ -1822,14 +1834,23 @@ function vvPollMonitor(live) {
<div style="margin-left:8px;background:${procColor}22;border:1px solid ${procColor};color:${procColor};
padding:1px 8px;border-radius:10px;font-size:11px;white-space:nowrap;">${procCount} proc${procCount !== 1 ? 's' : ''}</div>
</div>` +
vvMeter('VRAM', vramPct, `${gpu.memory_used} / ${gpu.memory_total} MB`) +
vvMeter('GPU', utilPct, `${utilPct}%`) +
vvMeter('Encode', gpu.enc_pct ?? 0, `${gpu.enc_pct ?? 0}%`) +
vvMeter('Decode', gpu.dec_pct ?? 0, `${gpu.dec_pct ?? 0}%`) +
// An integrated GPU has no VRAM pool, no sensor of its own and no encode/decode split,
// so it is drawn from what Intel actually publishes — per-engine busy — rather than
// from nvidia's fields with zeros standing in for the ones it lacks. Video is listed
// first: on a media server it is the engine a hardware transcode uses.
(isIntel
? (gpu.utilization != null ? vvMeter('GPU', utilPct, `${utilPct}%`) : '')
+ engineMeters
: vvMeter('VRAM', vramPct, `${gpu.memory_used} / ${gpu.memory_total} MB`)
+ vvMeter('GPU', utilPct, `${utilPct}%`)
+ vvMeter('Encode', gpu.enc_pct ?? 0, `${gpu.enc_pct ?? 0}%`)
+ vvMeter('Decode', gpu.dec_pct ?? 0, `${gpu.dec_pct ?? 0}%`)
) +
`<div style="display:flex;justify-content:space-between;font-size:11px;margin-top:6px;margin-bottom:8px;">
<span style="color:#666;">Temp</span>
<span style="color:${tempColor};font-weight:bold;">${temp}°C</span>
<span style="color:#666;margin-left:12px;">Power</span>
${gpu.temperature != null
? `<span style="color:#666;">Temp</span><span style="color:${tempColor};font-weight:bold;">${temp}°C</span>`
: `<span style="color:#666;">Temp</span><span style="color:#555;">in CPU pkg</span>`}
<span style="color:#666;margin-left:12px;">${isIntel && gpu.power_w == null ? 'Pkg' : 'Power'}</span>
<span style="color:#aaa;font-weight:bold;">${powerStr}</span>
</div>` + gpuProcHtml;
};