1DRM-MEMORY(7)              Direct Rendering Manager              DRM-MEMORY(7)


6       drm-memory, drm-mm, drm-gem, drm-ttm - DRM Memory Management


9       #include <xf86drm.h>


12       Many modern high-end GPUs come with their own memory managers. They
13       even include several different caches that need to be synchronized
14       during access. Textures, framebuffers, command buffers and more need to
15       be stored in memory that can be accessed quickly by the GPU. Therefore,
16       memory management on GPUs is highly driver- and hardware-dependent.
18       However, there are several frameworks in the kernel that are used by
19       more than one driver. These can be used for trivial mode-setting
20       without requiring driver-dependent code. But for hardware-accelerated
21       rendering you need to read the manual pages for the driver you want to
22       work with.
24   Dumb-Buffers
25       Almost all in-kernel DRM hardware drivers support an API called
26       Dumb-Buffers. This API allows to create buffers of arbitrary size that
27       can be used for scanout. These buffers can be memory mapped via mmap(2)
28       so you can render into them on the CPU. However, GPU access to these
29       buffers is often not possible. Therefore, they are fine for simple
30       tasks but not suitable for complex compositions and renderings.
32       The DRM_IOCTL_MODE_CREATE_DUMB ioctl can be used to create a dumb
33       buffer. The kernel will return a 32bit handle that can be used to
34       manage the buffer with the DRM API. You can create framebuffers with
35       drmModeAddFB(3) and use it for mode-setting and scanout. To access the
36       buffer, you first need to retrieve the offset of the buffer. The
37       DRM_IOCTL_MODE_MAP_DUMB ioctl requests the DRM subsystem to prepare the
38       buffer for memory-mapping and returns a fake-offset that can be used
39       with mmap(2).
41       The DRM_IOCTL_MODE_CREATE_DUMB ioctl takes as argument a structure of
42       type struct drm_mode_create_dumb:
44           struct drm_mode_create_dumb {
45                __u32 height;
46                __u32 width;
47                __u32 bpp;
48                __u32 flags;
50                __u32 handle;
51                __u32 pitch;
52                __u64 size;
53           };
55       The fields height, width, bpp and flags have to be provided by the
56       caller. The other fields are filled by the kernel with the return
57       values.  height and width are the dimensions of the rectangular buffer
58       that is created.  bpp is the number of bits-per-pixel and must be a
59       multiple of 8. You most commonly want to pass 32 here. The flags field
60       is currently unused and must be zeroed. Different flags to modify the
61       behavior may be added in the future. After calling the ioctl, the
62       handle, pitch and size fields are filled by the kernel.  handle is a
63       32bit gem handle that identifies the buffer. This is used by several
64       other calls that take a gem-handle or memory-buffer as argument. The
65       pitch field is the pitch (or stride) of the new buffer. Most drivers
66       use 32bit or 64bit aligned stride-values. The size field contains the
67       absolute size in bytes of the buffer. This can normally also be
68       computed with (height * pitch + width) * bpp / 4.
70       To prepare the buffer for mmap(2) you need to use the
71       DRM_IOCTL_MODE_MAP_DUMB ioctl. It takes as argument a structure of type
72       struct drm_mode_map_dumb:
74           struct drm_mode_map_dumb {
75                __u32 handle;
76                __u32 pad;
78                __u64 offset;
79           };
81       You need to put the gem-handle that was previously retrieved via
82       DRM_IOCTL_MODE_CREATE_DUMB into the handle field. The pad field is
83       unused padding and must be zeroed. After completion, the offset field
84       will contain an offset that can be used with mmap(2) on the DRM
85       file-descriptor.
87       If you don't need your dumb-buffer, anymore, you have to destroy it
88       with DRM_IOCTL_MODE_DESTROY_DUMB. If you close the DRM file-descriptor,
89       all open dumb-buffers are automatically destroyed. This ioctl takes as
90       argument a structure of type struct drm_mode_destroy_dumb:
92           struct drm_mode_destroy_dumb {
93                __u32 handle;
94           };
96       You only need to put your handle into the handle field. After this
97       call, the handle is invalid and may be reused for new buffers by the
98       dumb-API.
100   TTM
101       TTM stands for Translation Table Manager and is a generic
102       memory-manager provided by the kernel. It does not provide a common
103       user-space API so you need to look at each driver interface if you want
104       to use it. See for instance the radeon manpages for more information on
105       memory-management with radeon and TTM.
107   GEM
108       GEM stands for Graphics Execution Manager and is a generic DRM
109       memory-management framework in the kernel, that is used by many
110       different drivers. Gem is designed to manage graphics memory, control
111       access to the graphics device execution context and handle essentially
112       NUMA environment unique to modern graphics hardware. Gem allows
113       multiple applications to share graphics device resources without the
114       need to constantly reload the entire graphics card. Data may be shared
115       between multiple applications with gem ensuring that the correct memory
116       synchronization occurs.
118       Gem provides simple mechanisms to manage graphics data and control
119       execution flow within the linux DRM subsystem. However, gem is not a
120       complete framework that is fully driver independent. Instead, if
121       provides many functions that are shared between many drivers, but each
122       driver has to implement most of memory-management with driver-dependent
123       ioctls. This manpage tries to describe the semantics (and if it
124       applies, the syntax) that is shared between all drivers that use gem.
126       All GEM APIs are defined as ioctl(2) on the DRM file descriptor. An
127       application must be authorized via drmAuthMagic(3) to the current
128       DRM-Master to access the GEM subsystem. A driver that does not support
129       gem will return ENODEV for all these ioctls. Invalid object handles
130       return EINVAL and invalid object names return ENOENT.
132       Gem provides explicit memory management primitives. System pages are
133       allocated when the object is created, either as the fundamental storage
134       for hardware where system memory is used by the graphics processor
135       directly, or as backing store for graphics-processor resident memory.
137       Objects are referenced from user-space using handles. These are, for
138       all intents and purposes, equivalent to file descriptors but avoid the
139       overhead. Newer kernel drivers also support the drm-prime(7)
140       infrastructure which can return real file-descriptor for gem-handles
141       using the linux dma-buf API. Objects may be published with a name so
142       that other applications and processes can access them. The name remains
143       valid as long as the object exists. Gem-objects are reference counted
144       in the kernel. The object is only destroyed when all handles from
145       user-space were closed.
147       Gem-buffers cannot be created with a generic API. Each driver provides
148       its own API to create gem-buffers. See for example DRM_I915_GEM_CREATE,
149       DRM_NOUVEAU_GEM_NEW or DRM_RADEON_GEM_CREATE. Each of these ioctls
150       returns a gem-handle that can be passed to different generic ioctls.
151       The libgbm library from the mesa3D distribution tries to provide a
152       driver-independent API to create gbm buffers and retrieve a gbm-handle
153       to them. It allows to create buffers for different use-cases including
154       scanout, rendering, cursors and CPU-access. See the libgbm library for
155       more information or look at the driver-dependent man-pages (for example
156       drm-intel(7) or drm-radeon(7)).
158       Gem-buffers can be closed with the DRM_IOCTL_GEM_CLOSE ioctl. It takes
159       as argument a structure of type struct drm_gem_close:
161           struct drm_gem_close {
162                __u32 handle;
163                __u32 pad;
164           };
166       The handle field is the gem-handle to be closed. The pad field is
167       unused padding. It must be zeroed. After this call the gem handle
168       cannot be used by this process anymore and may be reused for new gem
169       objects by the gem API.
171       If you want to share gem-objects between different processes, you can
172       create a name for them and pass this name to other processes which can
173       then open this gem-object. Names are currently 32bit integer IDs and
174       have no special protection. That is, if you put a name on your
175       gem-object, every other client that has access to the DRM device and is
176       authenticated via drmAuthMagic(3) to the current DRM-Master, can guess
177       the name and open or access the gem-object. If you want more
178       fine-grained access control, you can use the new drm-prime(7) API to
179       retrieve file-descriptors for gem-handles. To create a name for a
180       gem-handle, you use the DRM_IOCTL_GEM_FLINK ioctl. It takes as argument
181       a structure of type struct drm_gem_flink:
183           struct drm_gem_flink {
184                __u32 handle;
185                __u32 name;
186           };
188       You have to put your handle into the handle field. After completion,
189       the kernel has put the new unique name into the name field. You can now
190       pass this name to other processes which can then import the name with
191       the DRM_IOCTL_GEM_OPEN ioctl. It takes as argument a structure of type
192       struct drm_gem_open:
194           struct drm_gem_open {
195                __u32 name;
197                __u32 handle;
198                __u32 size;
199           };
201       You have to fill in the name field with the name of the gem-object that
202       you want to open. The kernel will fill in the handle and size fields
203       with the new handle and size of the gem-object. You can now access the
204       gem-object via the handle as if you created it with the gem API.
206       Besides generic buffer management, the GEM API does not provide any
207       generic access. Each driver implements its own functionality on top of
208       this API. This includes execution-buffers, GTT management, context
209       creation, CPU access, GPU I/O and more. The next higher-level API is
210       OpenGL. So if you want to use more GPU features, you should use the
211       mesa3D library to create OpenGL contexts on DRM devices. This does not
212       require any windowing-system like X11, but can also be done on raw DRM
213       devices. However, this is beyond the scope of this man-page. You may
214       have a look at other mesa3D manpages, including libgbm and libEGL. 2D
215       software-rendering (rendering with the CPU) can be achieved with the
216       dumb-buffer-API in a driver-independent fashion, however, for
217       hardware-accelerated 2D or 3D rendering you must use OpenGL. Any other
218       API that tries to abstract the driver-internals to access
219       GEM-execution-buffers and other GPU internals, would simply reinvent
220       OpenGL so it is not provided. But if you need more detailed information
221       for a specific driver, you may have a look into the driver-manpages,
222       including drm-intel(7), drm-radeon(7) and drm-nouveau(7). However, the
223       drm-prime(7) infrastructure and the generic gem API as described here
224       allow display-managers to handle graphics-buffers and render-clients
225       without any deeper knowledge of the GPU that is used. Moreover, it
226       allows to move objects between GPUs and implement complex
227       display-servers that don't do any rendering on their own. See its
228       man-page for more information.


