The Linux Kernel already had an API called fbdev allowing to manage the framebuffer of a graphics adapter,[2] but it couldn't be used to handle the needs of modern 3D accelerated GPU based video cards. These type of cards usually require setting and managing a command queue in the card's memory (Video RAM) to dispatch commands to the GPU, and also they need a proper management of the buffers and free space of the Video RAM itself.[3] Initially user space programs (such as the X Server) directly managed these resources, but these programs usually acted as if they were the only ones with access to the card's resources. When two or more programs tried to control the same video card at the same time, and set its resources each one in its own way, most times they ended catastrophically.[3]

When the Direct Rendering Manager was first created, the purpose was that multiple programs using resources from the video card can cooperate through it. The DRM gets an exclusive access to the video card, and it's responsible for initializing and maintaining the command queue, the VRAM and any other hardware resource. The programs that want to use the GPU send their requests to DRM, which acts as an arbitrator and takes care to avoid possible conflicts.

Since then, the scope of DRM has been expanded over the years to cover more functionality previously handled by user space programs, such as framebuffer managing and mode setting, memory sharing objects and memory synchronization.[4][5] Some of these expansions had carried its own specific names, such as Graphics Execution Manager (GEM) or Kernel Mode-Setting (KMS), and the terminology prevails when the functionality they provide is specifically alluded. But they are really parts of the whole kernel DRM subsystem.

A process using the Direct Rendering Manager of the Linux Kernel to access a 3D accelerated graphics card

The Direct Rendering Manager resides in kernel space, so the user space programs must use kernel system calls to request its services. However, DRM doesn't define its own customized system calls. Instead, it follows the Unix principle "everything is a file" to expose the GPUs through the filesystem name space using device files under the /dev hierarchy. Each GPU detected by DRM is referred as a DRM device, and a device file /dev/dri/cardX (where X is a sequential number) is created to interface with it.[6][7] User space programs that want to talk to the GPU must open the file and use ioctl calls to communicate with DRM. Different ioctls correspond to different functions of the DRM API.

A library called libdrm was created to facilitate the interface of user space programs with the DRM subsystem. This library is merely a wrapper that provides a function written in C for every ioctl of the DRM API, as well as constants, structures and other helper elements.[8] The use of libdrm not only avoids exposing the kernel interface directly to user space, but presents the usual advantages of reusing and sharing code between programs.

DRM consists of two parts: a generic "DRM core" and a specific one ("DRM Driver") for each type of supported hardware.[9] DRM core provides the basic framework where different DRM drivers can register, and also provides to user space a minimum set of ioctls with common, hardware-independent functionality. A DRM driver, on the other hand, implements the hardware-dependent part of the API, specific to the type of GPU it supports; it should provide the implementation to the remainder ioctls not covered by DRM core, but it may also extend the API offering additional ioctls with extra functionality only available on such hardware.[6] When a specific DRM driver provides an enhanced API, user space libdrm is also extended by an extra library libdrm-driver that can be used by user space to interface with the additional ioctls.

Due to the increasing size of video memory and the growing complexity of graphics APIs such as OpenGL, the strategy of reinitializing the graphics card state at each context switch was too expensive, performance-wise. Also, modern Linux desktops needed an optimal way to share off-screen buffers with the compositing manager. This leads to the development of new methods to manage graphics buffers inside the kernel. The Graphics Execution Manager (GEM) emerged as one of these methods.[5]

GEM provides an API with explicit memory management primitives.[5] Through GEM, a user space program can create, handle and destroy memory objects living in the GPU's video memory. These objects, called "GEM objects",[10] are persistent from the user space program's perspective, and don't need to be reloaded every time the program regains control of the GPU. When a user space program needs a chunk of video memory (to store a framebuffer, texture or any other data required by the GPU[11]), it requests the allocation to the DRM driver using the GEM API. The DRM driver keeps track of the used video memory, and is able to comply with the request if there is free memory available, returning a "handle" to user space to futher refer the allocated memory in coming operations.[5][10] GEM API also provides operations to populate the buffer and to release it when is no more needed.

GEM also allows two or more user space processes using the same DRM device (hence the same DRM driver) to share a GEM object.[12] GEM handles are local 32-bit integers unique to a process but repeatable in other processes, therefore not suitable for sharing. What is needed is a global namespace, and GEM provides one through the use of global handles called GEM names. A GEM name refers to one, and only one, GEM object managed by the same DRM driver, by using an unique 32 bit integer. GEM provides a operation, flink, to obtain a GEM name from a GEM handle. The process can then pass this GEM name —this 32-bit integer— to another process using any IPC mechanism available. The GEM name can be used by the receiving process to obtain a local GEM handler pointing to the original GEM object.

Unfortunately, the use of GEM names to share buffers is not secure.[13][14][15] A malicious third party process accessing the same DRM device could try and guess a GEM name of a buffer shared by another two processes, simply by probing 32-bit integers. Once a GEM name is found, its contents can be accessed and modified, violating the confidenciality and integrity of the buffer's information. This drawback was overcome later by the introduction of DMA-BUF support into DRM.

AGP, PCIe and other graphics cards contain an IOMMU called Graphics address remapping table (GART) which can be used to map various pages of system memory into the GPU's address space. The result is that, at any time, an arbitrary (scattered) subset of the system's RAM pages are accessible to the GPU.[16]

