Manual Page Result
0
Command: drm-kms | Section: 7 | Source: OpenBSD | File: drm-kms.7
DRM-KMS(7) Direct Rendering Manager DRM-KMS(7)
NAME
drm-kms - Kernel Mode-Setting
SYNOPSIS
#include <xf86drm.h>
#include <xf86drmMode.h>
DESCRIPTION
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 dri-
vers 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 in-
troduce 5 objects: CRTCs, Planes, Encoders, Connectors and Frame-
buffers.
CRTCs 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 in-
dependent 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 ob-
ject), a list of driven connectors, a display mode and an (x, y)
offset into the video memory to support panning or configura-
tions where one piece of video memory spans multiple CRTCs. A
CRTC is the central point where configuration of displays hap-
pens. You select which objects to use, which modes and which pa-
rameters and then configure each CRTC via drmModeCrtcSet(3) to
drive the display devices.
Planes 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 im-
age 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).
Encoders
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 en-
coder. 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.
Connectors
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
Framebuffers are abstract memory objects that provide a source
of pixel data to scanout to a CRTC. Applications explicitly re-
quest the creation of framebuffers and can control their behav-
ior. Framebuffers rely on the underneath memory manager for
low-level memory operations. When creating a framebuffer, appli-
cations pass a memory handle through the API which is used as
backing storage. The framebuffer itself is only an abstract ob-
ject with no data. It just refers to memory buffers that must be
created with the drm-memory(7) API.
Mode-Setting
Before mode-setting can be performed, an application needs to call drm-
SetMaster(3) to become DRM-Master. It then has exclusive access to the
KMS API. A call to drmModeGetResources(3) returns a list of CRTCs, Con-
nectors, Encoders and Planes.
Normal procedure now includes: First, you select which connectors you
want to use. Users are mostly interested in which monitor or dis-
play-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 con-
nector, 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 suit-
able 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 Exam-
ples section below for more information.
All valid modes for a connector can be retrieved with a call to drmMod-
eGetConnector(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-dependent and described in drm-memory(7). You need to create
a buffer big enough for your selected mode. Now you can create a frame-
buffer 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).
Page-Flipping
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 drmMode-
SetCrtc(3) on the next buffer to flip. If you want to synchronize your
flips with vertical-blanks, you can use drmModePageFlip(3) which sched-
ules your page-flip for the next vblank.
Planes
Planes are controlled independently from CRTCs. That is, a call to drm-
ModeSetCrtc(3) does not affect planes. Instead, you need to call drm-
ModeSetPlane(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. How-
ever, plane resources are limited. See drmModeGetPlaneResources(3) for
more information.
Cursors
Similar to planes, many hardware also supports cursors. A cursor is a
very small buffer with an image that is blended over the CRTC frame-
buffer. You can set a different cursor for each CRTC with drmMode-
SetCursor(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.
EXAMPLES
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 drmModeGe-
tResources(3) as drmModeRes *res, selected a connector from the list in
res->connectors and retrieved the connector-information as drmModeCon-
nector *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... */
continue;
}
/* 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)))
continue;
/* 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") {
drmModeFreeEncoder(enc);
return res->crtcs[j];
}
}
drmModeFreeEncoder(enc);
}
/* cannot find a suitable CRTC */
return -ENOENT;
}
REPORTING BUGS
Bugs in this manual should be reported to
<https://gitlab.freedesktop.org/mesa/drm/-/issues>
SEE ALSO
drm(7), drm-memory(7), drmModeGetResources(3), drmModeGetConnector(3),
drmModeGetEncoder(3), drmModeGetCrtc(3), drmModeSetCrtc(3), drmMod-
eGetFB(3), drmModeAddFB(3), drmModeAddFB2(3), drmModeRmFB(3), drmMode-
PageFlip(3), drmModeGetPlaneResources(3), drmModeGetPlane(3), drmMode-
SetPlane(3), drmModeSetCursor(3), drmModeMoveCursor(3), drmSetMas-
ter(3), drmAvailable(3), drmCheckModesettingSupported(3), drmOpen(3)
September 2012 DRM-KMS(7)