231       This section includes examples for basic memory-management tasks.
233   Dumb-Buffers
234       This examples shows how to create a dumb-buffer via the generic DRM
235       API. This is driver-independent (as long as the driver supports
236       dumb-buffers) and provides memory-mapped buffers that can be used for
237       scanout. This example creates a full-HD 1920x1080 buffer with 32
238       bits-per-pixel and a color-depth of 24 bits. The buffer is then bound
239       to a framebuffer which can be used for scanout with the KMS API (see
240       drm-kms(7)).
242           struct drm_mode_create_dumb creq;
243           struct drm_mode_destroy_dumb dreq;
244           struct drm_mode_map_dumb mreq;
245           uint32_t fb;
246           int ret;
247           void *map;
249           /* create dumb buffer */
250           memset(&creq, 0, sizeof(creq));
251           creq.width = 1920;
252           creq.height = 1080;
253           creq.bpp = 32;
254           ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
255           if (ret < 0) {
256                /* buffer creation failed; see "errno" for more error codes */
257                ...
258           }
259           /* creq.pitch, creq.handle and creq.size are filled by this ioctl with
260            * the requested values and can be used now. */
262           /* create framebuffer object for the dumb-buffer */
263           ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &fb);
264           if (ret) {
265                /* frame buffer creation failed; see "errno" */
266                ...
267           }
268           /* the framebuffer "fb" can now used for scanout with KMS */
270           /* prepare buffer for memory mapping */
271           memset(&mreq, 0, sizeof(mreq));
272           mreq.handle = creq.handle;
273           ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
274           if (ret) {
275                /* DRM buffer preparation failed; see "errno" */
276                ...
277           }
278           /* mreq.offset now contains the new offset that can be used with mmap() */
280           /* perform actual memory mapping */
281           map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
282           if (map == MAP_FAILED) {
283                /* memory-mapping failed; see "errno" */
284                ...
285           }
287           /* clear the framebuffer to 0 */
288           memset(map, 0, creq.size);


291       Bugs in this manual should be reported to
292       https://bugs.freedesktop.org/enter_bug.cgi?product=DRI&component=libdrm
293       under the "DRI" product, component "libdrm"


296       drm(7), drm-kms(7), drm-prime(7), drmAvailable(3), drmOpen(3), drm-
297       intel(7), drm-radeon(7), drm-nouveau(7)
301libdrm                          September 2012                   DRM-MEMORY(7)