• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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@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 &lt;xf86drm.h&gt;</funcsynopsisinfo>
38      <funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</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>
265static 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 &lt; 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 &lt; res->count_crtcs; ++j) {
280			/* check whether this CRTC works with the encoder */
281			if (!(enc->possible_crtcs &amp; (1 &lt;&lt; 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