man: add drm-memory overview page
[glsdk/libdrm.git] / man / drm-memory.xml
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">
5 <!--
6   Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
7   Dedicated to the Public Domain
8 -->
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>
25   <refmeta>
26     <refentrytitle>drm-memory</refentrytitle>
27     <manvolnum>7</manvolnum>
28   </refmeta>
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>
38   <refsynopsisdiv>
39     <funcsynopsis>
40       <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
41     </funcsynopsis>
42   </refsynopsisdiv>
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>
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>
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>
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>
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>:
87 <programlisting>
88 struct drm_mode_create_dumb {
89         __u32 height;
90         __u32 width;
91         __u32 bpp;
92         __u32 flags;
94         __u32 handle;
95         __u32 pitch;
96         __u64 size;
97 };
98 </programlisting>
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>
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>:
130 <programlisting>
131 struct drm_mode_map_dumb {
132         __u32 handle;
133         __u32 pad;
135         __u64 offset;
136 };
137 </programlisting>
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>
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>:
154 <programlisting>
155 struct drm_mode_destroy_dumb {
156         __u32 handle;
157 };
158 </programlisting>
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>
164     </refsect2>
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>
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>
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>
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>
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>
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>
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>
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>:
246 <programlisting>
247 struct drm_gem_close {
248         __u32 handle;
249         __u32 pad;
250 };
251 </programlisting>
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>
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>:
275 <programlisting>
276 struct drm_gem_flink {
277         __u32 handle;
278         __u32 name;
279 };
280 </programlisting>
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>:
290 <programlisting>
291 struct drm_gem_open {
292         __u32 name;
294         __u32 handle;
295         __u32 size;
296 };
297 </programlisting>
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>
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>
340   <refsect1>
341     <title>Examples</title>
342       <para>This section includes examples for basic memory-management
343             tasks.</para>
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>
356 <programlisting>
357 struct drm_mode_create_dumb creq;
358 struct drm_mode_destroy_dumb dreq;
359 struct drm_mode_map_dumb mreq;
360 uint32_t fb;
361 int ret;
362 void *map;
364 /* create dumb buffer */
365 memset(&amp;creq, 0, sizeof(creq));
366 creq.width = 1920;
367 creq.height = 1080;
368 creq.bpp = 32;
369 ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &amp;creq);
370 if (ret &lt; 0) {
371         /* buffer creation failed; see "errno" for more error codes */
372         ...
374 /* creq.pitch, creq.handle and creq.size are filled by this ioctl with
375  * the requested values and can be used now. */
377 /* create framebuffer object for the dumb-buffer */
378 ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &amp;fb);
379 if (ret) {
380         /* frame buffer creation failed; see "errno" */
381         ...
383 /* the framebuffer "fb" can now used for scanout with KMS */
385 /* prepare buffer for memory mapping */
386 memset(&amp;mreq, 0, sizeof(mreq));
387 mreq.handle = creq.handle;
388 ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &amp;mreq);
389 if (ret) {
390         /* DRM buffer preparation failed; see "errno" */
391         ...
393 /* mreq.offset now contains the new offset that can be used with mmap() */
395 /* perform actual memory mapping */
396 map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
397 if (map == MAP_FAILED) {
398         /* memory-mapping failed; see "errno" */
399         ...
402 /* clear the framebuffer to 0 */
403 memset(map, 0, creq.size);
404 </programlisting>
406     </refsect2>
408   </refsect1>
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>
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>