dwww Home | Manual pages | Find package

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

NAME
       drm-memory - DRM Memory Management

SYNOPSIS
       #include <xf86drm.h>

DESCRIPTION
       Many  modern  high-end  GPUs  come with their own memory managers. They
       even include several different caches that need to be synchronized dur-
       ing  access.   Textures, framebuffers, command buffers and more need to
       be stored in memory that can be accessed quickly by the GPU. Therefore,
       memory management on GPUs is highly driver- and hardware-dependent.

       However,  there  are  several frameworks in the kernel that are used by
       more than one driver. These can be used for trivial mode-setting  with-
       out  requiring driver-dependent code. But for hardware-accelerated ren-
       dering you need to read the manual pages for the  driver  you  want  to
       work with.

   Dumb-Buffers
       Almost  all  in-kernel  DRM  hardware  drivers  support  an  API called
       Dumb-Buffers.  This API allows to create buffers of arbitrary size that
       can be used for scanout. These buffers can be memory mapped via mmap(2)
       so you can render into them on the CPU. However, GPU  access  to  these
       buffers  is  often  not  possible.  Therefore, they are fine for simple
       tasks but not suitable for complex compositions and renderings.

       The DRM_IOCTL_MODE_CREATE_DUMB ioctl can be used to create a dumb  buf-
       fer.  The kernel will return a 32-bit handle that can be used to manage
       the buffer with the DRM API. You can create framebuffers  with  drmMod-
       eAddFB(3)  and  use it for mode-setting and scanout. To access the buf-
       fer, you  first  need  to  retrieve  the  offset  of  the  buffer.  The
       DRM_IOCTL_MODE_MAP_DUMB ioctl requests the DRM subsystem to prepare the
       buffer for memory-mapping and returns a fake-offset that  can  be  used
       with mmap(2).

       The  DRM_IOCTL_MODE_CREATE_DUMB  ioctl takes as argument a structure of
       type struct drm_mode_create_dumb:

          struct drm_mode_create_dumb {
              __u32 height;
              __u32 width;
              __u32 bpp;
              __u32 flags;

              __u32 handle;
              __u32 pitch;
              __u64 size;
          };

       The fields height, width, bpp and flags have  to  be  provided  by  the
       caller.  The other fields are filled by the kernel with the return val-
       ues.  height and width are the dimensions  of  the  rectangular  buffer
       that is created. bpp is the number of bits-per-pixel and must be a mul-
       tiple of 8. You most commonly want to pass 32 here. The flags field  is
       currently  unused and must be zeroed. Different flags to modify the be-
       havior may be added in the future. After calling the ioctl, the handle,
       pitch  and size fields are filled by the kernel. handle is a 32-bit gem
       handle that identifies the buffer. This is used by several other  calls
       that take a gem-handle or memory-buffer as argument. The pitch field is
       the pitch (or stride) of the new buffer. Most  drivers  use  32-bit  or
       64-bit aligned stride-values. The size field contains the absolute size
       in bytes of the buffer. This can normally also be computed with (height
       * pitch + width) * bpp / 4.

       To   prepare   the   buffer   for   mmap(2)   you   need   to  use  the
       DRM_IOCTL_MODE_MAP_DUMB ioctl. It takes as argument a structure of type
       struct drm_mode_map_dumb:

          struct drm_mode_map_dumb {
              __u32 handle;
              __u32 pad;

              __u64 offset;
          };

       You  need  to  put  the  gem-handle  that  was previously retrieved via
       DRM_IOCTL_MODE_CREATE_DUMB into the handle field. The pad field is  un-
       used  padding  and  must  be zeroed. After completion, the offset field
       will contain an offset that  can  be  used  with  mmap(2)  on  the  DRM
       file-descriptor.

       If  you  don't  need  your dumb-buffer, anymore, you have to destroy it
       with DRM_IOCTL_MODE_DESTROY_DUMB. If you close the DRM file-descriptor,
       all  open dumb-buffers are automatically destroyed. This ioctl takes as
       argument a structure of type struct drm_mode_destroy_dumb:

          struct drm_mode_destroy_dumb {
              __u32 handle;
          };

       You only need to put your handle into  the  handle  field.  After  this
       call,  the  handle  is invalid and may be reused for new buffers by the
       dumb-API.

   TTM
       TTM stands for Translation Table Manager and is a  generic  memory-man-
       ager  provided  by  the kernel. It does not provide a common user-space
       API so you need to look at each driver interface if you want to use it.
       See  for  instance  the  radeon  man pages for more information on mem-
       ory-management with radeon and TTM.

   GEM
       GEM stands for Graphics Execution Manager and is  a  generic  DRM  mem-
       ory-management  framework in the kernel, that is used by many different
       drivers. GEM is designed to manage graphics memory, control  access  to
       the graphics device execution context and handle essentially NUMA envi-
       ronment unique to modern graphics hardware. GEM allows multiple  appli-
       cations  to  share  graphics  device resources without the need to con-
       stantly reload the entire graphics card. Data  may  be  shared  between
       multiple  applications  with  gem ensuring that the correct memory syn-
       chronization occurs.

       GEM provides simple mechanisms to manage graphics data and control exe-
       cution  flow within the linux DRM subsystem. However, GEM is not a com-
       plete framework that is fully driver independent. Instead, if  provides
       many  functions  that  are shared between many drivers, but each driver
       has  to  implement  most  of  memory-management  with  driver-dependent
       ioctls.  This  manpage  tries  to describe the semantics (and if it ap-
       plies, the syntax) that is shared between all drivers that use GEM.

       All GEM APIs are defined as ioctl(2) on the DRM file descriptor. An ap-
       plication  must  be  authorized  via  drmAuthMagic(3)  to  the  current
       DRM-Master to access the GEM subsystem. A driver that does not  support
       GEM will return ENODEV for all these ioctls. Invalid object handles re-
       turn EINVAL and invalid object names return ENOENT.

       Gem provides explicit memory management primitives.  System  pages  are
       allocated when the object is created, either as the fundamental storage
       for hardware where system memory is used by the graphics processor  di-
       rectly, or as backing store for graphics-processor resident memory.

       Objects  are  referenced  from user-space using handles. These are, for
       all intents and purposes, equivalent to file descriptors but avoid  the
       overhead.   Newer  kernel drivers also support the drm-prime (7) infra-
       structure which can return real file-descriptor for  GEM-handles  using
       the  linux  DMA-BUF  API.  Objects may be published with a name so that
       other applications and processes can  access  them.  The  name  remains
       valid  as long as the object exists.  GEM-objects are reference counted
       in the kernel. The object is  only  destroyed  when  all  handles  from
       user-space were closed.

       GEM-buffers  cannot be created with a generic API. Each driver provides
       its own API to create GEM-buffers. See for example DRM_I915_GEM_CREATE,
       DRM_NOUVEAU_GEM_NEW  or DRM_RADEON_GEM_CREATE. Each of these ioctls re-
       turns a GEM-handle that can be passed to different generic ioctls.  The
       libgbm  library  from  the  mesa3D  distribution  tries  to  provide  a
       driver-independent API to create GBM buffers and retrieve a  GBM-handle
       to them.  It allows to create buffers for different use-cases including
       scanout, rendering, cursors and CPU-access. See the libgbm library  for
       more information or look at the driver-dependent man-pages (for example
       drm-intel(7) or drm-radeon(7)).

       GEM-buffers can be closed with drmCloseBufferHandle(3). It takes as ar-
       gument the GEM-handle to be closed. After this call the GEM handle can-
       not be used by this process anymore and may be reused for new  GEM  ob-
       jects by the GEM API.

       If  you  want to share GEM-objects between different processes, you can
       create a name for them and pass this name to other processes which  can
       then  open  this GEM-object. Names are currently 32-bit integer IDs and
       have no special protection. That is, if you put a name on your  GEM-ob-
       ject,  every  other client that has access to the DRM device and is au-
       thenticated via drmAuthMagic(3) to the current  DRM-Master,  can  guess
       the  name  and  open  or  access  the  GEM-object.  If  you  want  more
       fine-grained access control, you can use the new  drm-prime(7)  API  to
       retrieve  file-descriptors  for  GEM-handles.  To  create  a name for a
       GEM-handle, you use the DRM_IOCTL_GEM_FLINK ioctl. It takes as argument
       a structure of type struct drm_gem_flink:

          struct drm_gem_flink {
              __u32 handle;
              __u32 name;
          };

       You  have  to  put your handle into the handle field. After completion,
       the kernel has put the new unique name into the name field. You can now
       pass  this  name to other processes which can then import the name with
       the DRM_IOCTL_GEM_OPEN ioctl. It takes as argument a structure of  type
       struct drm_gem_open:

          struct drm_gem_open {
              __u32 name;

              __u32 handle;
              __u32 size;
          };

       You have to fill in the name field with the name of the GEM-object that
       you want to open. The kernel will fill in the handle  and  size  fields
       with  the new handle and size of the GEM-object. You can now access the
       GEM-object via the handle as if you created it with the GEM API.

       Besides generic buffer management, the GEM API  does  not  provide  any
       generic  access. Each driver implements its own functionality on top of
       this API. This includes execution-buffers, GTT management, context cre-
       ation,  CPU  access,  GPU  I/O  and  more. The next higher-level API is
       OpenGL. So if you want to use more GPU features,  you  should  use  the
       mesa3D  library to create OpenGL contexts on DRM devices. This does not
       require any windowing-system like X11, but can also be done on raw  DRM
       devices.  However,  this  is beyond the scope of this man-page. You may
       have a look at other mesa3D man pages, including libgbm and libEGL.  2D
       software-rendering  (rendering  with  the CPU) can be achieved with the
       dumb-buffer-API in a driver-independent  fashion,  however,  for  hard-
       ware-accelerated  2D or 3D rendering you must use OpenGL. Any other API
       that tries  to  abstract  the  driver-internals  to  access  GEM-execu-
       tion-buffers  and  other GPU internals, would simply reinvent OpenGL so
       it is not provided. But if you need more  detailed  information  for  a
       specific  driver, you may have a look into the driver-manpages, includ-
       ing  drm-intel(7),  drm-radeon(7)  and  drm-nouveau(7).  However,   the
       drm-prime(7)  infrastructure  and the generic GEM API as described here
       allow display-managers to handle  graphics-buffers  and  render-clients
       without  any deeper knowledge of the GPU that is used. Moreover, it al-
       lows to move objects between GPUs and implement complex display-servers
       that don't do any rendering on their own. See its man-page for more in-
       formation.

