Home | History | Annotate | Download | only in man
      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-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 (a] 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>
     88 struct 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>
    131 struct 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>
    155 struct 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>
    247 struct 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>
    276 struct 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>
    291 struct 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>
    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;
    363 
    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 	...
    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 */
    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 	...
    382 }
    383 /* the framebuffer "fb" can now used for scanout with KMS */
    384 
    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 	...
    392 }
    393 /* mreq.offset now contains the new offset that can be used with mmap() */
    394 
    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 	...
    400 }
    401 
    402 /* clear the framebuffer to 0 */
    403 memset(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