Provided by: libdrm-dev_2.4.122-1~ubuntu0.24.04.1_amd64 bug

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 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
       Framebuffers.

       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
              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.

       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  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).

       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 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.

       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 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.

   Mode-Setting
       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-dependent 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).

   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 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
       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.

   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  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.

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  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... */
                      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), 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), drmOpen(3)

                                                 September 2012                                       DRM-KMS(7)