EXAMPLES
       This section includes examples for basic memory-management tasks.

   Dumb-Buffers
       This examples shows how to create a dumb-buffer  via  the  generic  DRM
       API.   This  is  driver-independent  (as  long  as  the driver supports
       dumb-buffers) and provides memory-mapped buffers that can be  used  for
       scanout.  This  example  creates  a  full-HD  1920x1080  buffer with 32
       bits-per-pixel and a color-depth of 24 bits. The buffer is  then  bound
       to  a  framebuffer  which can be used for scanout with the KMS API (see
       drm-kms(7)).

          struct drm_mode_create_dumb creq;
          struct drm_mode_destroy_dumb dreq;
          struct drm_mode_map_dumb mreq;
          uint32_t fb;
          int ret;
          void *map;

          /* create dumb buffer */
          memset(&creq, 0, sizeof(creq));
          creq.width = 1920;
          creq.height = 1080;
          creq.bpp = 32;
          ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
          if (ret < 0) {
              /* buffer creation failed; see "errno" for more error codes */
              ...
          }
          /* creq.pitch, creq.handle and creq.size are filled by this ioctl with
           * the requested values and can be used now. */

          /* create framebuffer object for the dumb-buffer */
          ret = drmModeAddFB(fd, 1920, 1080, 24, 32, creq.pitch, creq.handle, &fb);
          if (ret) {
              /* frame buffer creation failed; see "errno" */
              ...
          }
          /* the framebuffer "fb" can now used for scanout with KMS */

          /* prepare buffer for memory mapping */
          memset(&mreq, 0, sizeof(mreq));
          mreq.handle = creq.handle;
          ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
          if (ret) {
              /* DRM buffer preparation failed; see "errno" */
              ...
          }
          /* mreq.offset now contains the new offset that can be used with mmap() */

          /* perform actual memory mapping */
          map = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
          if (map == MAP_FAILED) {
              /* memory-mapping failed; see "errno" */
              ...
          }

          /* clear the framebuffer to 0 */
          memset(map, 0, creq.size);

REPORTING BUGS
       Bugs     in     this     manual     should     be      reported      to
       https://gitlab.freedesktop.org/mesa/drm/-/issues

SEE ALSO
       drm(7),  drm-kms(7), drm-prime(7), drmAvailable(3), drmOpen(3), drm-in-
       tel(7), drm-radeon(7), drm-nouveau(7)

                                September 2012                   DRM-MEMORY(7)

Generated by dwww version 1.15 on Sat Jun 29 02:03:13 CEST 2024.