diff --git a/man/Makefile.am b/man/Makefile.am index 01b56994..b393072a 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -6,6 +6,7 @@ MANPAGES = \ drm.7 \ + drm-kms.7 \ drmAvailable.3 \ drmHandleEvent.3 \ drmModeGetResources.3 diff --git a/man/drm-kms.xml b/man/drm-kms.xml new file mode 100644 index 00000000..5f041578 --- /dev/null +++ b/man/drm-kms.xml @@ -0,0 +1,342 @@ + + + + + + + + Direct Rendering Manager + libdrm + September 2012 + + + Developer + David + Herrmann + dh.herrmann@googlemail.com + + + + + + drm-kms + 7 + + + + drm-kms + Kernel Mode-Setting + + + + + #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 + drmModeSettingSupported3 + 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 + drmModeCrtcSet3 + 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 explicitely 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-memory7 + API. + + + + + + + Mode-Setting + Before mode-setting can be performed, an application needs to call + drmSetMaster3 + to become DRM-Master. It then has exclusive + access to the KMS API. A call to + drmModeGetResources3 + 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 + drmModeGetConnector3 + 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-memory7. + 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 + drmModeAddFB3 + and + drmModeAddFB23. + + As a last step, you want to program your CRTC to drive your selected + connector. You can do this with a call to + drmModeSetCrtc3. + + + + Page-Flipping + A call to + drmModeSetCrtc3 + 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 + drmModeSetCrtc3 + on the next buffer to flip. If you want to synchronize your flips + with vertical-blanks, you can use + drmModePageFlip3 + which schedules your page-flip for the next + vblank. + + + + Planes + Planes are controlled independently from CRTCs. That is, a call to + drmModeSetCrtc3 + does not affect planes. Instead, you need to call + drmModeSetPlane3 + 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 + drmModeGetPlaneResources3 + 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 + drmModeSetCursor3 + and move it on the screen with + drmModeMoveCursor3. + 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 + drmModeGetResources3 + as drmModeRes *res, + selected a connector from the list in + res->connectors + and retrieved the connector-information as + drmModeConnector *conn + via + drmModeGetConnector3 + 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 + drmOpen3) + 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 + http://bugs.freedesktop.org under the "Mesa" product, with "Other" or + "libdrm" as the component. + + + + See Also + + drm7, + drm-memory7, + drmModeGetResources3, + drmModeGetConnector3, + drmModeGetEncoder3, + drmModeGetCrtc3, + drmModeSetCrtc3, + drmModeGetFB3, + drmModeAddFB3, + drmModeAddFB23, + drmModeRmFB3, + drmModePageFlip3, + drmModeGetPlaneResources3, + drmModeGetPlane3, + drmModeSetPlane3, + drmModeSetCursor3, + drmModeMoveCursor3, + drmSetMaster3, + drmAvailable3, + drmCheckModesettingSupported3, + drmOpen3 + + +