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-memory">
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-memory</refentrytitle>
27    <manvolnum>7</manvolnum>
28  </refmeta>
29
30  <refnamediv>
31    <refname>drm-memory</refname>
32    <refname>drm-mm</refname>
33    <refname>drm-gem</refname>
34    <refname>drm-ttm</refname>
35    <refpurpose>DRM Memory Management</refpurpose>
36  </refnamediv>
37
38  <refsynopsisdiv>
39    <funcsynopsis>
40      <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
41    </funcsynopsis>
42  </refsynopsisdiv>
43
44  <refsect1>
45    <title>Description</title>
46      <para>Many modern high-end GPUs come with their own memory managers. They
47            even include several different caches that need to be synchronized
48            during access. Textures, framebuffers, command buffers and more need
49            to be stored in memory that can be accessed quickly by the GPU.
50            Therefore, memory management on GPUs is highly driver- and
51            hardware-dependent.</para>
52
53      <para>However, there are several frameworks in the kernel that are used by
54            more than one driver. These can be used for trivial mode-setting
55            without requiring driver-dependent code. But for
56            hardware-accelerated rendering you need to read the manual pages for
57            the driver you want to work with.</para>
58
59    <refsect2>
60      <title>Dumb-Buffers</title>
61      <para>Almost all in-kernel DRM hardware drivers support an API called
62            <emphasis>Dumb-Buffers</emphasis>. This API allows to create buffers
63            of arbitrary size that can be used for scanout. These buffers can be
64            memory mapped via
65            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
66            so you can render into them on the CPU. However, GPU access to these
67            buffers is often not possible. Therefore, they are fine for simple
68            tasks but not suitable for complex compositions and
69            renderings.</para>
70
71      <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl can be
72            used to create a dumb buffer. The kernel will return a 32bit handle
73            that can be used to manage the buffer with the DRM API. You can
74            create framebuffers with
75            <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
76            and use it for mode-setting and scanout. To access the buffer, you
77            first need to retrieve the offset of the buffer. The
78            <constant>DRM_IOCTL_MODE_MAP_DUMB</constant> ioctl requests the DRM
79            subsystem to prepare the buffer for memory-mapping and returns a
80            fake-offset that can be used with
81            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
82
83      <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl takes as
84            argument a structure of type
85            <structname>struct drm_mode_create_dumb</structname>:
86
87<programlisting>
88struct drm_mode_create_dumb {
89	__u32 height;
90	__u32 width;
91	__u32 bpp;
92	__u32 flags;
93
94	__u32 handle;
95	__u32 pitch;
96	__u64 size;
97};
98</programlisting>
99
100            The fields <structfield>height</structfield>,
101            <structfield>width</structfield>, <structfield>bpp</structfield> and
102            <structfield>flags</structfield> have to be provided by the caller.
103            The other fields are filled by the kernel with the return values.
104            <structfield>height</structfield> and
105            <structfield>width</structfield> are the dimensions of the
106            rectangular buffer that is created. <structfield>bpp</structfield>
107            is the number of bits-per-pixel and must be a multiple of
108            <literal>8</literal>. You most commonly want to pass
109            <literal>32</literal> here. The <structfield>flags</structfield>
110            field is currently unused and must be zeroed. Different flags to
111            modify the behavior may be added in the future. After calling the
112            ioctl, the <structfield>handle</structfield>,
113            <structfield>pitch</structfield> and <structfield>size</structfield>
114            fields are filled by the kernel. <structfield>handle</structfield>
115            is a 32bit gem handle that identifies the buffer. This is used by
116            several other calls that take a gem-handle or memory-buffer as
117            argument. The <structfield>pitch</structfield> field is the
118            pitch (or stride) of the new buffer. Most drivers use 32bit or 64bit
119            aligned stride-values. The <structfield>size</structfield> field
120            contains the absolute size in bytes of the buffer. This can normally
121            also be computed with
122            <emphasis>(height * pitch + width) * bpp / 4</emphasis>.</para>
123
124      <para>To prepare the buffer for
125            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
126            you need to use the <constant>DRM_IOCTL_MODE_MAP_DUMB</constant>
127            ioctl. It takes as argument a structure of type
128            <structname>struct drm_mode_map_dumb</structname>:
129
130<programlisting>
131struct drm_mode_map_dumb {
132	__u32 handle;
133	__u32 pad;
134
135	__u64 offset;
136};
137</programlisting>
138
139            You need to put the gem-handle that was previously retrieved via
140            <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> into the
141            <structfield>handle</structfield> field. The
142            <structfield>pad</structfield> field is unused padding and must be
143            zeroed. After completion, the <structfield>offset</structfield>
144            field will contain an offset that can be used with
145            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
146            on the DRM file-descriptor.</para>
147
148      <para>If you don't need your dumb-buffer, anymore, you have to destroy it
149            with <constant>DRM_IOCTL_MODE_DESTROY_DUMB</constant>. If you close
150            the DRM file-descriptor, all open dumb-buffers are automatically
151            destroyed. This ioctl takes as argument a structure of type
152            <structname>struct drm_mode_destroy_dumb</structname>:
153
154<programlisting>
155struct drm_mode_destroy_dumb {
156	__u32 handle;
157};
158</programlisting>
159
160            You only need to put your handle into the
161            <structfield>handle</structfield> field. After this call, the handle
162            is invalid and may be reused for new buffers by the dumb-API.</para>
163
164    </refsect2>
165
166    <refsect2>
167      <title>TTM</title>
168      <para><emphasis>TTM</emphasis> stands for
169            <emphasis>Translation Table Manager</emphasis> and is a generic
170            memory-manager provided by the kernel. It does not provide a common
171            user-space API so you need to look at each driver interface if you
172            want to use it. See for instance the radeon manpages for more
173            information on memory-management with radeon and TTM.</para>
174    </refsect2>
175
176    <refsect2>
177      <title>GEM</title>
178      <para><emphasis>GEM</emphasis> stands for
179            <emphasis>Graphics Execution Manager</emphasis> and is a generic DRM
180            memory-management framework in the kernel, that is used by many
181            different drivers. Gem is designed to manage graphics memory,
182            control access to the graphics device execution context and handle
183            essentially NUMA environment unique to modern graphics hardware. Gem
184            allows multiple applications to share graphics device resources
185            without the need to constantly reload the entire graphics card. Data
186            may be shared between multiple applications with gem ensuring that
187            the correct memory synchronization occurs.</para>
188
189      <para>Gem provides simple mechanisms to manage graphics data and control
190            execution flow within the linux DRM subsystem. However, gem is not a
191            complete framework that is fully driver independent. Instead, if
192            provides many functions that are shared between many drivers, but
193            each driver has to implement most of memory-management with
194            driver-dependent ioctls. This manpage tries to describe the
195            semantics (and if it applies, the syntax) that is shared between all
196            drivers that use gem.</para>
197
198      <para>All GEM APIs are defined as
199            <citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
200            on the DRM file descriptor. An application must be authorized via
201            <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
202            to the current DRM-Master to access the GEM subsystem. A driver that
203            does not support gem will return <constant>ENODEV</constant> for all
204            these ioctls. Invalid object handles return
205            <constant>EINVAL</constant> and invalid object names return
206            <constant>ENOENT</constant>.</para>
207
208      <para>Gem provides explicit memory management primitives. System pages are
209            allocated when the object is created, either as the fundamental
210            storage for hardware where system memory is used by the graphics
211            processor directly, or as backing store for graphics-processor
212            resident memory.</para>
213
214      <para>Objects are referenced from user-space using handles. These are, for
215            all intents and purposes, equivalent to file descriptors but avoid
216            the overhead. Newer kernel drivers also support the
217            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
218            infrastructure which can return real file-descriptor for gem-handles
219            using the linux dma-buf API. Objects may be published with a name so
220            that other applications and processes can access them. The name
221            remains valid as long as the object exists. Gem-objects are
222            reference counted in the kernel. The object is only destroyed when
223            all handles from user-space were closed.</para>
224
225      <para>Gem-buffers cannot be created with a generic API. Each driver
226            provides its own API to create gem-buffers. See for example
227            <constant>DRM_I915_GEM_CREATE</constant>,
228            <constant>DRM_NOUVEAU_GEM_NEW</constant> or
229            <constant>DRM_RADEON_GEM_CREATE</constant>. Each of these ioctls
230            returns a gem-handle that can be passed to different generic ioctls.
231            The <emphasis>libgbm</emphasis> library from the
232            <emphasis>mesa3D</emphasis> distribution tries to provide a
233            driver-independent API to create gbm buffers and retrieve a
234            gbm-handle to them. It allows to create buffers for different
235            use-cases including scanout, rendering, cursors and CPU-access. See
236            the libgbm library for more information or look at the
237            driver-dependent man-pages (for example
238            <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>
239            or
240            <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
241
242      <para>Gem-buffers can be closed with the
243            <constant>DRM_IOCTL_GEM_CLOSE</constant> ioctl. It takes as argument
244            a structure of type <structname>struct drm_gem_close</structname>:
245
246<programlisting>
247struct drm_gem_close {
248	__u32 handle;
249	__u32 pad;
250};
251</programlisting>
252
253            The <structfield>handle</structfield> field is the gem-handle to be
254            closed. The <structfield>pad</structfield> field is unused padding.
255            It must be zeroed. After this call the gem handle cannot be used by
256            this process anymore and may be reused for new gem objects by the
257            gem API.</para>
258
259      <para>If you want to share gem-objects between different processes, you
260            can create a name for them and pass this name to other processes
261            which can then open this gem-object. Names are currently 32bit
262            integer IDs and have no special protection. That is, if you put a
263            name on your gem-object, every other client that has access to the
264            DRM device and is authenticated via
265            <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
266            to the current DRM-Master, can <emphasis>guess</emphasis> the name
267            and open or access the gem-object. If you want more fine-grained
268            access control, you can use the new
269            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
270            API to retrieve file-descriptors for gem-handles. To create a name
271            for a gem-handle, you use the
272            <constant>DRM_IOCTL_GEM_FLINK</constant> ioctl. It takes as argument
273            a structure of type <structname>struct drm_gem_flink</structname>:
274
275<programlisting>
276struct drm_gem_flink {
277	__u32 handle;
278	__u32 name;
279};
280</programlisting>
281
282            You have to put your handle into the
283            <structfield>handle</structfield> field. After completion, the
284            kernel has put the new unique name into the
285            <structfield>name</structfield> field. You can now pass this name to
286            other processes which can then import the name with the
287            <constant>DRM_IOCTL_GEM_OPEN</constant> ioctl. It takes as argument
288            a structure of type <structname>struct drm_gem_open</structname>:
289
290<programlisting>
291struct drm_gem_open {
292	__u32 name;
293
294	__u32 handle;
295	__u32 size;
296};
297</programlisting>
298
299            You have to fill in the <structfield>name</structfield> field with
300            the name of the gem-object that you want to open. The kernel will
301            fill in the <structfield>handle</structfield> and
302            <structfield>size</structfield> fields with the new handle and size
303            of the gem-object. You can now access the gem-object via the handle
304            as if you created it with the gem API.</para>
305
306      <para>Besides generic buffer management, the GEM API does not provide any
307            generic access. Each driver implements its own functionality on top
308            of this API. This includes execution-buffers, GTT management,
309            context creation, CPU access, GPU I/O and more. The next
310            higher-level API is <emphasis>OpenGL</emphasis>. So if you want to
311            use more GPU features, you should use the
312            <emphasis>mesa3D</emphasis> library to create OpenGL contexts on DRM
313            devices. This does <emphasis>not</emphasis> require any
314            windowing-system like X11, but can also be done on raw DRM devices.
315            However, this is beyond the scope of this man-page. You may have a
316            look at other mesa3D manpages, including libgbm and libEGL. 2D
317            software-rendering (rendering with the CPU) can be achieved with the
318            dumb-buffer-API in a driver-independent fashion, however, for
319            hardware-accelerated 2D or 3D rendering you must use OpenGL. Any
320            other API that tries to abstract the driver-internals to access
321            GEM-execution-buffers and other GPU internals, would simply reinvent
322            OpenGL so it is not provided. But if you need more detailed
323            information for a specific driver, you may have a look into the
324            driver-manpages, including
325            <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
326            <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
327            and
328            <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
329            However, the
330            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
331            infrastructure and the generic gem API as described here allow
332            display-managers to handle graphics-buffers and render-clients
333            without any deeper knowledge of the GPU that is used. Moreover, it
334            allows to move objects between GPUs and implement complex
335            display-servers that don't do any rendering on their own. See its
336            man-page for more information.</para>
337    </refsect2>
338  </refsect1>
339
340  <refsect1>
341    <title>Examples</title>
342      <para>This section includes examples for basic memory-management
343            tasks.</para>
344
345    <refsect2>
346      <title>Dumb-Buffers</title>
347        <para>This examples shows how to create a dumb-buffer via the generic
348              DRM API. This is driver-independent (as long as the driver
349              supports dumb-buffers) and provides memory-mapped buffers that can
350              be used for scanout. This example creates a full-HD 1920x1080
351              buffer with 32 bits-per-pixel and a color-depth of 24 bits. The
352              buffer is then bound to a framebuffer which can be used for
353              scanout with the KMS API (see
354              <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
355
356<programlisting>
357struct drm_mode_create_dumb creq;
358struct drm_mode_destroy_dumb dreq;
359struct drm_mode_map_dumb mreq;
360uint32_t fb;
361int ret;
362void *map;
363
364/* create dumb buffer */
365memset(&amp;creq, 0, sizeof(creq));
366creq.width = 1920;
367creq.height = 1080;
368creq.bpp = 32;
369ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &amp;creq);
370if (ret &lt; 0) {
371	/* buffer creation failed; see "errno" for more error codes */
372	...
373}
374/* creq.pitch, creq.handle and creq.size are filled by this ioctl with
375 * the requested values and can be used now. */
376
377/* create framebuffer object for the dumb-buffer */
378ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &amp;fb);
379if (ret) {
380	/* frame buffer creation failed; see "errno" */
381	...
382}
383/* the framebuffer "fb" can now used for scanout with KMS */
384
385/* prepare buffer for memory mapping */
386memset(&amp;mreq, 0, sizeof(mreq));
387mreq.handle = creq.handle;
388ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &amp;mreq);
389if (ret) {
390	/* DRM buffer preparation failed; see "errno" */
391	...
392}
393/* mreq.offset now contains the new offset that can be used with mmap() */
394
395/* perform actual memory mapping */
396map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
397if (map == MAP_FAILED) {
398	/* memory-mapping failed; see "errno" */
399	...
400}
401
402/* clear the framebuffer to 0 */
403memset(map, 0, creq.size);
404</programlisting>
405
406    </refsect2>
407
408  </refsect1>
409
410  <refsect1>
411    <title>Reporting Bugs</title>
412    <para>Bugs in this manual should be reported to
413          http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
414          "libdrm" as the component.</para>
415  </refsect1>
416
417  <refsect1>
418    <title>See Also</title>
419    <para>
420      <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
421      <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
422      <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
423      <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
424      <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
425      <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
426      <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
427      <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>
428    </para>
429  </refsect1>
430</refentry>
431