Hands On Projects For The Linux Graphics Subsystem Now
Here’s a structured text for “Hands-On Projects for the Linux Graphics Subsystem” — suitable for a workshop, course syllabus, or self-study guide.
The Plan
- Open the DRM device (
/dev/dri/card0). - Acquire a dumb buffer (simple RAM-backed framebuffer).
- Map the buffer to userspace memory.
- Draw pixels directly into that memory.
- Set the CRTC (Cathode Ray Tube Controller) to scan out your buffer.
Project 3 — Simple Wayland Compositor (wlroots or libwayland)
- Objective: Implement a minimal Wayland compositor that maps client windows to DRM via GBM and EGL.
- Prereqs: Project 2; C or Rust; familiarity with Wayland protocol basics.
- Tools: libwayland, libinput, wlroots (optionally use as a library), Mesa.
- Tasks:
- Implement Wayland core globals (wl_display, wl_compositor, wl_shm).
- Accept client buffers (wl_shm and/or zwp_linux_dmabuf) and import them to EGL/GBM.
- Compose client surfaces and present via DRM KMS.
- Integrate libinput for pointer/keyboard events and map to clients.
- Support basic shell protocol (xdg-shell) to manage windows.
- Checkpoints:
- Can run a Wayland client (e.g., weston-terminal or Sway clients) and display windows.
- Learning outcomes:
- How compositors use dmabuf, buffer import, and handle input to drive surfaces.
Project 6: Simple Plane Composition
Goal: Overlay a small sprite or cursor using a hardware plane (if supported).
Concepts:
- DRM planes (primary, overlay, cursor)
- Plane properties (position, size, z-order)
- Legacy plane updates or atomic commit
Task:
- Enumerate available planes
- Set up a primary plane with a full-screen image
- Add an overlay plane with a smaller image or video
- Move the overlay plane across the screen
Outcome: Understanding how compositors use hardware planes for efficient compositing. Hands On Projects For The Linux Graphics Subsystem
The Project
- Enable GEM tracing:
echo 1 > /sys/kernel/debug/tracing/events/drm/drm_gem_object_init/enable - Write a parser: Use
cat /sys/kernel/debug/tracing/trace_pipeto watch GEM object creation and destruction. - Create a memory hog: Write a small OpenGL program using
glBufferDatawithout callingglDeleteBuffers. - Correlate PIDs: Modify your parser to map file descriptors (
/proc/<pid>/fd) to DRM device handles.
Advanced challenge: Write a Bash script that triggers a GPU memory dump using devmem2 to read the GPU's MMIO region and extract the framebuffer address.
Project 3: Atomic Modesetting with Page Flipping (Tearing-Free Animation)
Goal: Extend Project 2 to use the modern atomic API (instead of legacy SetCrtc). Implement double-buffering and page flipping to animate a bouncing square without tearing.
Why it matters: Atomic modesetting is the standard in modern Linux (used by Wayland compositors). It allows testing all display parameters together and guarantees a consistent frame.
Tools: libdrm atomic helpers, drmModeAtomicCommit. Here’s a structured text for “Hands-On Projects for
Key differences from legacy:
- Build a property set (request) using
drmModeAtomicAddProperty. - Properties include
CRTC_ID,MODE_ID,ACTIVE,FB_ID,SRC_X,SRC_Y. - Use
drmModeCreatePropertyBlobfor modes. - Commit with
DRM_MODE_ATOMIC_ALLOW_MODESETandDRM_MODE_PAGE_FLIP_EVENT.
Steps:
- Enumerate all DRM properties using
drmModeObjectGetProperties(for CRTC, connector, plane). - Create two dumb buffers (front and back).
- Set up a universal plane (overlay or primary) for drawing.
- Write a loop that:
- Renders to the back buffer.
- Issues an atomic commit flipping to the back buffer.
- Waits for a vblank event (using
drmHandleEvent).
- Update the square position each frame.
Challenge: Measure actual frame rate vs. target. Observe tearing if you disable the page flip flag.
Project 5: GPU Virtualization with SR-IOV (Single Root I/O Virtualization)
Goal: On supported hardware (Intel Gen11+ or AMD SRIOV-capable GPUs), enable virtual functions (VFs) on the physical GPU and assign a VF to a QEMU/KVM virtual machine for near-native 3D acceleration. The Plan
Why it matters: This is the cutting edge of Linux graphics, used in cloud gaming and VDI (Virtual Desktop Infrastructure).
Requirements:
- Intel Iris Xe / Arc or AMD Radeon Pro VII / MI series.
- IOMMU enabled in BIOS and kernel (
intel_iommu=onoramd_iommu=on). vfio-pcidriver.
Steps (Intel example):
- Check if your GPU supports SR-IOV:
lspci -vv -s 00:02.0 | grep SR-IOV - Enable SR-IOV in the kernel module:
echo 2 > /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs - Verify VFs appear as separate PCI functions (e.g.,
00:02.1,00:02.2). - Unbind the VF from
i915driver and bind tovfio-pci:echo 0000:00:02.1 > /sys/bus/pci/devices/0000:00:02.1/driver/unbind echo vfio-pci > /sys/bus/pci/devices/0000:00:02.1/driver_override - Pass the VF to QEMU:
qemu-system-x86_64 -enable-kvm -device vfio-pci,host=00:02.1 ... - Inside the VM, install the standard GPU driver (e.g.,
i915for Intel VF).
Expected Outcome: glxinfo in the VM reports a real GPU renderer, and glmark2 runs at near-native speed.
Project 4 — Implement dmabuf import/export and modifiers
- Objective: Handle zero-copy buffer sharing between clients and compositor, including tile/format modifiers.
- Prereqs: Project 3, kernel and Mesa knowledge.
- Tools: libdrm, libgbm, Mesa, wlroots code for reference.
- Tasks:
- Add support for zwp_linux_dmabuf_v1 to accept dma-buf file descriptors from clients.
- Parse and use DRM format modifiers (e.g., AFBC, UBWC, tiling).
- Handle buffer layouts correctly during import and support fallback for unsupported modifiers.
- Test with clients that export dmabufs (e.g., GStreamer, weston-simple-egl).
- Checkpoints:
- Can display client content using dmabuf without copying.
- Correct handling of at least two modifiers or a documented fallback.
- Learning outcomes:
- Practical handling of GPU-specific buffer formats and zero-copy rendering paths.
Implementation Steps
- Write a C program that opens
/dev/dri/card0. - Call
drmGetVersion()(fromlibdrm). - Retrieve
drmModeResresources. - Create a dumb buffer of size 1024x768, 32bpp.
- Print the pitch, size, and handle.
