Go to main content

man pages section 7: Standards, Environments, Macros, Character Sets, and Miscellany

Exit Print View

Updated: Wednesday, July 27, 2022

drm-kms (7)


drm-kms - Setting


#include <xf86drm.h>

#include <xf86drmMode.h>


DRM-KMS(7)                 Direct Rendering Manager                 DRM-KMS(7)

       drm-kms - Kernel Mode-Setting

       #include <xf86drm.h>

       #include <xf86drmMode.h>

       Each DRM device provides access to manage which monitors and displays
       are currently used and what frames to be displayed. This task is called
       Kernel Mode-Setting (KMS). Historically, this was done in user-space
       and called User-space Mode-Setting (UMS). Almost all open-source
       drivers now provide the KMS kernel API to do this in the kernel,
       however, many non-open-source binary drivers from different vendors
       still do not support this. You can use drmModeSettingSupported(3) to
       check whether your driver supports this. To understand how KMS works,
       we need to introduce 5 objects: CRTCs, Planes, Encoders, Connectors and

           A CRTC short for CRT Controller is an abstraction representing a
           part of the chip that contains a pointer to a scanout buffer.
           Therefore, the number of CRTCs available determines how many
           independent scanout buffers can be active at any given time. The
           CRTC structure contains several fields to support this: a pointer
           to some video memory (abstracted as a frame-buffer object), a list
           of driven connectors, a display mode and an (x, y) offset into the
           video memory to support panning or configurations where one piece
           of video memory spans multiple CRTCs. A CRTC is the central point
           where configuration of displays happens. You select which objects
           to use, which modes and which parameters and then configure each
           CRTC via drmModeCrtcSet(3) to drive the display devices.

           A plane respresents an image source that can be blended with or
           overlayed on top of a CRTC during the scanout process. Planes are
           associated with a frame-buffer to crop a portion of the image
           memory (source) and optionally scale it to a destination size. The
           result is then blended with or overlayed on top of a CRTC. Planes
           are not provided by all hardware and the number of available planes
           is limited. If planes are not available or if not enough planes are
           available, the user should fall back to normal software blending
           (via GPU or CPU).

           An encoder takes pixel data from a CRTC and converts it to a format
           suitable for any attached connectors. On some devices, it may be
           possible to have a CRTC send data to more than one encoder. In that
           case, both encoders would receive data from the same scanout
           buffer, resulting in a cloned display configuration across the
           connectors attached to each encoder.

           A connector is the final destination of pixel-data on a device, and
           usually connects directly to an external display device like a
           monitor or laptop panel. A connector can only be attached to one
           encoder at a time. The connector is also the structure where
           information about the attached display is kept, so it contains
           fields for display data, EDID data, DPMS and connection status, and
           information about modes supported on the attached displays.

           Framebuffers are abstract memory objects that provide a source of
           pixel data to scanout to a CRTC. Applications explicitly request
           the creation of framebuffers and can control their behavior.
           Framebuffers rely on the underneath memory manager for low-level
           memory operations. When creating a framebuffer, applications pass a
           memory handle through the API which is used as backing storage. The
           framebuffer itself is only an abstract object with no data. It just
           refers to memory buffers that must be created with the drm-
           memory(7) API.

       Before mode-setting can be performed, an application needs to call
       drmSetMaster(3) to become DRM-Master. It then has exclusive access to
       the KMS API. A call to drmModeGetResources(3) returns a list of CRTCs,
       Connectors, Encoders and Planes.

       Normal procedure now includes: First, you select which connectors you
       want to use. Users are mostly interested in which monitor or
       display-panel is active so you need to make sure to arrange them in the
       correct logical order and select the correct ones to use. For each
       connector, you need to find a CRTC to drive this connector. If you want
       to clone output to two or more connectors, you may use a single CRTC
       for all cloned connectors (if the hardware supports this). To find a
       suitable CRTC, you need to iterate over the list of encoders that are
       available for each connector. Each encoder contains a list of CRTCs
       that it can work with and you simply select one of these CRTCs. If you
       later program the CRTC to control a connector, it automatically selects
       the best encoder. However, this procedure is needed so your CRTC has at
       least one working encoder for the selected connector. See the Examples
       section below for more information.

       All valid modes for a connector can be retrieved with a call to
       drmModeGetConnector(3) You need to select the mode you want to use and
       save it. The first mode in the list is the default mode with the
       highest resolution possible and often a suitable choice.

       After you have a working connector+CRTC+mode combination, you need to
       create a framebuffer that is used for scanout. Memory buffer allocation
       is driver-depedent and described in drm-memory(7). You need to create a
       buffer big enough for your selected mode. Now you can create a
       framebuffer object that uses your memory-buffer as scanout buffer. You
       can do this with drmModeAddFB(3) and drmModeAddFB2(3).

       As a last step, you want to program your CRTC to drive your selected
       connector. You can do this with a call to drmModeSetCrtc(3).

       A call to drmModeSetCrtc(3) is executed immediately and forces the CRTC
       to use the new scanout buffer. If you want smooth-transitions without
       tearing, you probably use double-buffering. You need to create one
       framebuffer object for each buffer you use. You can then call
       drmModeSetCrtc(3) on the next buffer to flip. If you want to
       synchronize your flips with vertical-blanks, you can use
       drmModePageFlip(3) which schedules your page-flip for the next vblank.

       Planes are controlled independently from CRTCs. That is, a call to
       drmModeSetCrtc(3) does not affect planes. Instead, you need to call
       drmModeSetPlane(3) to configure a plane. This requires the plane ID, a
       CRTC, a framebuffer and offsets into the plane-framebuffer and the
       CRTC-framebuffer. The CRTC then blends the content from the plane over
       the CRTC framebuffer buffer during scanout. As this does not involve
       any software-blending, it is way faster than traditional blending.
       However, plane resources are limited. See drmModeGetPlaneResources(3)
       for more information.

       Similar to planes, many hardware also supports cursors. A cursor is a
       very small buffer with an image that is blended over the CRTC
       framebuffer. You can set a different cursor for each CRTC with
       drmModeSetCursor(3) and move it on the screen with
       drmModeMoveCursor(3). This allows to move the cursor on the screen
       without rerendering. If no hardware cursors are supported, you need to
       rerender for each frame the cursor is moved.

       Some examples of how basic mode-setting can be done. See the man-page
       of each DRM function for more information.

   CRTC/Encoder Selection
       If you retrieved all display configuration information via
       drmModeGetResources(3) as drmModeRes *res, selected a connector from
       the list in res->connectors and retrieved the connector-information as
       drmModeConnector *conn via drmModeGetConnector(3) then this example
       shows, how you can find a suitable CRTC id to drive this connector.
       This function takes a file-descriptor to the DRM device (see
       drmOpen(3)) as fd, a pointer to the retrieved resources as res and a
       pointer to the selected connector as conn. It returns an integer
       smaller than 0 on failure, otherwise, a valid CRTC id is returned.

           static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn)
                drmModeEncoder *enc;
                unsigned int i, j;

                /* iterate all encoders of this connector */
                for (i = 0; i < conn->count_encoders; ++i) {
                     enc = drmModeGetEncoder(fd, conn->encoders[i]);
                     if (!enc) {
                          /* cannot retrieve encoder, ignoring... */

                     /* iterate all global CRTCs */
                     for (j = 0; j < res->count_crtcs; ++j) {
                          /* check whether this CRTC works with the encoder */
                          if (!(enc->possible_crtcs & (1 << j)))

                          /* Here you need to check that no other connector
                           * currently uses the CRTC with id "crtc". If you intend
                           * to drive one connector only, then you can skip this
                           * step. Otherwise, simply scan your list of configured
                           * connectors and CRTCs whether this CRTC is already
                           * used. If it is, then simply continue the search here. */
                          if (res->crtcs[j] "is unused") {
                               return res->crtcs[j];


                /* cannot find a suitable CRTC */
                return -ENOENT;

       Bugs in this manual should be reported to
       under the "DRI" product, component "libdrm"

       See attributes(7) for descriptions of the following attributes:

       |Availability   | x11/library/libdrm |
       |Stability      | Volatile           |

       drm(7), drm-memory(7), drmModeGetResources(3), drmModeGetConnector(3),
       drmModeGetEncoder(3), drmModeGetCrtc(3), drmModeSetCrtc(3),
       drmModeGetFB(3), drmModeAddFB(3), drmModeAddFB2(3), drmModeRmFB(3),
       drmModePageFlip(3), drmModeGetPlaneResources(3), drmModeGetPlane(3),
       drmModeSetPlane(3), drmModeSetCursor(3), drmModeMoveCursor(3),
       drmSetMaster(3), drmAvailable(3), drmCheckModesettingSupported(3),

       Source code for open source software components in Oracle Solaris can
       be found at https://www.oracle.com/downloads/opensource/solaris-source-

       This software was built from source available at
       https://github.com/oracle/solaris-userland.  The original community
       source was downloaded from

       Further information about this software can be found on the open source
       community website at https://dri.freedesktop.org/.

libdrm                          September 2012                      DRM-KMS(7)