There must be a "DRM master" in user-space, this program has exclusive access to KMS.

The KMS driver is the component which is solely responsible for the mode setting. It is the device driver for a display controller, and it can be distinguished from the device driver of a rendering accelerator. Due to the fact that dies of modern GPUs found on graphics cards for desktop computers integrate "processing logic", "display controller" and "hardware video acceleration" SIP cores, non-technical people don't distinguish between these three very different components. SoCs on the other hand, regularly mix SIP from different developers, and e.g. ARM's Mali SIP does not feature a display controller. For historical reasons, the DRM and the KMS of the Linux kernel were amalgamated into one component. They were split in 2013 for technical reasons.[17]

A render node is a character device that exposes a GPU's off-screen rendering and GPGPU capabilities to unprivileged programs, without exposing any display manipulation access. This is the first step in an effort to decouple the kernel's interfaces for GPUs and display controllers from the obsolete notion of a graphics card.[17] Unprivileged off-screen rendering is presumed by both Wayland and Mir display protocols — only the compositor is entitled to send its output to a display, and rendering on behalf of client programs is outside the scope of these protocols.

Patches for universal plane were submitted by Intel's Matthew. D. Roper in May 2014. The idea behind universal plane is to expose all types of hardware planes to userspace via one consistent Kernel–user space API.[18] Universal plane brings framebuffers (primary planes), overlays (secondary planes) and cursors (cursor planes) together under the same API. No more type specific ioctls, but common ioctls shared by them all.[19]

Universal plane prepares the way for Atomic mode setting and nuclear pageflip.

The Linux DRM subsystem includes free and open source drivers to support hardware from the 3 main manufacturers of GPUs for desktop computers (AMD. NVIDIA and Intel), as well as from a growing number of mobile GPU and System on a chip (SoC) integrators. The quality of each driver highly varies, depending on the degree of cooperation by the manufacturer and other questions.

The Direct Rendering Manager is developed within the Linux kernel, and its source code resides in the /drivers/gpu/drm directory of the Linux source code. The subsystem maintainter is Dave Airlie, with other maintainers taking care of specific drivers.[31] As usual in the Linux kernel development, DRM submaintainers and contributors send their patches with new features and bug fixes to the main DRM maintainer which integrates them into its own Linux repository. The DRM maintainer in turn submits all of these patches that are ready to be mainlined to Linus Torvalds whenever a new Linux version is going to be released. Torvalds, as top maintainer of the whole kernel, holds the last word on whether a patch is suitable or not for inclusion in the kernel.

For historical reasons, the source code of the libdrm library is maintained under the umbrella of the Mesa project.[32]

In 1999, while developing DRI for XFree86, Precision Insight created the first version of DRM for the 3dfx video cards, as a linux kernel patch included within the Mesa source code.[33] Later that year, the DRM code was mainlined in Linux kernel 2.3.18 under the /drivers/char/drm/ directory for character devices.[34] During the following years the number of supported video cards grew. When Linux 2.4.0 was released in January 2001 there was already support for Creative Labs GMX 2000, Intel i810, Matrox G200/G400 and ATI Rage 128, in addition to 3dfx Voodoo3 cards,[35] and that list expanded during the 2.4.x series, with drivers for ATI Radeon cards, some SiS video cards and Intel 830M and and subsequent integrated GPUs.

The split of DRM into two components, DRM core and DRM driver, called DRM core/personality split was done during the second half of 2004,[36] and merged into kernel version 2.6.11.[37] This split allowed multiple DRM drivers for multiple devices to work simultaneously, opening the way to muti-GPU support.

The increasing complexity of video memory management led to several approaches to solving this issue. The first attempt was the Translation Table Maps (TTM) memory manager, developed by Thomas Hellstrom (Tungsten Graphics) in collaboration with Eric Anholt (Intel) and Dave Airlie (Red Hat).[38] TTM was proposed for inclusion into mainline kernel 2.6.25 in November 2007,[38] and againt in May 2008, but was ditched in favor of a new approach called Graphics Execution Manager (GEM).[39] GEM was first developed by Keith Packard and Eric Anholt from Intel as simpler solution for memory management for their i915 driver.[5] Intel's GEM also provides control execution flow for their i915 —and later— GPUs, but no other driver has attempted to use the whole GEM API beyond the memory management specific ioctls.

GEM was well received and merged into the Linux kernel version 2.6.28.[40]

In 2013, as part of GSoC, David Herrmann developed the multiple render nodes feature.[41] His code was added to the Linux kernel version 3.12 as an experimental feature[42][43][44][45][46] and enabled by default since Linux 3.17.[47]

^Vetter, Daniel. "i915/GEM Crashcourse by Daniel Vetter". Intel Open Source Technology Center. Retrieved 31 January 2015. "GEM essentially deals with graphics buffer objects (which can contain textures, renderbuffers, shaders, or all kinds of other state objects and data used by the gpu)"

^Packard, Keith (28 September 2012). "DRI-Next". Retrieved 13 February 2015. "GEM flink has lots of issues. The flink names are global, allowing anyone with access to the device to access the flink data contents."