watchthelight labs

Intel GPU: kernel driver attach (i915/xe) and Metal on Intel #18

openarea:gpu
watchthelight 2026-10-21

Later stage: claim the iGPU for rendering without losing the panel, then Mesa ANV through the Metal plugin. ANV compiles and links on Tahoe (link only). Parent: #12

watchthelight 2026-10-21

Code review of the Intel Metal path (reading only, nothing run), blockers that remain even once the GPU is claimed:

  1. ANV maps buffers with plain mmap(2) (anv_kmd_backend.c i915/xe gem_mmap); a macOS device node cannot be mmapped, so this needs the node-ioctl mapping on Darwin.
  2. libdrm finds render nodes by device minor; clone/first-free minors on macOS do not match renderD128, so enumeration returns no device.
  3. The i915 backend requires dma-buf sync-file support at probe (i915_gem_supports_dma_buf_sync_file); without PRIME export ANV returns VK_ERROR_INCOMPATIBLE_DRIVER. Darwin should skip it and hide the sync-fd extensions.
  4. The Metal plugin refuses WindowServer on non-NVIDIA vendors and pins one vendor per process; with two accelerators the first one enumerated decides.
  5. NVAccel only treats head 0 as its primary framebuffer; a lone head 4 (muxless laptops, NVIDIA without display engine) never gets a display pipe, VRAM or GPU addresses.
    None of these show up in drm-shim tests. Order of fixes: node minors and mmap, then the dma-buf probe, then the plugin vendor rule, then NVAccel's head-0 assumption.
watchthelight 2026-10-21

Kernel driver review (i915/xe on a LinuxKPI layer, checked against drm-kmod c16de0f9fa84, Linux 6.14 xe and XNU IOServicePM; details with exact locations go to nullmoth directly, his tree is private):

  1. Meteor/Arrow Lake attach ("none took it"): xe registers last, so the driver-ID search returned xe for the vgapci offer (xe lists MTL/ARL IDs behind force_probe), and the FreeBSD-style probe then silently returned ENXIO for i915. i915 itself accepts these parts (mtl_info has no force_probe). The newer source fixes the search; the 7D55 spoof changed nothing because 7D55 is in xe's table too.
  2. "stolen memory 0x0" is harmless: on display 14 config 0xC0/0x5C read 0 (confirmed on this Legion); i915 takes stolen memory from MMIO DSMBASE through the stolen-LMEM path, not that value.
  3. disable_display does not leave the panel alone: in this i915 base it still runs power-domain init, DMC, cdclk, VGA disable, output setup, PPS, hw-state sanitize and the initial plane takeover, then reports every DP/eDP connector disconnected. That matches "screen still dark".
  4. IOKit power glue runs i915's resume on a live device: the first power state is On without kIOPMInitialDeviceState, so IOKit calls setPowerState(1) right after attach, which forwards to i915 resume: engine reset, GGTT rebind, DMC resume, drm_mode_config_reset (drops the adopted BIOS framebuffer) and display re-init. Fix: mark the initial state with kIOPMInitialDeviceState and only forward a resume after a forwarded suspend.
  5. Ruled out: a GGTT scrub blacking the panel (Gen8+ clear_range is a no-op).
    Next failures forecast: on Arrow Lake the console-on-this-GPU check looks in the BARs and misses the stolen-memory framebuffer (same cause as #14); drm-kmod defaults enable_guc=0, so MTL/ARL would run execlists without SLPC/HuC, where Linux here runs GuC 70.53 submission + SLPC.

Reply on GitHub