fix(nesdoctor): every Mac reported gpu=unknown, because the probe had no macOS arm

Seen in the macOS CI log:

  nesdoctor 0.2.2 | macos/aarch64 | gpu=unknown | ...

`gpus()` had a Linux arm, a Windows arm, and `Vec::new()` for everything else.
Macs are clients rather than hosts, so it went unnoticed -- but 0041 wants a
client vendor matrix and an unlabelled row is no use in one. An M-series
integrated GPU and a discrete Radeon in an Intel Mac decode very differently,
and "unknown" cannot tell them apart.

`system_profiler SPDisplaysDataType` is the only place the chipset name lives.
Parsed loosely: the format has changed between macOS releases, so a name we
cannot find costs a field rather than the run. Vendor is matched over Apple,
AMD, Radeon, NVIDIA and Intel; `render_node` stays `None` because macOS has
none and a Mac cannot host regardless.

Still missing on macOS and stated rather than papered over: filesystem types
and the display probe. The EDID path is sysfs on Linux and WMI on Windows, and
macOS exposes neither -- so Mac respondents report no colour depth or HDR
capability. That is a real gap for the video work, since Mac panels are exactly
the P3 and high-refresh cases worth knowing about, and it needs
`CoreDisplay`/`system_profiler` parsing rather than a one-line fix.
This commit is contained in:
Wanjohi
2026-09-02 16:25:09 +03:00
parent 53d69ca289
commit 0f26df5c02

View File

@@ -252,7 +252,50 @@ fn gpus() -> Vec<Gpu> {
out.sort_by_key(|g| (is_virtual_adapter(&g.name), g.vendor.is_none()));
return out;
}
#[cfg(not(any(target_os = "linux", windows)))]
#[cfg(target_os = "macos")]
{
// Every Mac reported `gpu=unknown`, because this arm did not exist --
// seen in the macOS CI log. Macs are clients rather than hosts, but
// 0041 wants a client vendor matrix and an unlabelled entry is no use
// in one: an M-series integrated GPU and a discrete Radeon in an Intel
// Mac decode very differently.
//
// `SPDisplaysDataType` is the only place the chipset name lives.
// Parsed loosely on purpose: the format has changed between macOS
// releases and a missing name should cost a field.
let out = sh("system_profiler", &["SPDisplaysDataType"]).unwrap_or_default();
let mut gpus = Vec::new();
for line in out.lines() {
let l = line.trim();
if let Some(name) = l
.strip_prefix("Chipset Model:")
.or_else(|| l.strip_prefix("Chipset:"))
{
let name = name.trim();
if name.is_empty() {
continue;
}
let up = name.to_uppercase();
gpus.push(Gpu {
name: name.to_string(),
vendor: [
("APPLE", "Apple"),
("AMD", "AMD"),
("RADEON", "AMD"),
("NVIDIA", "NVIDIA"),
("INTEL", "Intel"),
]
.into_iter()
.find(|(needle, _)| up.contains(needle))
.map(|(_, v)| v.to_string()),
// macOS has no DRM render nodes; a Mac cannot host anyway.
render_node: None,
});
}
}
return gpus;
}
#[cfg(not(any(target_os = "linux", windows, target_os = "macos")))]
return Vec::new();
}