This guide walks you through the complete path from opening a DRM device to displaying a GPU-allocated buffer on a connected monitor. You will openDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Smithay/gbm.rs/llms.txt
Use this file to discover all available pages before exploring further.
/dev/dri/card0, wrap it in a GBM device, allocate a 1280×720 scanout buffer, fill it with pixel data from the CPU, and hand it to the DRM/KMS subsystem as a framebuffer. The full example requires the default feature set (drm-support, import-wayland, import-egl). Add gbm.rs and drm-rs to your Cargo.toml before running this code.
Open the DRM device
GBM needs a file descriptor pointing to an open DRM device node. The simplest way is to open
/dev/dri/card0 with read/write permissions using std::fs::OpenOptions. In a real compositor you would enumerate available nodes or accept a file descriptor passed in by a display manager, but for this guide a direct open is sufficient.You also need to implement the drm-rs marker traits on a newtype wrapper so that GBM can recognise the file as a DRM device:Create a GBM Device
Pass the open DRM file to
Device::new. GBM takes ownership of the file descriptor (through the AsFd implementation) and negotiates with the kernel driver to set up the buffer manager. The call returns an IoResult<Device<Card>>, so you can unwrap or propagate the error with ?.Device<T> implements Deref<Target = T>, so you can call any drm-rs method directly on gbm — mode-setting calls such as resource_handles(), get_connector(), and set_crtc() are all available on the same handle.Allocate a BufferObject
Use The generic type parameter
Device::create_buffer_object to allocate GPU memory. You supply the width, height, pixel format, and a set of usage flags. The SCANOUT flag tells the driver that this buffer will be presented to a display controller; WRITE allows CPU writes via BufferObject::write.<()> is the userdata type. Pass any 'static type here to attach application-defined metadata to the buffer; () means no userdata. Use Device::is_format_supported beforehand if you need to confirm that the driver supports a particular format and flag combination.Write pixel data
Because the buffer was allocated with
BufferObjectFlags::WRITE, you can push raw pixel data from the CPU using BufferObject::write. The slice you pass must be exactly the right size for the buffer’s width, height, and stride.The example below generates a simple vertical stripe pattern in ARGB8888 format (4 bytes per pixel):For real rendering workloads you would typically use EGL or Vulkan to render into the buffer on the GPU rather than writing pixel data from the CPU. CPU writes through
write() are slower and may involve cache flushes depending on the driver.Create a framebuffer and display
With the pixel data in place, register the buffer object as a DRM framebuffer and then set it as the active framebuffer for a CRTC. Because
Device<Card> implements drm::control::Device (via the drm-support feature), you can call add_framebuffer and set_crtc directly on gbm.This step requires the
drm-support feature (enabled by default). Without it, add_framebuffer and set_crtc are not available on Device. If you disabled default features, re-enable it with features = ["drm-support"] in your Cargo.toml.Next Steps
Core Concepts
Dive deeper into GBM devices, buffer objects, surfaces, formats, and modifiers.
DRM Integration
Build a complete DRM device wrapper with connector enumeration and page-flipping.
API Reference
Explore the full
Device, BufferObject, and Surface API documentation.