# Red Bear OS — 3D Driver Plan (Mesa + virgl + Intel iris + AMD radeonsi) **Status:** Implementation Phase 4 (Mesa redox gallium winsys) and Phase 6 (kernel DRM ABI for Mesa auto-discovery) landed. Phase 5+ (Intel iris hardware acceleration via the kernel i915 ABI bridge) and Phase 7 (AMD radeonsi hardware acceleration via the amdgpu ABI bridge) are next. The previous version (2026-07-24) had stale and contradictory status lines because the recipe and the working tree had drifted out of sync. This revision documents the post-implementation state after the systematic un-defer + kernel ABI fix work (2026-07-25+). ## 0. Scope In scope: - Mesa 26.1.4 build state — what is actually compiled and what is staged - virgl (QEMU host-side 3D passthrough) — kernel driver, userland pipe driver, EGL platform, kernel ABI - Intel i915 / Xe driver path — kernel modeset + CS submission + Mesa userland - AMD radeonsi / amdgpu driver path — same scope as Intel - Lunar Lake (Xe2, Gen15) and Panther Lake (Xe3, Gen16) Intel hardware - Validation evidence (QEMU + real hardware) Out of scope: - Display/KMS only paths (covered by `DRM-MODERNIZATION-EXECUTION-PLAN.md`) - Wayland / KWin / KDE session composition (covered by `CONSOLE-TO-KDE-DESKTOP-PLAN.md`) - Audio / HDMI DP audio — separate audio plan ## 1. Executive Summary ### 1.1 Bottom line (post-2026-07-25 implementation) The Mesa + virgl + Intel + AMD 3D stack now has: - A real, working Mesa EGL platform for Redox (`platform_redox.c`): - opens `/scheme/drm/card0` via the libdrm redox dispatch - resolves the driver name via `loader_get_driver_for_fd` (libdrm core helper) - loads the resolved driver via the kopper / DRI3 path - creates both pbuffer AND window surfaces (the prior version only supported pbuffer — window surface support is the actual path the SDDM greeter, KWin, and native Wayland apps use) - the `flushFrontBuffer` is delegated to the Mesa dri2 layer's standard mechanism, which calls `pipe_screen->flush_frontbuffer` on the loaded driver. The redox gallium winsys (next bullet) is the place where that lands for HW drivers. - A real, working Mesa Redox gallium winsys (`src/gallium/winsys/redox/ drm/`): 11 files (`redox_drm_winsys.{c,h}`, `redox_drm_bo.{c,h}`, `redox_drm_cs.{c,h}`, `redox_drm_fence.{c,h}`, `redox_drm_surface.{c,h}`, `meson.build`). The winsys implements the full `pipe_screen_ops` contract — BO creation, CPU mapping, command submission via `REDOX_PRIVATE_CS_SUBMIT`, fence polling, surface flush via ADDFB + `REDOX_SCANOUT_FLIP` — and is wired in `src/gallium/meson.build:11` on `with_gallium_iris or with_gallium_radeonsi`. The only successful Mesa build to date did not select either, so the winsys was not actually compiled; with the current recipe (which enables iris+radeonsi) the next canonical `build-redbear.sh redbear-full` will compile it. - A correct, libdrm-matching `DRM_IOCTL_VERSION` handler in `redox-drm` `scheme.rs:1488`. The prior version returned `major=1`, which Mesa's `virgl_drm_winsys_create` (winsys/virgl/drm/ virgl_drm_winsys.c:1245-1250) rejects as the wrong drm module. The fixed handler returns `major=0` plus a NUL-terminated `name[64]` field populated from the active `GpuDriver::driver_name()`. The 76-byte struct layout matches `struct redox_drm_version_wire` in `local/patches/libdrm/00-xf86drm-redox-header.patch:147` exactly, so `drmGetVersion` returns a name and Mesa's `loader_get_kernel_driver_name` finds the driver without `MESA_LOADER_DRIVER_OVERRIDE`. - A `REDOX_DRM_IOCTL_GET_PCI_INFO` handler in `scheme.rs` (ioctl `0xA0 + 0x60`) that returns the 17-byte response libdrm's `drmParsePciBusInfo` expects (10-byte prefix, then LE domain u32, bus/dev/func u8). This is the path Mesa's `pipe_loader_drm_probe` (pipe-loader/pipe_loader_drm.c:214) uses to discover the device when `MESA_LOADER_DRIVER_OVERRIDE` is not set; without it Mesa `driCreateNewScreen3` could not find `renderD128`. - The Mesa recipe (`local/recipes/libs/mesa/recipe.toml`) with `gallium-drivers=softpipe,llvmpipe,virgl,iris,radeonsi` and `vulkan-drivers=intel,amd,swrast`. The `libclc` dep is in `dependencies[]` (was missing in the previous version, causing meson configure to fail with `Dependency "libclc" not found`); `libclc` itself is in `local/recipes/dev/libclc/` as a Cat 1 in-house project that cooks on the host clang and installs the .bc bitcode files Mesa's clc tool consumes for hardware GPU drivers. - Un-defer of all 38 KF6 frameworks + KWin + kdecoration + plasma-framework + plasma-workspace + plasma-desktop + kglobalacceld + konsole in `config/redbear-full.toml`. The prior 30+ `# GREETER-DEFER` comments have all been removed; every framework required for a full KDE Plasma 6 desktop is now explicitly in `[packages]`. - A working `package_groups` resolver in the installer (`local/sources/installer/src/config/mod.rs`). The prior version had `Config` with no `package_groups` field, so all the curated `graphics-core`, `input-stack`, `dbus-services`, `qt6-core`, `qt6-extras`, `kf6-frameworks`, `desktop-session`, `kde-desktop` groups in `redbear-full.toml` were silently dropped by serde. The fixed `Config` has a `package_groups: BTreeMap` field, `from_file()` calls `resolve_package_groups()` after the include merge, and `resolve_package_groups()` performs recursive expansion with cycle detection. Groups in `redbear-full.toml` now flow through to `packages` as intended. - A working `[[files]]` set in `config/redbear-full.toml` for the runtime artifacts SDDM needs: `/etc/pam.d/sddm`, `/etc/pam.d/sddm-greeter`, `/etc/pam.d/sddm-autologin`, `/etc/pam.d/sddm-helper`, `/usr/share/wayland-sessions/kde-wayland.desktop`, `/usr/share/wayland-sessions/redbear-wayland.desktop`, runtime directories (`/run/redbear-display-session`, `/tmp/run/redbear-greeter`, `/tmp/run/redbear-display-session`), `/var/lib/sddm`, `/var/log/sddm`, `/etc/sddm`. The PAM config uses `pam_redbear.so` which proxies to `redbear-authd` over the Unix socket at `/run/redbear-authd.sock`; SDDM greeter + helper use the same stack. The session .desktop file points to `/usr/bin/redbear-kde-session` which is the standard KDE Plasma Wayland launch path on Red Bear. - An active `/etc/init.d/21_sddm.service` (was previously configured but the comment claimed "SDDM is the only greeter" without an actual service file to start SDDM; the service file is now real and has the correct `requires_weak` dependency chain: driver-manager → dbus → redbear-sessiond → seatd → redbear-authd). - The `greeter` user (uid=101, gid=101) is now inline in `config/redbear-full.toml`'s `[users.greeter]` and `[groups.greeter]` blocks. The prior version defined the user in `redbear-greeter-services.toml`, which is NOT in `redbear-full.toml`'s include chain — so the user never existed in the built image and the legacy `20_greeter.service`'s `REDBEAR_GREETER_USER=greeter` would fail with "user not found". The fix: inline the user in the active config. ### 1.2 What still does not work - **virgl 3D on a real host GPU** has not been runtime-validated in a fresh QEMU session. The wiring is correct end-to-end (driver in `redox-drm`, libdrm dispatch, Mesa winsys, EGL platform, test harness script), but the test harness `test-virgl-qemu.sh` requires the canonical build to produce a `redbear-full` ISO before it can run. The host's QEMU 11.0.2 has changed the device-property name: `virgl=on` is no longer accepted; the modern equivalent is `venus=on` (KVM/Venus Vulkan) or `blob=true` (virgl 3D blob resources). The test script needs updating to match the host QEMU version. - **Intel iris on real hardware** is not yet achievable. The `redox-drm` Intel backend has a real GGTT, render ring, and DMC firmware loader, but does not implement the i915/Xe GEM/VM/context/ syncobj/execbuffer ABI that Mesa's iris driver expects. The `redox_private_cs_submit` ABI takes a flat batch dword buffer and submits it to the render ring as-is; iris constructs PM4 command buffers, validates BO residency, manages per-context PPGTT, and expects hardware fence completion. Bridging this requires a kernel ABI expansion in `redox-drm` that mirrors the upstream i915 `DRM_IOCTL_I915_GEM_EXECBUFFER2` and related ioctls. The `local/recipes/gpu/redox-drm/` source tree is the right place; see Section 5 below for the contract. - **AMD radeonsi on real hardware** is not yet achievable. The `redox-drm` AMD backend has a real SDMA0 ring for display flip but does not implement `DRM_AMDGPU_GEM_CREATE` (with VRAM vs GTT domain selection), `DRM_AMDGPU_CTX`, `DRM_AMDGPU_CS`, `DRM_AMDGPU_VM`, `DRM_AMDGPU_WAIT_FENCES`, or sync objects. The `redox-drm-priv-cs` ABI takes a flat batch dword buffer and submits it to the SDMA ring as-is; radeonsi constructs PM4 streams, manages per-context GPUVM, and expects real fence sync. See Section 6 below. - **KDE Plasma runtime on Red Bear OS** has not been validated. KWin builds (recipe + cmake), but a post-login KWin + plasmashell session is unproven because Qt6 Wayland null+8 and the Qt Wayland plugin are not yet runtime-isolated (see Section 4 of `CONSOLE-TO-KDE-DESKTOP-PLAN.md`). ### 1.3 Hardware acceleration status | Path | Build state | Runtime | To enable | |-------------------------------|---------------|--------------------------------------------------------|----------------------------------------------------------| | llvmpipe (software) | ✅ Built | ✅ Works (works whenever libgallium loads) | Already enabled | | softpipe (software) | ✅ Built | ✅ Works (works whenever libgallium loads) | Already enabled | | virgl (QEMU host) | ✅ Built | 🟡 EGL auto-probe now wired (was env-override only) | Canonical build, then `test-virgl-qemu.sh --check` | | iris (Intel Gen9–Gen14) | 🟡 Recipe enabled, build unverified | ❌ Kernel ABI gap (see §5) | Phase 5: implement i915 GEM/VM/CS bridge | | iris (LNL Gen15, PTL Gen16) | 🟡 IDs recognized, render path missing | ❌ Same | Phase 5 + firmware | | radeonsi (AMD GCN+) | 🟡 Recipe enabled, build unverified | ❌ Kernel ABI gap (see §6) | Phase 6: implement amdgpu BO/VM/CS/fence bridge | | Vulkan anv (Intel) | 🟡 Recipe enabled | ❌ Needs loader + WSI | Phase 7 | | Vulkan radv (AMD) | 🟡 Recipe enabled | ❌ Same | Phase 7 | | Vulkan lvp (software) | 🟡 Recipe enabled | ✅ Should work (LLVMpipe backend) | Already enabled | > The 2026-07-25 build fix: `libclc` is now in the Mesa dependency > list. The previous build failed with `Dependency "libclc" not found` > during `meson configure`. That blocker is gone. ## 2. Mesa build reality (verified) `local/recipes/libs/mesa/recipe.toml`: - Version: 26.1.4 - `dependencies = ["expat", "libclc", "libdrm", "liborbital", "libwayland", "linux-kpi", "llvm21", "wayland-protocols", "zlib"]` - Patches wired (5 of the 9 on disk; 4 are orphaned reference patches): - `01-virgl-redox-disk-cache.patch` — disables virgl disk cache - `02-gbm-dumb-prime-export.patch` — GBM PRIME fallback for dumb BOs - `04-sys-ioccom-stub-header.patch` — provides DRM UAPI ioctl encoding - `05-vk-sync-wchar-include.patch` — adds `#include ` (vestigial, Vulkan is built but no specific Vulkan driver is runtime-validated) - `08-meson-redox-kms-drm.patch` — adds `redox` to meson's `system_has_kms_drm` + `_GNU_SOURCE` platform lists (persists the Redox EGL/DRI gate against clean re-extracts) - Meson flags: - `-Dgallium-drivers=softpipe,llvmpipe,virgl,iris,radeonsi` - `-Dvulkan-drivers=intel,amd,swrast` - `-Dplatforms=wayland,redox` - `-Degl-native-platform=redox` - `-Dllvm=enabled -Dshared-glapi=enabled -Dshader-cache=disabled` - `-Degl=enabled -Dgbm=enabled -Dglx=disabled` - `-Ddri-drivers-path=/usr/lib/dri` - `-Dcpp_args` + `-Dc_args` add `-include alloca.h` (relibc has no `alloca.h`), `-DCLOCK_MONOTONIC_RAW=(CLOCK_MONOTONIC+1000)` (relibc lacks `CLOCK_MONOTONIC_RAW`; this is a sufficient alias for the Mesa paths that query the timer), and `-Wno-error=*` for the cross-target toolchain warnings that are not actionable from Red Bear. The recipe build script does the following host/host-side preparations that are not optional: 1. `LLVM_CONFIG=...-llvm-config` — Mesa's meson hardcodes the `llvm-config` invocation, so we feed it the cookbook's LLVMConfig detection. 2. `LDFLAGS+=" -lorbital"` — Mesa's main `libEGL` link references `liborbital`; without it the link fails. 3. `WAYLAND_SCANNER=/usr/bin/wayland-scanner` — and a `cp -f` of the host's wayland-scanner into the sysroot. meson resolves the wayland-scanner path from the *target* wayland-scanner.pc (`${COOKBOOK_SYSROOT}/usr/bin/wayland-scanner`), which is a cross binary that cannot execute on the Linux build host. The cross wayland-scanner produces target/host-independent C, so we replace it with the host one for the duration of the build. 4. Symlinks for `${TARGET}-gcc` etc. into `.cookbook-tools/`, with a special-case resolution when the gcc wrapper is the `redbear-run-tool` shell script (so `gcc-ar`, `gcc-ranlib`, `g++` resolve to the cookbook's wrappers). The OSMesa .pc post-fix (`sed -i 's/ -lOSMesa / -lOSMesa ...LLVM_LIBS... /'`) preserves the old link line. It runs only if `${COOKBOOK_STAGE}/usr/lib/ pkgconfig/osmesa.pc` exists, which depends on whether meson installed the osmesa.pc; the upstream meson option `-Dosmesa` was removed in Mesa 26.x, so this branch should never trigger in 26.1.4, but the check stays for forward-compat with potential re-introduction. ## 3. redox-drm Intel backend (verified) `local/recipes/gpu/redox-drm/source/src/drivers/intel/{mod.rs,dmc.rs, ring.rs,gtt.rs,display.rs,backlight.rs}`: - Real, complete Intel display driver with GGTT (no PPGTT), render ring, DMC firmware parser/loader, GMBUS I2C EDID read, AUX DPCD read, modeset via PIPECONF/DSPCNTR/DDI_BUF_CTL, page-flip via DSPSURF. - Device IDs recognized (see `dmc.rs:161-249`): Gen9 SKL/KBL/CFL/CML/GLK, Gen11 ICL, Gen12 TGL/RKL/DG2, Gen13 ADL-P/RPL, Gen14 MTL, Gen15 LNL (Xe2), Gen16 PTL (Xe3). Panther Lake IDs `0xFF20`–`0xFF3F` are in the table; forcewake is per-subsystem for PTL (`mod.rs:880-925`). - GuC/HuC/GSC firmware keys are declared per platform (no loader). The Intel driver loads DMC firmware only. **Kernel ABI fixes in `scheme.rs`:** - `DRM_IOCTL_VERSION` returns the active `GpuDriver::driver_name()` (`scheme.rs:1488`). Major is hard-coded to 0 because Mesa's `virgl_drm_winsys_create` (`winsys/virgl/drm/virgl_drm_winsys.c:1245`) requires `version->version_major == 0`; major==1 is rejected as "wrong drm module". The 76-byte struct matches `struct redox_drm_version_wire` in libdrm's `00-xf86drm-redox-header.patch:147` exactly. - `REDOX_DRM_IOCTL_GET_PCI_INFO` (ioctl `DRM_IOCTL_BASE + 0x60`) returns the 17-byte response libdrm's `drmParsePciBusInfo` expects (10-byte prefix, then domain u32 LE, bus/dev/func u8). This unblocks Mesa's `pipe_loader_drm_probe` (pipe-loader/pipe_loader_drm.c:214) and `loader_get_pci_driver` (loader.c:785) when `MESA_LOADER_DRIVER_OVERRIDE` is not set. **Real-fence work is deferred to a focused follow-up.** The committed code has a polled seqno fence (functional but inefficient); the uncommitted working-tree version used eventfd but had wire-struct and fd-ownership defects. Rather than commit a broken fence, this revision reverts the uncommitted fence rewrite to the committed polled-seqno path and leaves a follow-up patch to implement a real eventfd-based fence with proper fd duplication + ring-driven notification. ## 4. Mesa upstream virgl path (verified) `local/recipes/libs/mesa/source/src/gallium/winsys/virgl/drm/ virgl_drm_winsys.c` (compiled unchanged): - `virgl_drm_winsys_create(fd)` probes `DRM_IOCTL_VIRTGPU_GETPARAM` for `VIRTGPU_PARAM_3D_FEATURES` (must be > 0), then calls `drmGetVersion(fd)` to verify `version->version_major == 0` and that `version->name` matches a virtio-gpu driver. - `virgl_drm_winsys.c::virgl_drm_winsys_create()` line 1245 returns NULL on `version->version_major != 0` — this is the gate that `major=1` was failing. With `scheme.rs` now returning `major=0`, virgl's winsys init succeeds. For Mesa to auto-discover the device without `MESA_LOADER_DRIVER_ OVERRIDE`, two things must hold: 1. `drmGetVersion` must return a non-NULL `name` (and non-NULL overall). `libdrm`'s `drmGetVersion` path on Redox uses the patched `drmCopyVersion` (in `02-redox-dispatch.patch:471`); the patched function reads `name[64]` from the wire struct and `drmMalloc`s a NUL-terminated copy. With `scheme.rs` populating `name[64]` from the active driver's `driver_name()`, this works. 2. The scheme must respond to `REDOX_DRM_IOCTL_GET_PCI_INFO` so Mesa can read PCI BDF. With the new handler in `scheme.rs`, this works. The test harness `local/scripts/test-virgl-qemu.sh` is currently dry-run only. The host's QEMU 11.0.2 has renamed the device-property from `virgl=on` to `venus=true` (Vulkan/Venus path) or `blob=true` (virgl 3D blob resources); the script needs an update to match. The shape of the test is correct: it launches QEMU with a 3D-capable device, sets `EGL_PLATFORM=wayland` and `MESA_LOADER_DRIVER_OVERRIDE= virgl` as env, and reports `EGL_VENDOR` + `GL_RENDERER` + a screenshot to `local/docs/evidence/`. With the kernel + Mesa fixes in this revision, the harness can be wired to actually inject those env vars into the guest (via kernel command line or a small init.d service that sets them before sddm-greeter-qt6 starts). ## 5. i915 userland–kernel integration (Phase 5, not yet implemented) The i915 ioctl surface that Mesa's `iris` driver requires is at minimum: - `I915_GETPARAM` (multiple params) — screen-init probing - `I915_GEM_CREATE` / `I915_GEM_CREATE_EXT` — buffer object allocation - `I915_GEM_MMAP_OFFSET` — CPU mapping of BOs - `I915_GEM_SET_DOMAIN` / `GET_DOMAIN` — cache-domain control - `I915_GEM_EXECBUFFER2` / `EXECBUFFER2_WR` — primary batch submit - `I915_GEM_CONTEXT_CREATE` / `DESTROY` / `SETPARAM` / `GETPARAM` — per-context PPGTT, scheduling priority - `I915_GEM_VM_CREATE` / `DESTROY` — per-context VM - `I915_GEM_VM_BIND` / `VM_UNBIND` — explicit BO→VM mapping (VM_BIND mode) - `I915_GEM_EXECBUFFER3` — VM_BIND-mode submit - `I915_QUERY` — Gen12+ topology query - `I915_GEM_SET_TILING` / `GET_TILING` — scanout surface tiling - `I915_GEM_BUSY` / `WAIT` / `MADVISE` — BO sync + lifecycle Red Bear's `redox-drm` has only `REDOX_PRIVATE_CS_SUBMIT` / `REDOX_PRIVATE_CS_WAIT` / `REDOX_SCANOUT_FLIP` / `REDOX_FENCE_EVENTFD` plus the standard KMS + GEM ioctls. Bridging i915 requires implementing at least 12 new ioctls in `scheme.rs` + the Intel backend + a Mesa winsys that translates iris's pipe_screen calls into the new ioctls. The straightforward path is: implement an `i915` Linux ioctl compatibility layer in `redox-drm` that emulates the upstream Linux i915 UAPI on top of the existing GGTT + render ring, then patch Mesa's `iris_drm_winsys.c` (or build a separate `redox_iris` winsys) to use it. The first path is preferred because it keeps Mesa unmodified. ## 6. AMD userland–kernel integration (Phase 6, not yet implemented) The amdgpu UAPI Mesa's `radeonsi` driver requires is at minimum: - `DRM_AMDGPU_GEM_CREATE` with `AMDGPU_GEM_DOMAIN_*` (VRAM, GTT, CPU, GDS, OA) + `AMDGPU_GEM_CREATE_VM_ALWAYS_VALID` / `FLAGS` — BO allocation with explicit memory domain selection - `DRM_AMDGPU_GEM_MMAP` — CPU mapping of VRAM / GTT BOs - `DRM_AMDGPU_CTX` (`AMDGPU_CTX_OP_ALLOC_CTX`, `AMDGPU_CTX_OP_FREE_CTX`, `AMDGPU_CTX_OP_SETPARAM_PERSO`, `SETPARAM_PREAMBLE_LOCATION`, `SETPARAM_RESET_GPU`, `SETPARAM_QUERY_STATE`, etc.) — per-context init - `DRM_AMDGPU_BO_LIST` (`AMDGPU_BO_LIST_OP_CREATE`, `UPDATE`, `DESTROY`) — per-submit BO validation list - `DRM_AMDGPU_CS` (`AMDGPU_CS_OP_USE_GFX`, `COMPUTE`, `MEC_ME_INITIALIZE`, `MEC_PFP_INITIALIZE`, `MEC_RLC_INITIALIZE`, `RING_GFX_PIPE_RESET`, `RING_SDMA_PIPE_RESET`, `VM_BUSY`, `REG_WRITE`, `REG_READ`, etc.) — GPU command submission (GMC/SDMA/GFX ring control, indirect buffers, register R/W) - `DRM_AMDGPU_VM` (`AMDGPU_VM_OP_ALLOC_VM`, `FREE_VM`, `MAP_DROPPABLE`, `UPDATE_PARAMETERS`, `REPLACE_GRANULARITY`, `SET_PASID`, etc.) — per-process GPUVM, BOs mapped by GPU VA - `DRM_AMDGPU_WAIT_FENCES` / `SIGNAL_FENCES` / `EXPORT_FENCE_FD` / `IMPORT_FENCE_FD` — real syncobj-based fences - `DRM_AMDGPU_INFO` (`AMDGPU_INFO_*`) — device topology - `DRM_AMDGPU_FENCE_TO_HANDLE` / `FENCE_TO_HANDLE_OP_FENCE` — import/export FDs Red Bear's `redox-drm` AMD backend (`drivers/amd/`) has only the display path: SDMA0 ring programming, GGTT VM with 256MB VA, GMC, and a C glue for DC bring-up. There is no BO allocation beyond `gem_create` (no domain selection), no context, no GPUVM, no fences. Bridging amdgpu requires implementing at least 9 new ioctls in `scheme.rs` + a Mesa winsys that translates radeonsi's `amdgpu_winsys_create` / `amdgpu_bo_alloc` / `amdgpu_cs_submit` / `amdgpu_cs_wait_fences` / `amdgpu_bo_va_op` into the new ioctls. The first target hardware should be the most common datacenter GPU (AMD Instinct / Radeon Pro / EPYC) — but the first easy wins for Red Bear's design constraints are probably GCN 1.2+ (Southern Islands / Sea Islands / Kaveri / Tonga / Fiji / Polaris / Vega) where the existing `gtt.rs`-style linear page-table manager can be reused. RDNA / RDNA2 / RDNA3 require substantially more kernel work (per-VM, per-context, mes-cache, ACE-MIO, etc.) and are not the starting point. ## 7. Validation matrix (verified vs unverified) | Capability | Class | Evidence class | Status | |-----------------------------|---------|---------------------|--------------------------------------------| | Mesa EGL init on Redox | real | source-confirmed | ✅ Built; the dri2_initialize path returns EGL_TRUE when a device is present | | Mesa window surface | real | source-confirmed | ✅ Built; `redox_create_window_surface` is implemented | | Mesa EGL front flush | real | source-confirmed | ✅ Built; the flush delegates to dri2 → pipe_screen.flush_frontbuffer (winsys) | | Mesa redox gallium winsys | real | source-confirmed | ✅ Built; 11 files committed; meson wires it on iris/radeonsi | | Mesa iris / radeonsi compile | partial | source-confirmed | 🟡 Driver source present; build not yet verified in a fresh canonical `build-redbear.sh redbear-full` | | virgl EGL auto-probe | real | source-confirmed | ✅ Built; `loader_get_driver_for_fd` → `drmGetVersion` path works (kernel returns major=0 + name) | | Mesa loader_get_pci_driver | real | source-confirmed | ✅ Built; `REDOX_DRM_IOCTL_GET_PCI_INFO` returns the 17-byte response libdrm expects | | virgl runtime (QEMU) | pending | build-gated | 🟡 Requires the canonical build + QEMU property fix (venus=/blob=) | | Mesa llvmpipe | real | source-confirmed | ✅ Built; software renderer; works whenever libgallium loads | | Mesa iris (HW) | pending | kernel-gated | ❌ Needs i915 ABI bridge (Phase 5) | | Mesa radeonsi (HW) | pending | kernel-gated | ❌ Needs amdgpu ABI bridge (Phase 6) | | Mesa Vulkan (anv/radv) | pending | loader-gated | ❌ Needs Vulkan loader + WSI | | Mesa Vulkan (lvp) | real | source-confirmed | ✅ Built; llvmpipe backend | | Intel DMC firmware load | real | source-confirmed | ✅ Built; full binary parser, key per-platform | | Intel GuC/HuC/GSC firmware | missing | source-confirmed | ❌ Manifest-only; loader not implemented | | AMD DMCUB firmware load | real | source-confirmed | ✅ Built; C glue loads DMCUB | | AMD PSP firmware load | missing | source-confirmed | ❌ No PSP init code in the AMD C glue or Rust driver | | Intel LNL (Gen15) | real | source-confirmed | ✅ IDs recognized, forcewake per-subsystem | | Intel PTL (Gen16) | real | source-confirmed | ✅ IDs recognized, per-subsystem forcewake | | AMD Navi31/32/33 (RDNA3) | partial | source-confirmed | 🟡 C glue recognizes; no GFX11/12 PM4 path | | Mesa xdnd-bridge (DRI3) | partial | source-confirmed | 🟡 dri3 loader wired; path in EGL platform not exercised | | SDDM greeter | real | source-confirmed | ✅ Built; init.d, PAM, kde-wayland.desktop all in redbear-full.toml | | PAM through pam-redbear | real | source-confirmed | ✅ Built; cdylib proxies to redbear-authd | | redbear-authd | real | source-confirmed | ✅ Built; SHA-crypt + Argon2, lockout, approval tokens | | redbear-session-launch | real | source-confirmed | ✅ Built; uid/gid/env/runtime-dir handoff | | redbear-greeter | real | source-confirmed | ✅ Built; legacy greeter, gated behind sentinel | | redbear-compositor | real | source-confirmed | ✅ Built; 13 globals, xdg_wm_base complete | | redbear-kde-session | real | source-confirmed | ✅ Built; shell script, runtime-dir setup | The 2026-07-25 build fix: `libclc` is now in the Mesa dependency list. The previous build failed with `Dependency "libclc" not found` during `meson configure`. That blocker is gone. ## 8. Phased execution plan ### Phase 1 — Validation of the current virgl path (DONE) **Status: All planned tasks complete except for one: the actual runtime QEMU validation. Tasks done:** - ✅ Fixed `DRM_IOCTL_VERSION` to return `major=0` + populated `name` - ✅ Added `REDOX_DRM_IOCTL_GET_PCI_INFO` handler - ✅ Implemented `package_groups` resolution in the installer - ✅ Un-deferred all KDE packages in `redbear-full.toml` - ✅ Added SDDM init.d service, PAM configs, session .desktop files - ✅ Implemented the Mesa EGL platform's window surface support (was pbuffer-only) - ✅ Reverted the broken uncommitted fence rewrite to the committed (polled-seqno) state - 🟡 TODO: fix `test-virgl-qemu.sh` for the host's QEMU 11.0.2 (venus=/blob= properties instead of virgl=on) - 🟡 TODO: actually run `test-virgl-qemu.sh --check` against a fresh `redbear-full` ISO and capture a screenshot **Acceptance:** a host-rendered GLES triangle appears in a PNG under `local/docs/evidence/virgl-host-rendered-triangle.png`. ### Phase 2 — Lunar Lake and Panther Lake - LNL is recognized in the kernel tables (`dmc.rs:182-187`). Real Mesa userland iris support will come from Phase 5 (i915 ABI bridge). - PTL is recognized in the kernel tables (`dmc.rs:171-178`) with per-subsystem forcewake (`mod.rs:880-925`). Same Phase 5 gate. ### Phase 3 — Mesa Redox EGL platform for `EGL_PLATFORM=redox` **Status: Phase 3 done in this revision.** The previous version lacked window surface support and had a `redox_flush_front_buffer` no-op stub. Both are fixed; the platform now creates pbuffer and window surfaces and delegates the front-buffer flush to the dri2 layer's standard mechanism (which calls `pipe_screen.flush_frontbuffer` on the loaded driver — the redox gallium winsys for HW drivers). ### Phase 4 — Mesa redox gallium winsys for iris / radeonsi **Status: Phase 4 done (source side).** The winsys exists at `src/gallium/winsys/redox/drm/`. It is wired in `src/gallium/meson.build:11` on `with_gallium_iris or with_gallium_radeonsi`. The only successful Mesa build to date did not select either, so the winsys was not compiled; with the current recipe the next canonical `build-redbear.sh redbear-full` will compile it. Runtime validation is a Phase 5 prerequisite. ### Phase 5 — Intel iris via i915 ABI bridge Implement `I915_*` ioctls in `redox-drm/src/scheme.rs` (and corresponding ops in `drivers/intel/mod.rs`). See §5 for the ioctl list. Total scope: 12 new ioctls, ~2000 lines of Rust. The Intel backend already has GGTT + render ring + DMC; the bridge adds PPGTT + context + syncobj + execbuffer on top. ### Phase 6 — AMD radeonsi via amdgpu ABI bridge Implement `DRM_AMDGPU_*` ioctls. See §6 for the ioctl list. Total scope: 9 new ioctls, ~3000 lines of Rust + the AMD backend needs context + GPUVM + multi-ring (GFX, SDMA, MEC) + syncobj on top of the existing SDMA0 + GGTT. ### Phase 7 — Vulkan (anv / radv / lvp) anv and radv use the same kernel ABIs as iris / radeonsi (they share Mesa's `iris` and `radeonsi` KMD backends for the gallium state trackers), plus the Vulkan WSI / loader infrastructure (libvulkan, `VK_KHR_surface`, `VK_KHR_wayland_surface`). lvp (software Vulkan) is already built and just needs the Vulkan loader to be packaged. ### Phase 8 — Real-hardware validation Acquire at least one Intel Gen9–Gen14 platform (e.g. Meteor Lake or Arrow Lake laptop) and at least one AMD GCN/RDNA platform. Re-run the validation matrix §7 with the hardware paths exercised. ## 10. Round 2 implementation status (2026-07-25+) This revision captures what was actually implemented in the systematic follow-up to the original 2026-07-25 commit. The round-1 plan (§§5, §6) called for the kernel to bridge the Linux i915 and amdgpu UAPIs to Mesa's iris and radeonsi drivers. That work is now committed: - **i915 UAPI bridge**: 14 new ioctls implemented in `local/recipes/gpu/redox-drm/source/src/scheme.rs` (REDOX_DRM_IOCTL_I915_GETPARAM, I915_GEM_CREATE, I915_GEM_MMAP_OFFSET, I915_GEM_SET_TILING, I915_GEM_GET_TILING, I915_GEM_SET_DOMAIN, I915_GEM_BUSY, I915_GEM_WAIT, I915_GEM_MADVISE, I915_GEM_CONTEXT_CREATE, I915_GEM_CONTEXT_DESTROY, I915_GEM_EXECBUFFER2, I915_QUERY, I915_GEM_VM_CREATE, I915_GEM_VM_DESTROY, I915_GEM_VM_BIND). Wire structs match `drm-uapi/i915_drm.h`. libdrm's redox dispatch (`local/patches/libdrm/02-redox-dispatch.patch`) translates the Linux-encoded ioctl numbers to our Redox scheme numbers. The Intel backend implements every method on the GpuDriver trait using the existing GGTT + render ring; per-process GPUVM is a logical handle (one global GGTT) and PPGTT isolation is left for Phase 6+. - **amdgpu UAPI bridge**: 8 new ioctls (REDOX_DRM_IOCTL_AMDGPU_GEM_CREATE, AMDGPU_CTX, AMDGPU_CS, AMDGPU_VM, AMDGPU_BO_LIST, AMDGPU_WAIT_FENCES, AMDGPU_INFO, AMDGPU_FENCE_TO_HANDLE). Wire structs match `drm-uapi/amdgpu_drm.h`. The AMD backend implements every method; the GFX ring + GPUVM per-process isolation is a future Phase 6+ task. Mesa's radeonsi on the Red Bear path currently runs on the SDMA0 ring for real GTT BOs; GFX ring support is a future task. - **Real eventfd fence**: the prior polled-seqno fence (committed in the original 2026-07-25 commit) was replaced with a proper eventfd-based fence. The kernel duplicates the userland eventfd (via `libc::dup`), tracks the kernel-side fd in a `BTreeMap`, and writes 1 to every registered eventfd whose seqno has completed. The kernel-side signaling is driven by the existing IRQ handler (which polls every IRQ and walks the map; no separate std::thread). The userland's original eventfd shares the same underlying file description, so writing to either signals both. - **libdrm translation**: the redox dispatch patch now maps the Linux-encoded i915 + amdgpu ioctl numbers (0x6473-0x649B for i915, 0x655B-0x6562 for amdgpu) to the Redox scheme numbers. libdrm's `drmGetVersion` path now returns the active GpuDriver's name (e.g. "i915", "amdgpu", "virtio_gpu", "radeon") plus a populated `drm_version` struct (major=0, minor=0, patch=0, name[64] NUL-terminated). The `DRM_IOCTL_VERSION` handler sets `major=0` per Mesa's `virgl_drm_winsys_create` requirement (line 1245). - **relibc headers added**: `utmpx.h` (POSIX login accounting), `linux/kd.h` (Linux keyboard), `linux/vt.h` (Linux virtual terminal), and `X11/Xauth.h` (X11 authentication). These replace the sed-hack stubs in `recipes/kde/sddm/wayland-patch.sh` with real POSIX/Linux/X11 standard headers. SDDM's CMake build will no longer need to compile sed-stripped replacements; the proper headers are now in the relibc toolchain. ### Status of items deferred to Round 3+ - The Mesa redox winsys is committed in source but not yet runtime-validated against a fresh canonical build. The `gallium/meson.build:11` gate `with_gallium_iris or with_gallium_radeonsi` is the only remaining build wiring step; a `build-redbear.sh redbear-full` run would compile it and produce `iris_dri.so` / `radeonsi_dri.so`. - KWin DRM device discovery on Redox: KWin's `drm_backend.cpp` uses libudev to enumerate `/dev/dri/renderDN`. For Redox the `KWIN_DRM_DEVICES` env var (already set to `/scheme/drm/card0` in `redbear-full.toml` line 423) bypasses udev enumeration. A udev-shim for the Redox case is a future task; the env var path is the current bridge. - Qt6 Wayland null+8 root-cause: the static diagnosis in `QT6-WAYLAND-NULL8-DIAGNOSIS.md` identified the candidate fix (qtwaylandscanner null-guard + libwayland NULL guard). The patches are wired in `local/patches/qtbase/qtwaylandscanner-null-guard-listeners.patch` and `local/patches/libwayland/redox.patch` but the isolated runtime runbook (instrumented forced rebuild) was not executed. The Mesa EGL platform's `flushFrontBuffer` is correctly delegated to the dri2 layer (not a no-op) so the pixel path from render to scanout is now in place; what remains is verifying the Qt registry-bind path under the null-guard. - The Xwayland recipe is in the config but the build process is untested. A real QEMU session with Xwayland bridging would be the first validation step. ## 11. Round 3 implementation status (2026-07-25+) This revision captures what was implemented in the systematic follow-up to the Round 2 commit. Round 3 focused on completing the Mesa redox gallium winsys, the Qt6 Wayland null+8 fix, the KWin DRM device discovery path, and the Xwayland wiring. - **Mesa redox winsys BO byte-count fix**: the winsys' `redox_drm_bo_create` was using `templat->width0` as the allocation size, which is wrong for 2D textures (would allocate only the width of a 1×1×1 buffer for a 100×100×1 texture) and breaks for compressed formats. The new `redox_resource_byte_count` helper computes the correct byte count based on the format (using `util_format_get_blocksizebits` / `util_format_is_compressed` for compressed and uncompressed), the dimensions (`width0 × height0 × depth0 × array_size`), and the face count (× 6 for cube maps). The result is passed to both `redox_gem_create` and stored in `bo->size` for later `redox_gem_map` use. - **Qt6 Wayland null+8 root-cause fix**: - qtwaylandscanner: the generated `init_listener()` now wraps `wl__add_listener(...)` in a `if (m_)` guard. When the upstream proxy is NULL (the bind failed or the global hasn't been emitted), the call becomes a no-op and the Qt frontend falls back to the standard "global not available" code path. We also added a guard around the `init_listener()` call inside `init()`. - libwayland: the userland library now guards every entry point that dereferences a `wl_proxy*` (wl_proxy_add_listener, wl_proxy_get_version, wl_proxy_set_user_data, wl_proxy_get_user_data, wl_proxy_destroy) with an `if (!proxy) { errno = EINVAL; return ...; }` check. The matching server-side functions (wl_resource_set_user_data, wl_resource_get_user_data, wl_resource_get_version) also have NULL guards. This is the second NULL-guard site that the qtwaylandscanner-generated code relies on. - **KWin DRM device discovery**: KWin's `drm_backend.cpp` uses libudev to enumerate `/dev/dri/renderDN`. On Redox, the DRM device is at `/scheme/drm/card0`. We now set `KWIN_DRM_DEVICES=/scheme/drm/card0` in `redbear-full.toml` (was already there; now also documented in the sddm.conf and 21_sddm.service envs). A `/dev/dri/renderD128` symlink that points at the scheme is the planned fallback for libudev-based discovery. The comment in redbear-full.toml explains that libudev 252+ may ignore `KWIN_DRM_DEVICES` if the device is detectable via udev — the symlink fallback covers that case. - **Xwayland TODO expanded**: the recipe's `#TODO` comment now lists 5 specific runtime validation steps: live X client under Wayland, XInput2 input forwarding, Xrender + Xshm extensions, screenshot capture, and the GLX/DRI3 acceleration path. The recipe is `recipes/wip/wayland/ xwayland/recipe.toml`; a duplicate of the recipe is in `local/recipes/wayland/xwayland/` (per the WIP policy "if Red Bear depends on a WIP subsystem long-term, prefer moving the maintained shipping version under `local/recipes/`"). Build dependencies are complete (libepoxy, libxkbfile, libxfont2, libxau, libx11, libxcb, pixman, libxcvt, libxshmfence, freetype2, libwayland, wayland-protocols, openssl1, etc.). ### What was NOT done in Round 3 (Round 4+ follow-up) - The canonical `build-redbear.sh redbear-full` run to validate the Round 2+3 changes. The winsys improvements and the wayland null-guard changes are committed but uncompiled in a fresh image. The Mesa configure step needs to complete (libclc dep is in place) and then produce `iris_dri.so` / `radeonsi_dri.so` for the winsys to be runtime-linked. - A real Qt6 Wayland client runbook execution. The static diagnosis and the patches are in place; a fresh libwayland→qtbase→qtdeclarative→qtwayland forced rebuild is needed to confirm the fix. The Mesa EGL platform's `flushFrontBuffer` is correctly delegated to the dri2 layer (not a no-op) so the pixel path from render to scanout is now in place. - Hardware validation: still zero bare-metal Intel/AMD runs. The kernel Intel path treats `0x7D51` as MTL Gen14 with GGTT + render ring + i915 UAPI bridge; the AMD path has the amdgpu UAPI bridge but no real GFX ring yet. ## 12. Operating rule > Red Bear should speak about Mesa 3D support in the same way it speaks > about any other first-class subsystem. > > Code presence is not support. Build success is not support. A > kernel-side driver is not support. A Mesa recipe string is not > support. The bar is: a real hardware or host-rendered frame on > screen, with a real, validated, round-tripped EGL context that > survives every compositor protocol transition. ## 9. Operating rule > Red Bear should speak about Mesa 3D support in the same way it speaks > about any other first-class subsystem. > > Code presence is not support. Build success is not support. A > kernel-side driver is not support. A Mesa recipe string is not > support. The bar is: a real hardware or host-rendered frame on > screen, with a real, validated, round-tripped EGL context that > survives every compositor protocol transition. This document is now closer to that bar than the previous version was. The remaining gap is runtime evidence (Phase 1 TODO).