1 <?xml version='1.0'?> <!--*-nxml-*--> 2 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 3 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> 4 5 <!-- 6 Written 2012 by David Herrmann <dh.herrmann (a] googlemail.com> 7 Dedicated to the Public Domain 8 --> 9 10 <refentry id="drm-kms"> 11 <refentryinfo> 12 <title>Direct Rendering Manager</title> 13 <productname>libdrm</productname> 14 <date>September 2012</date> 15 <authorgroup> 16 <author> 17 <contrib>Developer</contrib> 18 <firstname>David</firstname> 19 <surname>Herrmann</surname> 20 <email>dh.herrmann (a] googlemail.com</email> 21 </author> 22 </authorgroup> 23 </refentryinfo> 24 25 <refmeta> 26 <refentrytitle>drm-kms</refentrytitle> 27 <manvolnum>7</manvolnum> 28 </refmeta> 29 30 <refnamediv> 31 <refname>drm-kms</refname> 32 <refpurpose>Kernel Mode-Setting</refpurpose> 33 </refnamediv> 34 35 <refsynopsisdiv> 36 <funcsynopsis> 37 <funcsynopsisinfo>#include <xf86drm.h></funcsynopsisinfo> 38 <funcsynopsisinfo>#include <xf86drmMode.h></funcsynopsisinfo> 39 </funcsynopsis> 40 </refsynopsisdiv> 41 42 <refsect1> 43 <title>Description</title> 44 <para>Each DRM device provides access to manage which monitors and displays 45 are currently used and what frames to be displayed. This task is 46 called <emphasis>Kernel Mode-Setting</emphasis> (KMS). Historically, 47 this was done in user-space and called 48 <emphasis>User-space Mode-Setting</emphasis> (UMS). Almost all 49 open-source drivers now provide the KMS kernel API to do this in the 50 kernel, however, many non-open-source binary drivers from different 51 vendors still do not support this. You can use 52 <citerefentry><refentrytitle>drmModeSettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry> 53 to check whether your driver supports this. To understand how KMS 54 works, we need to introduce 5 objects: <emphasis>CRTCs</emphasis>, 55 <emphasis>Planes</emphasis>, <emphasis>Encoders</emphasis>, 56 <emphasis>Connectors</emphasis> and 57 <emphasis>Framebuffers</emphasis>. 58 59 <variablelist> 60 <varlistentry> 61 <term>CRTCs</term> 62 <listitem> 63 <para>A <emphasis>CRTC</emphasis> short for 64 <emphasis>CRT Controller</emphasis> is an abstraction 65 representing a part of the chip that contains a pointer to a 66 scanout buffer. Therefore, the number of CRTCs available 67 determines how many independent scanout buffers can be active 68 at any given time. The CRTC structure contains several fields 69 to support this: a pointer to some video memory (abstracted as 70 a frame-buffer object), a list of driven connectors, a display 71 mode and an (x, y) offset into the video memory to support 72 panning or configurations where one piece of video memory 73 spans multiple CRTCs. A CRTC is the central point where 74 configuration of displays happens. You select which objects to 75 use, which modes and which parameters and then configure each 76 CRTC via 77 <citerefentry><refentrytitle>drmModeCrtcSet</refentrytitle><manvolnum>3</manvolnum></citerefentry> 78 to drive the display devices.</para> 79 </listitem> 80 </varlistentry> 81 <varlistentry> 82 <term>Planes</term> 83 <listitem> 84 <para>A <emphasis>plane</emphasis> respresents an image source that 85 can be blended with or overlayed on top of a CRTC during the 86 scanout process. Planes are associated with a frame-buffer to 87 crop a portion of the image memory (source) and optionally 88 scale it to a destination size. The result is then blended 89 with or overlayed on top of a CRTC. Planes are not provided by 90 all hardware and the number of available planes is limited. If 91 planes are not available or if not enough planes are 92 available, the user should fall back to normal software 93 blending (via GPU or CPU).</para> 94 </listitem> 95 </varlistentry> 96 <varlistentry> 97 <term>Encoders</term> 98 <listitem> 99 <para>An <emphasis>encoder</emphasis> takes pixel data from a CRTC 100 and converts it to a format suitable for any attached 101 connectors. On some devices, it may be possible to have a CRTC 102 send data to more than one encoder. In that case, both 103 encoders would receive data from the same scanout buffer, 104 resulting in a <emphasis>cloned</emphasis> display 105 configuration across the connectors attached to each 106 encoder.</para> 107 </listitem> 108 </varlistentry> 109 <varlistentry> 110 <term>Connectors</term> 111 <listitem> 112 <para>A <emphasis>connector</emphasis> is the final destination of 113 pixel-data on a device, and usually connects directly to an 114 external display device like a monitor or laptop panel. A 115 connector can only be attached to one encoder at a time. The 116 connector is also the structure where information about the 117 attached display is kept, so it contains fields for display 118 data, <emphasis>EDID</emphasis> data, 119 <emphasis>DPMS</emphasis> and 120 <emphasis>connection status</emphasis>, and information about 121 modes supported on the attached displays.</para> 122 </listitem> 123 </varlistentry> 124 <varlistentry> 125 <term>Framebuffers</term> 126 <listitem> 127 <para><emphasis>Framebuffers</emphasis> are abstract memory objects 128 that provide a source of pixel data to scanout to a CRTC. 129 Applications explicitely request the creation of framebuffers 130 and can control their behavior. Framebuffers rely on the 131 underneath memory manager for low-level memory operations. 132 When creating a framebuffer, applications pass a memory handle 133 through the API which is used as backing storage. The 134 framebuffer itself is only an abstract object with no data. It 135 just refers to memory buffers that must be created with the 136 <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry> 137 API.</para> 138 </listitem> 139 </varlistentry> 140 </variablelist> 141 </para> 142 143 <refsect2> 144 <title>Mode-Setting</title> 145 <para>Before mode-setting can be performed, an application needs to call 146 <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry> 147 to become <emphasis>DRM-Master</emphasis>. It then has exclusive 148 access to the KMS API. A call to 149 <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry> 150 returns a list of <emphasis>CRTCs</emphasis>, 151 <emphasis>Connectors</emphasis>, <emphasis>Encoders</emphasis> and 152 <emphasis>Planes</emphasis>.</para> 153 154 <para>Normal procedure now includes: First, you select which connectors 155 you want to use. Users are mostly interested in which monitor or 156 display-panel is active so you need to make sure to arrange them in 157 the correct logical order and select the correct ones to use. For 158 each connector, you need to find a CRTC to drive this connector. If 159 you want to clone output to two or more connectors, you may use a 160 single CRTC for all cloned connectors (if the hardware supports 161 this). To find a suitable CRTC, you need to iterate over the list of 162 encoders that are available for each connector. Each encoder 163 contains a list of CRTCs that it can work with and you simply select 164 one of these CRTCs. If you later program the CRTC to control a 165 connector, it automatically selects the best encoder. However, this 166 procedure is needed so your CRTC has at least one working encoder 167 for the selected connector. See the <emphasis>Examples</emphasis> 168 section below for more information.</para> 169 170 <para>All valid modes for a connector can be retrieved with a call to 171 <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry> 172 You need to select the mode you want to use and save it. The first 173 mode in the list is the default mode with the highest resolution 174 possible and often a suitable choice.</para> 175 176 <para>After you have a working connector+CRTC+mode combination, you need 177 to create a framebuffer that is used for scanout. Memory buffer 178 allocation is driver-depedent and described in 179 <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>. 180 You need to create a buffer big enough for your selected mode. Now 181 you can create a framebuffer object that uses your memory-buffer as 182 scanout buffer. You can do this with 183 <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry> 184 and 185 <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> 186 187 <para>As a last step, you want to program your CRTC to drive your selected 188 connector. You can do this with a call to 189 <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para> 190 </refsect2> 191 192 <refsect2> 193 <title>Page-Flipping</title> 194 <para>A call to 195 <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry> 196 is executed immediately and forces the CRTC to use the new scanout 197 buffer. If you want smooth-transitions without tearing, you probably 198 use double-buffering. You need to create one framebuffer object for 199 each buffer you use. You can then call 200 <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry> 201 on the next buffer to flip. If you want to synchronize your flips 202 with <emphasis>vertical-blanks</emphasis>, you can use 203 <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry> 204 which schedules your page-flip for the next 205 <emphasis>vblank</emphasis>.</para> 206 </refsect2> 207 208 <refsect2> 209 <title>Planes</title> 210 <para>Planes are controlled independently from CRTCs. That is, a call to 211 <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry> 212 does not affect planes. Instead, you need to call 213 <citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry> 214 to configure a plane. This requires the plane ID, a CRTC, a 215 framebuffer and offsets into the plane-framebuffer and the 216 CRTC-framebuffer. The CRTC then blends the content from the plane 217 over the CRTC framebuffer buffer during scanout. As this does not 218 involve any software-blending, it is way faster than traditional 219 blending. However, plane resources are limited. See 220 <citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry> 221 for more information.</para> 222 </refsect2> 223 224 <refsect2> 225 <title>Cursors</title> 226 <para>Similar to planes, many hardware also supports cursors. A cursor is 227 a very small buffer with an image that is blended over the CRTC 228 framebuffer. You can set a different cursor for each CRTC with 229 <citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry> 230 and move it on the screen with 231 <citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>. 232 This allows to move the cursor on the screen without rerendering. If 233 no hardware cursors are supported, you need to rerender for each 234 frame the cursor is moved.</para> 235 </refsect2> 236 237 </refsect1> 238 239 <refsect1> 240 <title>Examples</title> 241 <para>Some examples of how basic mode-setting can be done. See the man-page 242 of each DRM function for more information.</para> 243 244 <refsect2> 245 <title>CRTC/Encoder Selection</title> 246 <para>If you retrieved all display configuration information via 247 <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry> 248 as <structname>drmModeRes</structname> *<varname>res</varname>, 249 selected a connector from the list in 250 <varname>res</varname>-><structfield>connectors</structfield> 251 and retrieved the connector-information as 252 <structname>drmModeConnector</structname> *<varname>conn</varname> 253 via 254 <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry> 255 then this example shows, how you can find a suitable CRTC id to 256 drive this connector. This function takes a file-descriptor to the 257 DRM device (see 258 <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>) 259 as <varname>fd</varname>, a pointer to the retrieved resources as 260 <varname>res</varname> and a pointer to the selected connector as 261 <varname>conn</varname>. It returns an integer smaller than 0 on 262 failure, otherwise, a valid CRTC id is returned.</para> 263 264 <programlisting> 265 static int modeset_find_crtc(int fd, drmModeRes *res, drmModeConnector *conn) 266 { 267 drmModeEncoder *enc; 268 unsigned int i, j; 269 270 /* iterate all encoders of this connector */ 271 for (i = 0; i < conn->count_encoders; ++i) { 272 enc = drmModeGetEncoder(fd, conn->encoders[i]); 273 if (!enc) { 274 /* cannot retrieve encoder, ignoring... */ 275 continue; 276 } 277 278 /* iterate all global CRTCs */ 279 for (j = 0; j < res->count_crtcs; ++j) { 280 /* check whether this CRTC works with the encoder */ 281 if (!(enc->possible_crtcs & (1 << j))) 282 continue; 283 284 285 /* Here you need to check that no other connector 286 * currently uses the CRTC with id "crtc". If you intend 287 * to drive one connector only, then you can skip this 288 * step. Otherwise, simply scan your list of configured 289 * connectors and CRTCs whether this CRTC is already 290 * used. If it is, then simply continue the search here. */ 291 if (res->crtcs[j] "is unused") { 292 drmModeFreeEncoder(enc); 293 return res->crtcs[j]; 294 } 295 } 296 297 drmModeFreeEncoder(enc); 298 } 299 300 /* cannot find a suitable CRTC */ 301 return -ENOENT; 302 } 303 </programlisting> 304 305 </refsect2> 306 307 </refsect1> 308 309 <refsect1> 310 <title>Reporting Bugs</title> 311 <para>Bugs in this manual should be reported to 312 http://bugs.freedesktop.org under the "Mesa" product, with "Other" or 313 "libdrm" as the component.</para> 314 </refsect1> 315 316 <refsect1> 317 <title>See Also</title> 318 <para> 319 <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>, 320 <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>, 321 <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 322 <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 323 <citerefentry><refentrytitle>drmModeGetEncoder</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 324 <citerefentry><refentrytitle>drmModeGetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 325 <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 326 <citerefentry><refentrytitle>drmModeGetFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 327 <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 328 <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 329 <citerefentry><refentrytitle>drmModeRmFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 330 <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 331 <citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 332 <citerefentry><refentrytitle>drmModeGetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 333 <citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 334 <citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 335 <citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 336 <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 337 <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 338 <citerefentry><refentrytitle>drmCheckModesettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>, 339 <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry> 340 </para> 341 </refsect1> 342 </refentry> 343