[PATCH libdrm 4/4] man: add drm-memory man-page

David Herrmann dh.herrmann at googlemail.com
Sun Sep 23 07:40:07 PDT 2012


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 <dh.herrmann at googlemail.com>
---
 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 <xf86drm.h>
+
+.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
-- 
1.7.12.1



More information about the dri-devel mailing list