From patchwork Sun Sep 23 14:40:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 1495611 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 29952E006E for ; Sun, 23 Sep 2012 14:41:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E16B9F32A for ; Sun, 23 Sep 2012 07:41:50 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wg0-f43.google.com (mail-wg0-f43.google.com [74.125.82.43]) by gabe.freedesktop.org (Postfix) with ESMTP id 25ADD9EAF1 for ; Sun, 23 Sep 2012 07:38:08 -0700 (PDT) Received: by wgbdq11 with SMTP id dq11so3652672wgb.12 for ; Sun, 23 Sep 2012 07:38:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=9EFJgPvRrZIM2JECzKcDO/im3QAGqxvpRTRhWuR654w=; b=BsgiMmO4tJ9pohIy0Jo1aNsYCAwywywhWF+V3ttNFNvMILXWsAbtwU4SVPN3MpRjbz L7kp7GfP0MqzgUk7ygMCjo2iukWmjlbIqdwfIThJOlD2A9xBTk+cX8Xv0TYpcfXWbB77 8F06llwwL8FtS5sqiv2+i5l0anmiAN7vUSaruK5uvZP6zo5Vr46eAa/4HSy/5BCDJLDu COPAUqj4U1mmpiKzzS8/G7AMHowrj9xHKXdFoR85T6RdUP9WYDr54utQkERIOKVxbaka udvzxEtbUJS/rgpP3Jb/UEM7M0+fjY9kntNlaGhBtC8sXAbm7bl2utLJ+KnL9DUs8pgo VM/A== Received: by 10.180.100.37 with SMTP id ev5mr8669669wib.5.1348411088158; Sun, 23 Sep 2012 07:38:08 -0700 (PDT) Received: from localhost.localdomain (stgt-5f71ab6d.pool.mediaWays.net. [95.113.171.109]) by mx.google.com with ESMTPS id dm3sm10865329wib.3.2012.09.23.07.38.06 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 23 Sep 2012 07:38:07 -0700 (PDT) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [PATCH libdrm 4/4] man: add drm-memory man-page Date: Sun, 23 Sep 2012 16:40:07 +0200 Message-Id: <1348411208-3943-5-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.12.1 In-Reply-To: <1348411208-3943-1-git-send-email-dh.herrmann@googlemail.com> References: <1348411208-3943-1-git-send-email-dh.herrmann@googlemail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org The drm-memory man-page (aliased as drm-gem, drm-mm and drm-ttm) describes the high-level overview of different memory-management frameworks used in the DRM subsystem. It is really targeted at driver-independent semantics (and where it applies, syntax). It links to all other man-pages if more driver-dependent information is needed. Signed-off-by: David Herrmann Reviewed-by: Jesse Barnes --- man/Makefile.am | 4 + man/drm-gem.7 | 1 + man/drm-memory.7 | 412 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ man/drm-mm.7 | 1 + man/drm-ttm.7 | 1 + 5 files changed, 419 insertions(+) create mode 100644 man/drm-gem.7 create mode 100644 man/drm-memory.7 create mode 100644 man/drm-mm.7 create mode 100644 man/drm-ttm.7 diff --git a/man/Makefile.am b/man/Makefile.am index 7ce7ac4..ded3b4a 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,10 @@ man_MANS = \ drm.7 \ drm-kms.7 \ + drm-memory.7 \ + drm-mm.7 \ + drm-gem.7 \ + drm-ttm.7 \ drmAvailable.3 \ drmHandleEvent.3 \ drmModeGetResources.3 diff --git a/man/drm-gem.7 b/man/drm-gem.7 new file mode 100644 index 0000000..258b5a3 --- /dev/null +++ b/man/drm-gem.7 @@ -0,0 +1 @@ +.so man7/drm-memory.7 diff --git a/man/drm-memory.7 b/man/drm-memory.7 new file mode 100644 index 0000000..1eff38a --- /dev/null +++ b/man/drm-memory.7 @@ -0,0 +1,412 @@ +.\" +.\" Written 2012 by David Herrmann +.\" Dedicated to the Public Domain +.\" +.TH "DRM-MEMORY" 7 "September 2012" "libdrm" "Direct Rendering Manager" +.SH NAME +DRM-Memory \- DRM Memory Management + +.SH SYNOPSIS +.B #include + +.SH DESCRIPTION +Many modern high-end GPUs come with their own memory managers. They even include +several different caches that need to be synchronized during 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 without requiring +driver-dependent code. But for hardware-accelerated rendering you need to read +the manual pages for the driver you want to work with. + +.SS Dumb-Buffers +Almost all in-kernel DRM hardware drivers support an API called +.BR "Dumb-Buffers" "." +This API allows to create buffers of arbitrary size that can be used for +scanout. These buffers can be memory mapped via +.BR 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 +.B DRM_IOCTL_MODE_CREATE_DUMB +ioctl can be used to create a dumb buffer. The kernel will return a 32bit handle +that can be used to manage the buffer with the DRM API. You can create +framebuffers with +.BR drmModeAddFB (3) +and use it for mode-setting and scanout. +.br +To access the buffer, you first need to retrieve the offset of the buffer. The +.B 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 +.BR mmap "(2)." + +The +.B DRM_IOCTL_MODE_CREATE_DUMB +ioctl takes as argument a structure of type +.IR "struct drm_mode_create_dumb" : + +.in +4n +.nf +struct drm_mode_create_dumb { + __u32 height; + __u32 width; + __u32 bpp; + __u32 flags; + + __u32 handle; + __u32 pitch; + __u64 size; +}; +.fi +.in + +The fields +.IR "height" ", " "width" ", " "bpp" " and " "flags" +have to be provided by the caller. The other fields are filled by the kernel +with the return values. +.IR "height" " and " "width" +are the dimensions of the rectangular buffer that is created. +.I "bpp" +is the number of bits-per-pixel and must be a multiple of +.IR 8 "." +You most commonly want to pass +.I 32 +here. The +.I "flags" +field is currently unused and must be zeroed. Different flags to modify the +behavior may be added in the future. +.br +After calling the ioctl, the +.IR "handle" ", " "pitch" " and " "size" +fields are filled by the kernel. +.I "handle" +is a 32bit gem handle that identifies the buffer. This is used by several other +calls that take a gem-handle or memory-buffer as argument. The +.I "pitch" +field is the +.IR pitch " or " stride +of the new buffer. Most drivers use 32bit or 64bit aligned stride-values. The +.I "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 +.BR mmap (2) +you need to use the +.B DRM_IOCTL_MODE_MAP_DUMB +ioctl. It takes as argument a structure of type +.IR "struct drm_mode_map_dumb" : + +.in +4n +.nf +struct drm_mode_map_dumb { + __u32 handle; + __u32 pad; + + __u64 offset; +}; +.fi +.in + +You need to put the gem-handle that was previously retrieved via +.B DRM_IOCTL_MODE_CREATE_DUMB +into the +.I "handle" +field. The +.I "pad" +field is unused padding and must be zeroed. After completion, the +.I offset +field will contain an offset that can be used with +.BR mmap (2) +on the DRM file-descriptor. + +If you don't need your dumb-buffer, anymore, you have to destroy it with +.BR DRM_IOCTL_MODE_DESTROY_DUMB "." +If you close the DRM file-descriptor, all open dumb-buffers are automatically +destroyed. +.br +This ioctl takes as argument a structure of type +.IR "struct drm_mode_destroy_dumb" : + +.in +4n +.nf +struct drm_mode_destroy_dumb { + __u32 handle; +}; +.fi +.in + +You only need to put your handle into the +.I handle +field. After this call, the handle is invalid and may be reused for new buffers +by the dumb-API. + +.SS TTM +.B TTM +stands for +.B Translation Table Manager +and is another generic memory-manager provided by the kernel. Only the radeon +driver uses it. See the radeon manpages for more information on +memory-management with radeon and TTM. + +.SS GEM +.B GEM +stands for +.B Graphics Execution Manager +and is a generic DRM memory-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 +environment unique to modern graphics hardware. Gem allows multiple applications +to share graphics device resources without the need to constantly reload the +entire graphics card. Data may be shared between multiple applications with gem +ensuring that the correct memory synchronization occurs. + +Gem provides simple mechanisms to manage graphics data and control execution +flow within the linux DRM subsystem. However, gem is not a complete 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 applies, the syntax) that is shared between all drivers +that use gem. + +All GEM APIs are defined as +.BR ioctl (2) +on the DRM file descriptor. An application must be authorized via +.BR drmAuthMagic (2) +to the current DRM-Master to access the GEM subsystem. A driver that does not +support gem will return +.I ENODEV +for all these ioctls. Invalid object handles return +.I EINVAL +and invalid object names return +.IR 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 directly, 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 +.BR drm-prime (7) +infrastructure which can return real file-descriptor for gem-handles using the +linux dma-buf API. +.br +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. +.br +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 +.BR DRM_I915_GEM_CREATE ", " DRM_NOUVEAU_GEM_NEW " or " DRM_RADEON_GEM_CREATE . +Each of these ioctls returns a gem-handle that can be passed to different +generic ioctls. +.br +The +.I libgbm +library from the +.I 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 +.RI "(for example " drm-intel "(7) or " drm-radeon "(7))." + +Gem-buffers can be closed with the +.B DRM_IOCTL_GEM_CLOSE +ioctl. It takes as argument a structure of type +.IR "struct drm_gem_close" : + +.in +4n +.nf +struct drm_gem_close { + __u32 handle; + __u32 pad; +}; +.fi +.in + +The +.I handle +field is the gem-handle to be closed. The +.I pad +field is unused padding. It must be zeroed. After this call the gem handle +cannot be used by this process anymore and may be reused for new gem objects 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 32bit integer IDs and have no special +protection. That is, if you put a name on your gem-object, every other client +that has access to the DRM device and is authenticated via +.BR drmAuthMagic (3) +to the current DRM-Master, can +.I guess +the name and open or access the gem-object. If you want more fine-grained access +control, you can use the new +.BR drm-prime (7) +API to retrieve file-descriptors for gem-handles. +.br +To create a name for a gem-handle, you use the +.B DRM_IOCTL_GEM_FLINK +ioctl. It takes as argument a structure of type +.IR "struct drm_gem_flink" : + +.in +4n +.nf +struct drm_gem_flink { + __u32 handle; + __u32 name; +}; +.fi +.in + +You have to put your handle into the +.I handle +field. After completion, the kernel has put the new unique name into the +.I name +field. You can now pass this name to other processes which can then import the +name with the +.B DRM_IOCTL_GEM_OPEN +ioctl. It takes as argument a structure of type +.IR "struct drm_gem_open" : + +.in +4n +.nf +struct drm_gem_open { + __u32 name; + + __u32 handle; + __u32 size; +}; +.fi +.in + +You have to fill in the +.I name +field with the name of the gem-object that you want to open. The kernel will +fill in the +.I handle +and +.I 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 creation, CPU access, GPU +I/O and more. +.br +The next higher-level API is +.BR OpenGL . +So if you want to use more GPU features, you should use the +.I mesa3D +library to create OpenGL contexts on DRM devices. This does +.I 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 manpages, 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 +hardware-accelerated 2D or 3D rendering you must use OpenGL. Any other API that +tries to abstract the driver-internals to access GEM-execution-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, including +.BR drm-intel "(7), " drm-radeon "(7) and " drm-nouveau (7). +.br +However, the +.BR 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 allows 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 information. + +.SH EXAMPLES +This section includes examples for basic memory-management tasks. + +.SS 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. +.br +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 +.RB "(see " drm-kms "(7))." + +.in +4n +.nf + 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); +.fi +.in + +.SH REPORTING BUGS +Bugs in this manual should be reported to http://bugs.freedesktop.org under +the "Mesa" product, with "Other" or "libdrm" as the component. + +.SH "SEE ALSO" +.BR drm (7), +.BR drm-kms (7), +.BR drmAvailable (3), +.BR drmOpen (3), +.BR drm-intel (7), +.BR drm-radeon (7), +.BR drm-nouveau (7), +.BR drm-prime (7) diff --git a/man/drm-mm.7 b/man/drm-mm.7 new file mode 100644 index 0000000..258b5a3 --- /dev/null +++ b/man/drm-mm.7 @@ -0,0 +1 @@ +.so man7/drm-memory.7 diff --git a/man/drm-ttm.7 b/man/drm-ttm.7 new file mode 100644 index 0000000..258b5a3 --- /dev/null +++ b/man/drm-ttm.7 @@ -0,0 +1 @@ +.so man7/drm-memory.7