FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GPU: show the PCI device-id on the scan screen; detect it on macOS by Epic34-cyberdudder · Pull Request #69 · riftaway7-code/hackmate · GitHub

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (5) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
8 changes: 6 additions & 2 deletions src/config_editor.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,12 @@ def set_smbios(cfg: dict, val: str) -> None:
}

def suggest_framebuffers(gpu_device_id: str) -> list[tuple[str, str]]:
"""Return list of (hex, label) suggestions for a GPU device ID."""
return IGPU_FRAMEBUFFERS.get(gpu_device_id.lower(), [])
"""Return list of (hex, label) suggestions for a GPU device ID.

Accepts any shape the detectors emit ('8086:5917', '0x5917', '5917').
"""
key = gpu_device_id.lower().replace("0x", "").rsplit(":", 1)[-1].strip()
return IGPU_FRAMEBUFFERS.get(key, [])

def get_igpu_platform_id(cfg: dict) -> str:
try:
Expand Down
12 changes: 9 additions & 3 deletions src/hackmate.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def _line(msg, ok=False, warn=False, header=False, grey=False):
print(f" {sys.executable} -m pip install textual\n")
sys.exit(1)

from hardware import scan, HardwareProfile, needs_dgpu_disable_prompt
from hardware import scan, HardwareProfile, needs_dgpu_disable_prompt, format_device_id
from kexts import select_kexts, get_alc_layout, alc_layout_is_known
from smbios import generate as gen_smbios
from config_gen import generate as gen_config, write_plist, _required_ssdts
Expand Down Expand Up @@ -1434,14 +1434,20 @@ def _show_results(self, profile: HardwareProfile) -> None:
kexts = select_kexts(profile, wifi_kext_mode=self.app.wifi_kext_mode)
layout = get_alc_layout(profile.audio_codec)
gen_suffix = f" (Gen {profile.cpu_generation})" if profile.cpu_vendor != "amd" else ""
gpu_id = format_device_id(profile.gpu_device_id)
dgpu_id = format_device_id(profile.dgpu_device_id)
lines = [
f" CPU {profile.cpu_name}",
f" Codename {profile.cpu_codename}{gen_suffix}",
f" Platform {profile.platform} — {profile.oc_platform}",
f" GPU {profile.gpu_name} [{profile.gpu_vendor}]",
f" GPU {profile.gpu_name} [{profile.gpu_vendor}]"
+ (f" — device-id {gpu_id}" if gpu_id else ""),
]
if profile.dgpu_name:
lines.append(f" dGPU {profile.dgpu_name} [{profile.dgpu_vendor}]")
lines.append(
f" dGPU {profile.dgpu_name} [{profile.dgpu_vendor}]"
+ (f" — device-id {dgpu_id}" if dgpu_id else "")
)
lines += [
f" Audio {profile.audio_name} / codec: {profile.audio_codec} → layout-id {layout}",
f" Ethernet {profile.ethernet_name or 'None'}",
Expand Down
12 changes: 9 additions & 3 deletions src/hackmate_gui.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
require_admin()

from hardware import (
scan, HardwareProfile, needs_dgpu_disable_prompt,
scan, HardwareProfile, needs_dgpu_disable_prompt, format_device_id,
CPU_OPTIONS, GPU_OPTIONS, ETHERNET_OPTIONS, WIFI_OPTIONS, CPU_META,
)
from kexts import select_kexts, get_alc_layout, alc_layout_is_known
Expand Down Expand Up @@ -633,14 +633,20 @@ def _show_results(self, profile: HardwareProfile):
kexts = select_kexts(profile, wifi_kext_mode=self.app.wifi_kext_mode)
layout = get_alc_layout(profile.audio_codec)
gen_suffix = f" (Gen {profile.cpu_generation})" if profile.cpu_vendor != "amd" else ""
gpu_id = format_device_id(profile.gpu_device_id)
dgpu_id = format_device_id(profile.dgpu_device_id)
lines = [
f" CPU {profile.cpu_name}",
f" Codename {profile.cpu_codename}{gen_suffix}",
f" Platform {profile.platform} — {profile.oc_platform}",
f" GPU {profile.gpu_name} [{profile.gpu_vendor}]",
f" GPU {profile.gpu_name} [{profile.gpu_vendor}]"
+ (f" — device-id {gpu_id}" if gpu_id else ""),
]
if profile.dgpu_name:
lines.append(f" dGPU {profile.dgpu_name} [{profile.dgpu_vendor}]")
lines.append(
f" dGPU {profile.dgpu_name} [{profile.dgpu_vendor}]"
+ (f" — device-id {dgpu_id}" if dgpu_id else "")
)
lines += [
f" Audio {profile.audio_name} / codec: {profile.audio_codec} → layout-id {layout}",
f" Ethernet {profile.ethernet_name or 'None'}",
Expand Down
53 changes: 50 additions & 3 deletions src/hardware.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,25 @@ class HardwareProfile:

raw_pci: list = field(default_factory=list)


def pci_id_device_part(raw: str) -> str:
"""Bare 4-hex device id from whatever shape a per-OS detector stored:
'8086:5917' / '0x5917' / '5917' / '1002:73FF' -> '5917' / '73ff' (lowercase).
Used for lookups keyed on the device id alone (INTEL_GENERATIONS, framebuffers)."""
return raw.lower().replace("0x", "").rsplit(":", 1)[-1].strip()


def format_device_id(raw: str) -> str:
"""Readable PCI id for the scan screen. Keeps 'vendor:device' when the
vendor is known, otherwise just the device id — always lowercase."""
if not raw:
return ""
parts = [p.strip() for p in raw.lower().replace("0x", "").split(":") if p.strip()]
if len(parts) >= 2:
return f"{parts[0]}:{parts[1]}"
return parts[0] if parts else ""


def needs_dgpu_disable_prompt(profile: HardwareProfile) -> bool:
return bool(
profile.dgpu_vendor
Expand Down Expand Up @@ -448,7 +467,7 @@ def _detect_cpu_windows(profile: HardwareProfile):
profile.cpu_codename = codename or "Unknown"

if profile.gpu_device_id:
dev_id = profile.gpu_device_id.lower()
dev_id = pci_id_device_part(profile.gpu_device_id)
if dev_id in INTEL_GENERATIONS:
gen, codename, oc_platform = INTEL_GENERATIONS[dev_id]
profile.cpu_generation = gen
Expand Down Expand Up @@ -1196,27 +1215,51 @@ def _detect_gpu_macos(profile: HardwareProfile):
sp = _sp("SPDisplaysDataType")
intel_name = ""
discrete_name = discrete_vendor = ""
cur = "" # bucket the following id lines belong to
ven = {"intel": "", "discrete": ""}
dev = {"intel": "", "discrete": ""}
for line in sp.splitlines():
line = line.strip()
if not line:
continue
lower = line.lower()
name = line.split(":")[-1].strip() if ":" in line else line

# "Vendor: AMD (0x1002)" / "Vendor ID: 0x1002" / "Device ID: 0x73bf"
# belong to whichever GPU block is currently being read.
if cur and ("device id" in lower or "vendor id" in lower or lower.startswith("vendor:")):
m = re.search(r"0x([0-9a-f]{2,4})", lower)
if m:
target = dev if "device id" in lower else ven
target[cur] = m.group(1).zfill(4)
continue

name = line.split(":", 1)[-1].strip() if ":" in line else line
if "intel" in lower and ("uhd" in lower or "iris" in lower or "hd graphics" in lower):
cur = "intel"
if not intel_name:
intel_name = name
elif "amd" in lower or "radeon" in lower:
cur = "discrete"
if not discrete_name:
discrete_name, discrete_vendor = name, "amd"
elif "nvidia" in lower or "geforce" in lower:
cur = "discrete"
if not discrete_name:
discrete_name, discrete_vendor = name, "nvidia"

def _id(bucket: str) -> str:
if dev[bucket] and ven[bucket]:
return f"{ven[bucket]}:{dev[bucket]}"
return dev[bucket]

if intel_name:
profile.gpu_name, profile.gpu_vendor = intel_name, "intel"
profile.gpu_device_id = _id("intel")
profile.dgpu_name, profile.dgpu_vendor = discrete_name, discrete_vendor
profile.dgpu_device_id = _id("discrete")
elif discrete_name:
profile.gpu_name, profile.gpu_vendor = discrete_name, discrete_vendor
profile.gpu_device_id = _id("discrete")

_NOT_ONBOARD_AUDIO = (
"blackhole", "existential audio", "soundflower", "loopback",
Expand Down Expand Up @@ -1355,7 +1398,11 @@ def scan() -> HardwareProfile:
print(f"Codename: {p.cpu_codename} (Gen {p.cpu_generation})")
print(f"Platform: {p.platform}")
print(f"OC Target: {p.oc_platform}")
print(f"GPU: {p.gpu_name} [{p.gpu_vendor}]")
print(f"GPU: {p.gpu_name} [{p.gpu_vendor}]"
+ (f" device-id {format_device_id(p.gpu_device_id)}" if p.gpu_device_id else ""))
if p.dgpu_name:
print(f"dGPU: {p.dgpu_name} [{p.dgpu_vendor}]"
+ (f" device-id {format_device_id(p.dgpu_device_id)}" if p.dgpu_device_id else ""))
print(f"Audio: {p.audio_name} / codec: {p.audio_codec}")
print(f"Ethernet: {p.ethernet_name} [{p.ethernet_chipset}]")
print(f"WiFi: {p.wifi_name} [{p.wifi_chipset}]")
Expand Down
62 changes: 62 additions & 0 deletions tests/test_hardware.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,68 @@ def test_generic_lspci_name_is_resolved_via_bundled_pci_ids(self):
self.assertEqual(profile.gpu_vendor, "intel")


class DeviceIdFormatTests(unittest.TestCase):
def test_format_device_id_keeps_vendor_when_present(self):
self.assertEqual(hardware.format_device_id("8086:5917"), "8086:5917")
self.assertEqual(hardware.format_device_id("0x1002:0x73BF"), "1002:73bf")

def test_format_device_id_bare_and_prefixed(self):
self.assertEqual(hardware.format_device_id("591B"), "591b")
self.assertEqual(hardware.format_device_id("0x5917"), "5917")
self.assertEqual(hardware.format_device_id(""), "")

def test_pci_id_device_part_strips_vendor_and_prefix(self):
self.assertEqual(hardware.pci_id_device_part("8086:5917"), "5917")
self.assertEqual(hardware.pci_id_device_part("0x5917"), "5917")
self.assertEqual(hardware.pci_id_device_part("1002:73FF"), "73ff")


class MacosGpuDeviceIdTests(unittest.TestCase):
_SP = (
"Graphics/Displays:\n\n"
" Intel UHD Graphics 620:\n\n"
" Chipset Model: Intel UHD Graphics 620\n"
" Type: GPU\n"
" Bus: Built-In\n"
" Vendor: Intel (0x8086)\n"
" Device ID: 0x5917\n"
" Revision ID: 0x0007\n\n"
" AMD Radeon RX 6800 XT:\n\n"
" Chipset Model: AMD Radeon RX 6800 XT\n"
" Type: GPU\n"
" Bus: PCIe\n"
" Vendor: AMD (0x1002)\n"
" Device ID: 0x73bf\n"
" Revision ID: 0x00c0\n"
)

def test_igpu_and_dgpu_device_ids_are_parsed_and_bucketed(self):
profile = hardware.HardwareProfile()
with patch.object(hardware, "_sp", return_value=self._SP):
hardware._detect_gpu_macos(profile)

self.assertEqual(profile.gpu_name, "Intel UHD Graphics 620")
self.assertEqual(profile.gpu_device_id, "8086:5917")
self.assertEqual(profile.dgpu_name, "AMD Radeon RX 6800 XT")
self.assertEqual(profile.dgpu_vendor, "amd")
self.assertEqual(profile.dgpu_device_id, "1002:73bf")

def test_single_discrete_gpu_lands_in_primary_slot_with_its_id(self):
sp = (
"Graphics/Displays:\n\n"
" AMD Radeon RX 6800 XT:\n\n"
" Chipset Model: AMD Radeon RX 6800 XT\n"
" Vendor: AMD (0x1002)\n"
" Device ID: 0x73bf\n"
)
profile = hardware.HardwareProfile()
with patch.object(hardware, "_sp", return_value=sp):
hardware._detect_gpu_macos(profile)

self.assertEqual(profile.gpu_vendor, "amd")
self.assertEqual(profile.gpu_device_id, "1002:73bf")


class SmbiosGenerationMatchTests(unittest.TestCase):
def test_zen_2_laptop_uses_amd_smbios(self):
profile = hardware.HardwareProfile(
Expand Down

Back | FazBrowse Home | New Git URL