Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Smithay/drm-rs/llms.txt
Use this file to discover all available pages before exploring further.
The drm::Device trait is the foundational building block of drm-rs. Any type that wraps a DRM file descriptor and implements the standard AsFd trait can implement Device — all of its methods have default implementations that delegate directly to the appropriate ioctl calls via the drm-ffi crate. No extra state is required.
Minimal Implementation
Because every method has a default implementation, implementing the trait only requires satisfying the AsFd bound. Opening the device node with read and write permissions is sufficient for most operations.
use drm::Device;
use std::fs::{File, OpenOptions};
use std::os::unix::io::{AsFd, BorrowedFd};
struct Card(File);
impl AsFd for Card {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}
impl Device for Card {}
impl Card {
fn open() -> Self {
let mut options = OpenOptions::new();
options.read(true);
options.write(true);
Card(options.open("/dev/dri/card0").unwrap())
}
}
drm::control::Device extends this trait with full KMS modesetting capabilities — CRTCs, connectors, planes, framebuffers, and atomic commits. See the control::Device reference for details.
Methods
acquire_master_lock
fn acquire_master_lock(&self) -> io::Result<()>
Acquires the DRM Master lock for this process. The DRM Master is required for all modesetting operations on a primary node (/dev/dri/card*).
Privileges: The calling process must have CAP_SYS_ADMIN (typically root) or already be the session’s DRM master. Most display servers acquire this automatically when they open the primary device node.
Notes: When the primary device node is opened by a session manager (e.g. logind), the lock is usually handed to the process automatically. This method is needed only if you need to re-acquire after explicitly releasing the lock, or in setuid/privileged helper scenarios.
card.acquire_master_lock().expect("failed to acquire DRM master");
release_master_lock
fn release_master_lock(&self) -> io::Result<()>
Releases the DRM Master lock so that another process can acquire it. This is useful for cooperative handoff between a display server and a GPU-intensive client, or when implementing a compositor that suspends itself.
card.release_master_lock().expect("failed to release DRM master");
set_client_capability
fn set_client_capability(&self, cap: ClientCapability, enable: bool) -> io::Result<()>
Enables or disables an optional feature for the calling process. Client capabilities are per-process and per-file-descriptor — they do not affect other processes or other open file descriptors.
This method must be called before using the features gated behind each capability. For example, Atomic modesetting requires enabling UniversalPlanes first, then Atomic.
| Parameter | Type | Description |
|---|
cap | ClientCapability | The capability to enable or disable |
enable | bool | true to enable, false to disable |
Key capabilities:
ClientCapability::UniversalPlanes — exposes all plane types (overlay, cursor) beyond the default primary planes. Required for most KMS usage.
ClientCapability::Atomic — enables the atomic modesetting API. Requires UniversalPlanes to be set first.
ClientCapability::AspectRatio — includes aspect ratio data in mode information.
ClientCapability::WritebackConnectors — exposes writeback connectors for render-to-memory. Requires Atomic.
ClientCapability::CursorPlaneHotspot — tells the driver that the client handles cursor hotspot positioning correctly (needed for para-virtualised hardware). Requires Atomic.
// Enable atomic modesetting (the standard sequence)
card.set_client_capability(drm::ClientCapability::UniversalPlanes, true)
.expect("UniversalPlanes not supported");
card.set_client_capability(drm::ClientCapability::Atomic, true)
.expect("Atomic modesetting not supported");
See Capabilities for the full ClientCapability reference.
get_driver_capability
fn get_driver_capability(&self, cap: DriverCapability) -> io::Result<u64>
Returns the current value of a driver capability. A return value of 0 indicates that the capability is not supported or not enabled. Non-zero values are capability-specific — for boolean capabilities 1 means supported, while capabilities like CursorWidth and CursorHeight return the actual pixel dimension.
| Parameter | Type | Description |
|---|
cap | DriverCapability | The capability to query |
Returns: io::Result<u64> — the capability value on success.
let cursor_w = card.get_driver_capability(drm::DriverCapability::CursorWidth).unwrap();
let cursor_h = card.get_driver_capability(drm::DriverCapability::CursorHeight).unwrap();
println!("Max cursor size: {}×{}", cursor_w, cursor_h);
See Capabilities for the full DriverCapability reference.
get_driver
fn get_driver(&self) -> io::Result<Driver>
Returns a Driver struct describing the kernel DRM driver that is powering this device. The struct exposes the driver name, version tuple, publication date, and a human-readable description.
let driver = card.get_driver().unwrap();
println!("Driver: {:?} v{}.{}.{}",
driver.name(),
driver.version.0,
driver.version.1,
driver.version.2,
);
Returns: io::Result<Driver>. May return EFAULT if the kernel cannot copy the version strings into userspace.
See Driver for the full struct reference.
get_bus_id
fn get_bus_id(&self) -> io::Result<OsString>
Returns the PCI bus ID string that the kernel associates with this device (for example "PCI:0000:00:02.0"). This can be used to correlate a DRM device node with a PCI device from /sys/bus/pci/devices/.
let bus_id = card.get_bus_id().unwrap();
println!("Bus ID: {:?}", bus_id);
authenticated
fn authenticated(&self) -> io::Result<bool>
Returns true if the current process’s file descriptor has been authenticated by the DRM master. On the master fd itself this always returns true. On a secondary fd it returns true only after the master has called authenticate_auth_token with a token produced by generate_auth_token.
if card.authenticated().unwrap() {
println!("We are authenticated");
}
generate_auth_token (deprecated)
fn generate_auth_token(&self) -> io::Result<AuthToken>
Generates an AuthToken for the current file descriptor. The token can be passed out-of-band (e.g. via a Unix socket) to a DRM master process, which can then call authenticate_auth_token to grant access.
This authentication mechanism is deprecated. Opening a render node (/dev/dri/renderD*) is the modern, privilege-free alternative for unprivileged GPU access. Use generate_auth_token only when interfacing with legacy software that requires it.
authenticate_auth_token
fn authenticate_auth_token(&self, token: AuthToken) -> io::Result<()>
Called by the DRM master to authenticate a token that was generated by another process via generate_auth_token. Once authenticated, the other process gains unprivileged access to the device.
| Parameter | Type | Description |
|---|
token | AuthToken | The token received from the client process |
// On the master side — token received over IPC
card.authenticate_auth_token(received_token)
.expect("authentication failed");
wait_vblank
fn wait_vblank(
&self,
target_sequence: VblankWaitTarget,
flags: VblankWaitFlags,
high_crtc: u32,
user_data: usize,
) -> io::Result<VblankWaitReply>
Blocks until a specific vblank sequence occurs, or schedules an asynchronous vblank event. This is the low-level vblank synchronisation primitive. For most use cases, page flip events via page_flip() are simpler.
| Parameter | Type | Description |
|---|
target_sequence | VblankWaitTarget | Absolute(n) or Relative(n) frame target |
flags | VblankWaitFlags | Modifier flags (event mode, next-on-miss) |
high_crtc | u32 | CRTC index for hardware with many outputs; usually 0 |
user_data | usize | Arbitrary value echoed back in the reply/event |
Returns: io::Result<VblankWaitReply> containing the frame number and timestamp.
use drm::{VblankWaitTarget, VblankWaitFlags};
let reply = card.wait_vblank(
VblankWaitTarget::Relative(1),
VblankWaitFlags::empty(),
0,
0,
).unwrap();
println!("Vblank frame {}, time {:?}", reply.frame(), reply.time());
See Vblank for full documentation of the types.