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

  1. Open the DRM device (/dev/dri/card0).
  2. Acquire a dumb buffer (simple RAM-backed framebuffer).
  3. Map the buffer to userspace memory.
  4. Draw pixels directly into that memory.
  5. 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:
    1. Implement Wayland core globals (wl_display, wl_compositor, wl_shm).
    2. Accept client buffers (wl_shm and/or zwp_linux_dmabuf) and import them to EGL/GBM.
    3. Compose client surfaces and present via DRM KMS.
    4. Integrate libinput for pointer/keyboard events and map to clients.
    5. 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

  1. Enable GEM tracing: echo 1 > /sys/kernel/debug/tracing/events/drm/drm_gem_object_init/enable
  2. Write a parser: Use cat /sys/kernel/debug/tracing/trace_pipe to watch GEM object creation and destruction.
  3. Create a memory hog: Write a small OpenGL program using glBufferData without calling glDeleteBuffers.
  4. 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 drmModeCreatePropertyBlob for modes.
  • Commit with DRM_MODE_ATOMIC_ALLOW_MODESET and DRM_MODE_PAGE_FLIP_EVENT.

Steps:

  1. Enumerate all DRM properties using drmModeObjectGetProperties (for CRTC, connector, plane).
  2. Create two dumb buffers (front and back).
  3. Set up a universal plane (overlay or primary) for drawing.
  4. 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).
  5. 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=on or amd_iommu=on).
  • vfio-pci driver.

Steps (Intel example):

  1. Check if your GPU supports SR-IOV:
    lspci -vv -s 00:02.0 | grep SR-IOV
    
  2. Enable SR-IOV in the kernel module:
    echo 2 > /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs
    
  3. Verify VFs appear as separate PCI functions (e.g., 00:02.1, 00:02.2).
  4. Unbind the VF from i915 driver and bind to vfio-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
    
  5. Pass the VF to QEMU:
    qemu-system-x86_64 -enable-kvm -device vfio-pci,host=00:02.1 ...
    
  6. Inside the VM, install the standard GPU driver (e.g., i915 for 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:
    1. Add support for zwp_linux_dmabuf_v1 to accept dma-buf file descriptors from clients.
    2. Parse and use DRM format modifiers (e.g., AFBC, UBWC, tiling).
    3. Handle buffer layouts correctly during import and support fallback for unsupported modifiers.
    4. 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

  1. Write a C program that opens /dev/dri/card0.
  2. Call drmGetVersion() (from libdrm).
  3. Retrieve drmModeRes resources.
  4. Create a dumb buffer of size 1024x768, 32bpp.
  5. Print the pitch, size, and handle.
Album Art

Ready to Play

TopMixtapes.com

0:00
0:00

Up Next