1======= 2drm-kms 3======= 4 5------------------- 6Kernel Mode-Setting 7------------------- 8 9:Date: September 2012 10:Manual section: 7 11:Manual group: Direct Rendering Manager 12 13Synopsis 14======== 15 16``#include <xf86drm.h>`` 17 18``#include <xf86drmMode.h>`` 19 20Description 21=========== 22 23Each DRM device provides access to manage which monitors and displays are 24currently used and what frames to be displayed. This task is called *Kernel 25Mode-Setting* (KMS). Historically, this was done in user-space and called 26*User-space Mode-Setting* (UMS). Almost all open-source drivers now provide the 27KMS kernel API to do this in the kernel, however, many non-open-source binary 28drivers from different vendors still do not support this. You can use 29**drmModeSettingSupported**\ (3) to check whether your driver supports this. To 30understand how KMS works, we need to introduce 5 objects: *CRTCs*, *Planes*, 31*Encoders*, *Connectors* and *Framebuffers*. 32 33CRTCs 34 A *CRTC* short for *CRT Controller* is an abstraction representing a part of 35 the chip that contains a pointer to a scanout buffer. Therefore, the number 36 of CRTCs available determines how many independent scanout buffers can be 37 active at any given time. The CRTC structure contains several fields to 38 support this: a pointer to some video memory (abstracted as a frame-buffer 39 object), a list of driven connectors, a display mode and an (x, y) offset 40 into the video memory to support panning or configurations where one piece 41 of video memory spans multiple CRTCs. A CRTC is the central point where 42 configuration of displays happens. You select which objects to use, which 43 modes and which parameters and then configure each CRTC via 44 **drmModeCrtcSet**\ (3) to drive the display devices. 45 46Planes 47 A *plane* respresents an image source that can be blended with or overlayed 48 on top of a CRTC during the scanout process. Planes are associated with a 49 frame-buffer to crop a portion of the image memory (source) and optionally 50 scale it to a destination size. The result is then blended with or overlayed 51 on top of a CRTC. Planes are not provided by all hardware and the number of 52 available planes is limited. If planes are not available or if not enough 53 planes are available, the user should fall back to normal software blending 54 (via GPU or CPU). 55 56Encoders 57 An *encoder* takes pixel data from a CRTC and converts it to a format 58 suitable for any attached connectors. On some devices, it may be possible to 59 have a CRTC send data to more than one encoder. In that case, both encoders 60 would receive data from the same scanout buffer, resulting in a *cloned* 61 display configuration across the connectors attached to each encoder. 62 63Connectors 64 A *connector* is the final destination of pixel-data on a device, and 65 usually connects directly to an external display device like a monitor or 66 laptop panel. A connector can only be attached to one encoder at a time. The 67 connector is also the structure where information about the attached display 68 is kept, so it contains fields for display data, *EDID* data, *DPMS* and 69 *connection status*, and information about modes supported on the attached 70 displays. 71 72Framebuffers 73 *Framebuffers* are abstract memory objects that provide a source of pixel 74 data to scanout to a CRTC. Applications explicitly request the creation of 75 framebuffers and can control their behavior. Framebuffers rely on the 76 underneath memory manager for low-level memory operations. When creating a 77 framebuffer, applications pass a memory handle through the API which is used 78 as backing storage. The framebuffer itself is only an abstract object with 79 no data. It just refers to memory buffers that must be created with the 80 **drm-memory**\ (7) API. 81 82Mode-Setting 83------------ 84 85Before mode-setting can be performed, an application needs to call 86**drmSetMaster**\ (3) to become *DRM-Master*. It then has exclusive access to 87the KMS API. A call to **drmModeGetResources**\ (3) returns a list of *CRTCs*, 88*Connectors*, *Encoders* and *Planes*. 89 90Normal procedure now includes: First, you select which connectors you want to 91use. Users are mostly interested in which monitor or display-panel is active so 92you need to make sure to arrange them in the correct logical order and select 93the correct ones to use. For each connector, you need to find a CRTC to drive 94this connector. If you want to clone output to two or more connectors, you may 95use a single CRTC for all cloned connectors (if the hardware supports this). To 96find a suitable CRTC, you need to iterate over the list of encoders that are 97available for each connector. Each encoder contains a list of CRTCs that it can 98work with and you simply select one of these CRTCs. If you later program the 99CRTC to control a connector, it automatically selects the best encoder. 100However, this procedure is needed so your CRTC has at least one working encoder 101for the selected connector. See the *Examples* section below for more 102information. 103 104All valid modes for a connector can be retrieved with a call to 105**drmModeGetConnector**\ (3) You need to select the mode you want to use and save it. 106The first mode in the list is the default mode with the highest resolution 107possible and often a suitable choice. 108 109After you have a working connector+CRTC+mode combination, you need to create a 110framebuffer that is used for scanout. Memory buffer allocation is 111driver-dependent and described in **drm-memory**\ (7). You need to create a 112buffer big enough for your selected mode. Now you can create a framebuffer 113object that uses your memory-buffer as scanout buffer. You can do this with 114**drmModeAddFB**\ (3) and **drmModeAddFB2**\ (3). 115 116As a last step, you want to program your CRTC to drive your selected connector. 117You can do this with a call to **drmModeSetCrtc**\ (3). 118 119Page-Flipping 120------------- 121 122A call to **drmModeSetCrtc**\ (3) is executed immediately and forces the CRTC 123to use the new scanout buffer. If you want smooth-transitions without tearing, 124you probably use double-buffering. You need to create one framebuffer object 125for each buffer you use. You can then call **drmModeSetCrtc**\ (3) on the next 126buffer to flip. If you want to synchronize your flips with *vertical-blanks*, 127you can use **drmModePageFlip**\ (3) which schedules your page-flip for the 128next *vblank*. 129 130Planes 131------ 132 133Planes are controlled independently from CRTCs. That is, a call to 134**drmModeSetCrtc**\ (3) does not affect planes. Instead, you need to call 135**drmModeSetPlane**\ (3) to configure a plane. This requires the plane ID, a 136CRTC, a framebuffer and offsets into the plane-framebuffer and the 137CRTC-framebuffer. The CRTC then blends the content from the plane over the CRTC 138framebuffer buffer during scanout. As this does not involve any 139software-blending, it is way faster than traditional blending. However, plane 140resources are limited. See **drmModeGetPlaneResources**\ (3) for more 141information. 142 143Cursors 144------- 145 146Similar to planes, many hardware also supports cursors. A cursor is a very 147small buffer with an image that is blended over the CRTC framebuffer. You can 148set a different cursor for each CRTC with **drmModeSetCursor**\ (3) and move it 149on the screen with **drmModeMoveCursor**\ (3). This allows to move the cursor 150on the screen without rerendering. If no hardware cursors are supported, you 151need to rerender for each frame the cursor is moved. 152 153Examples 154======== 155 156Some examples of how basic mode-setting can be done. See the man-page of each 157DRM function for more information. 158 159CRTC/Encoder Selection 160---------------------- 161 162If you retrieved all display configuration information via 163**drmModeGetResources**\ (3) as ``drmModeRes *res``, selected a connector from 164the list in ``res->connectors`` and retrieved the connector-information as 165``drmModeConnector *conn`` via **drmModeGetConnector**\ (3) then this example 166shows, how you can find a suitable CRTC id to drive this connector. This 167function takes a file-descriptor to the DRM device (see **drmOpen**\ (3)) as 168``fd``, a pointer to the retrieved resources as ``res`` and a pointer to the 169selected connector as ``conn``. It returns an integer smaller than 0 on 170failure, otherwise, a valid CRTC id is returned. 171 172:: 173 174 static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn) 175 { 176 drmModeEncoder *enc; 177 unsigned int i, j; 178 179 /* iterate all encoders of this connector */ 180 for (i = 0; i < conn->count_encoders; ++i) { 181 enc = drmModeGetEncoder(fd, conn->encoders[i]); 182 if (!enc) { 183 /* cannot retrieve encoder, ignoring... */ 184 continue; 185 } 186 187 /* iterate all global CRTCs */ 188 for (j = 0; j < res->count_crtcs; ++j) { 189 /* check whether this CRTC works with the encoder */ 190 if (!(enc->possible_crtcs & (1 << j))) 191 continue; 192 193 194 /* Here you need to check that no other connector 195 * currently uses the CRTC with id "crtc". If you intend 196 * to drive one connector only, then you can skip this 197 * step. Otherwise, simply scan your list of configured 198 * connectors and CRTCs whether this CRTC is already 199 * used. If it is, then simply continue the search here. */ 200 if (res->crtcs[j] "is unused") { 201 drmModeFreeEncoder(enc); 202 return res->crtcs[j]; 203 } 204 } 205 206 drmModeFreeEncoder(enc); 207 } 208 209 /* cannot find a suitable CRTC */ 210 return -ENOENT; 211 } 212 213Reporting Bugs 214============== 215 216Bugs in this manual should be reported to 217https://gitlab.freedesktop.org/mesa/drm/-/issues 218 219See Also 220======== 221 222**drm**\ (7), **drm-memory**\ (7), **drmModeGetResources**\ (3), 223**drmModeGetConnector**\ (3), **drmModeGetEncoder**\ (3), 224**drmModeGetCrtc**\ (3), **drmModeSetCrtc**\ (3), **drmModeGetFB**\ (3), 225**drmModeAddFB**\ (3), **drmModeAddFB2**\ (3), **drmModeRmFB**\ (3), 226**drmModePageFlip**\ (3), **drmModeGetPlaneResources**\ (3), 227**drmModeGetPlane**\ (3), **drmModeSetPlane**\ (3), **drmModeSetCursor**\ (3), 228**drmModeMoveCursor**\ (3), **drmSetMaster**\ (3), **drmAvailable**\ (3), 229**drmCheckModesettingSupported**\ (3), **drmOpen**\ (3) 230