[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libdrm: Changes to 'upstream-experimental'



 .gitignore                   |    4 
 Makefile.am                  |    2 
 configure.ac                 |   26 --
 intel/intel_bufmgr_gem.c     |   10 -
 libkms/intel.c               |    1 
 libkms/linux.c               |    2 
 libkms/nouveau.c             |    1 
 man/Makefile.am              |   65 +++++-
 man/drm-kms.xml              |  342 ++++++++++++++++++++++++++++++++++
 man/drm-memory.xml           |  430 +++++++++++++++++++++++++++++++++++++++++++
 man/drm.xml                  |  137 +++++++++++++
 man/drmAvailable.man         |   25 --
 man/drmAvailable.xml         |   75 +++++++
 man/drmHandleEvent.man       |   45 ----
 man/drmHandleEvent.xml       |  102 ++++++++++
 man/drmModeGetResources.man  |   79 -------
 man/drmModeGetResources.xml  |  139 +++++++++++++
 nouveau/abi16.c              |   28 ++
 nouveau/libdrm_nouveau.pc.in |    2 
 nouveau/nouveau.c            |    3 
 nouveau/nouveau.h            |   16 +
 nouveau/private.h            |    1 
 nouveau/pushbuf.c            |    8 
 radeon/r600_pci_ids.h        |    1 
 radeon/radeon_bo_gem.c       |   16 +
 25 files changed, 1363 insertions(+), 197 deletions(-)

New commits:
commit 007bff7a034741dcf9d1716583f91fc4453d4112
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date:   Wed Jan 16 13:06:52 2013 +0100

    configure.ac: bump version to 2.4.41 for release

diff --git a/configure.ac b/configure.ac
index 0e6db86..10cc9a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
 
 AC_PREREQ([2.63])
 AC_INIT([libdrm],
-        [2.4.40],
+        [2.4.41],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
         [libdrm])
 

commit c41b494c47f8e514e69cb8c2f2ace41d5fa17c94
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Fri Nov 23 12:40:30 2012 +1000

    nouveau: expose channel engine selection on kepler chipsets
    
    v2: Take Maarten Lankhorst's suggestion of nesting the struct to prevent
        sizeof() issues due to padding on older revisions.
    
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>

diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index a67fbc1..f34175e 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -24,9 +24,11 @@
 
 #include <stdlib.h>
 #include <stdint.h>
+#include <stddef.h>
 
 #include "private.h"
 
+
 int
 abi16_chan_nv04(struct nouveau_object *obj)
 {
@@ -70,6 +72,32 @@ abi16_chan_nvc0(struct nouveau_object *obj)
 }
 
 int
+abi16_chan_nve0(struct nouveau_object *obj)
+{
+	struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+	struct drm_nouveau_channel_alloc req = {};
+	struct nve0_fifo *nve0 = obj->data;
+	int ret;
+
+	if (obj->length > offsetof(struct nve0_fifo, engine)) {
+		req.fb_ctxdma_handle = 0xffffffff;
+		req.tt_ctxdma_handle = nve0->engine;
+	}
+
+	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+				  &req, sizeof(req));
+	if (ret)
+		return ret;
+
+	nve0->base.channel = req.channel;
+	nve0->base.pushbuf = req.pushbuf_domains;
+	nve0->notify = req.notifier_handle;
+	nve0->base.object->handle = req.channel;
+	nve0->base.object->length = sizeof(*nve0);
+	return 0;
+}
+
+int
 abi16_engobj(struct nouveau_object *obj)
 {
 	struct drm_nouveau_grobj_alloc req = {
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 940d933..9b32e31 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -247,7 +247,10 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
 			if (dev->chipset < 0xc0)
 				ret = abi16_chan_nv04(obj);
 			else
+			if (dev->chipset < 0xe0)
 				ret = abi16_chan_nvc0(obj);
+			else
+				ret = abi16_chan_nve0(obj);
 		}
 			break;
 		default:
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index c42eea7..a55e2b0 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -41,6 +41,22 @@ struct nvc0_fifo {
 	uint32_t notify;
 };
 
+#define NVE0_FIFO_ENGINE_GR  0x00000001
+#define NVE0_FIFO_ENGINE_VP  0x00000002
+#define NVE0_FIFO_ENGINE_PPP 0x00000004
+#define NVE0_FIFO_ENGINE_BSP 0x00000008
+#define NVE0_FIFO_ENGINE_CE0 0x00000010
+#define NVE0_FIFO_ENGINE_CE1 0x00000020
+#define NVE0_FIFO_ENGINE_ENC 0x00000040
+
+struct nve0_fifo {
+	struct {
+		struct nouveau_fifo base;
+		uint32_t notify;
+	};
+	uint32_t engine;
+};
+
 struct nv04_notify {
 	struct nouveau_object *object;
 	uint32_t offset;
diff --git a/nouveau/private.h b/nouveau/private.h
index b409cc8..8a5cb26 100644
--- a/nouveau/private.h
+++ b/nouveau/private.h
@@ -113,6 +113,7 @@ nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t);
 /* abi16.c */
 int  abi16_chan_nv04(struct nouveau_object *);
 int  abi16_chan_nvc0(struct nouveau_object *);
+int  abi16_chan_nve0(struct nouveau_object *);
 int  abi16_engobj(struct nouveau_object *);
 int  abi16_ntfy(struct nouveau_object *);
 void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *);

commit 9e6f96a579fc2ed241e9a31a35a5995129ee8f7a
Author: Marcin Slusarz <marcin.slusarz@gmail.com>
Date:   Sun Dec 16 19:28:24 2012 +0100

    libdrm_nouveau.pc: don't include I${includedir}/nouveau
    
    Nouveau headers are installed in I${includedir}/libdrm.

diff --git a/nouveau/libdrm_nouveau.pc.in b/nouveau/libdrm_nouveau.pc.in
index 6170613..454fc87 100644
--- a/nouveau/libdrm_nouveau.pc.in
+++ b/nouveau/libdrm_nouveau.pc.in
@@ -7,5 +7,5 @@ Name: libdrm_nouveau
 Description: Userspace interface to nouveau kernel DRM services
 Version: 2.4.33
 Libs: -L${libdir} -ldrm_nouveau
-Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/nouveau
+Cflags: -I${includedir} -I${includedir}/libdrm
 Requires.private: libdrm

commit fdda97007b1dbf95beb16a0e3510fd36c89e8c33
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Jan 11 00:55:12 2013 +0000

    intel: Remove the fence count contributions when clearing relocs
    
    As we clear the relocs from the bo, we also need to clear the
    contribution of the reloc_target_bo from the fence count. Otherwise they
    are leaked and prevent any further relocations being added to the bo.

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 512bc6f..294e575 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -1733,9 +1733,10 @@ drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
 	assert(bo_gem->reloc_count >= start);
 	/* Unreference the cleared target buffers */
 	for (i = start; i < bo_gem->reloc_count; i++) {
-		if (bo_gem->reloc_target_info[i].bo != bo) {
-			drm_intel_gem_bo_unreference_locked_timed(bo_gem->
-								  reloc_target_info[i].bo,
+		drm_intel_bo_gem *target_bo_gem = (drm_intel_bo_gem *) bo_gem->reloc_target_info[i].bo;
+		if (&target_bo_gem->bo != bo) {
+			bo_gem->reloc_tree_fences -= target_bo_gem->reloc_tree_fences;
+			drm_intel_gem_bo_unreference_locked_timed(&target_bo_gem->bo,
 								  time.tv_sec);
 		}
 	}

commit 1dbd873700f281d9773e64931ff0c1cf96e13793
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Wed Jan 9 17:28:41 2013 -0800

    man: disable man page building until David saves us all
    
    I must have botched something in the push of the xml switchover, since I
    now get errors when building the pages and aliases.  Just disable for
    now.

diff --git a/Makefile.am b/Makefile.am
index 8ecd9d9..9f106d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,7 +49,7 @@ if HAVE_EXYNOS
 EXYNOS_SUBDIR = exynos
 endif
 
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include man
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include 
 
 libdrm_la_LTLIBRARIES = libdrm.la
 libdrm_ladir = $(libdir)

commit fd6b369d39bc710acf56632a292308eb4e23d6db
Author: David Herrmann <dh.herrmann@googlemail.com>
Date:   Fri Sep 28 23:44:22 2012 +0200

    man: add drm-memory overview page
    
    This adds an overview page that describes Dumb-Buffers, TTM and GEM. It
    does not describe chipset-specific features. You should do that in the
    driver-manpages.
    
    Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
    Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>

diff --git a/man/Makefile.am b/man/Makefile.am
index b393072..32acd07 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -7,10 +7,14 @@
 MANPAGES = \
 	drm.7 \
 	drm-kms.7 \
+	drm-memory.7 \
 	drmAvailable.3 \
 	drmHandleEvent.3 \
 	drmModeGetResources.3
-MANPAGES_ALIASES =
+MANPAGES_ALIASES = \
+	drm-mm.7 \
+	drm-gem.7 \
+	drm-ttm.7
 
 XML_FILES = \
 	${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubs %.7,%.xml,$(MANPAGES)}}}}
@@ -32,7 +36,8 @@ XSLTPROC_FLAGS = \
 
 XSLTPROC_PROCESS_MAN = \
 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
-	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< && \
+	$(SED) -i -e 's/^\.so \(.*\)\.\(.\)$$/\.so man\2\/\1\.\2/' $(MANPAGES_ALIASES)
 
 %.1: %.xml
 	$(XSLTPROC_PROCESS_MAN)
diff --git a/man/drm-memory.xml b/man/drm-memory.xml
new file mode 100644
index 0000000..6b4f075
--- /dev/null
+++ b/man/drm-memory.xml
@@ -0,0 +1,430 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd";>
+
+<!--
+  Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
+  Dedicated to the Public Domain
+-->
+
+<refentry id="drm-memory">
+  <refentryinfo>
+    <title>Direct Rendering Manager</title>
+    <productname>libdrm</productname>
+    <date>September 2012</date>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>David</firstname>
+        <surname>Herrmann</surname>
+        <email>dh.herrmann@googlemail.com</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>drm-memory</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>drm-memory</refname>
+    <refname>drm-mm</refname>
+    <refname>drm-gem</refname>
+    <refname>drm-ttm</refname>
+    <refpurpose>DRM Memory Management</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+      <para>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.</para>
+
+      <para>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.</para>
+
+    <refsect2>
+      <title>Dumb-Buffers</title>
+      <para>Almost all in-kernel DRM hardware drivers support an API called
+            <emphasis>Dumb-Buffers</emphasis>. This API allows to create buffers
+            of arbitrary size that can be used for scanout. These buffers can be
+            memory mapped via
+            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+            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.</para>
+
+      <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> 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
+            <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            and use it for mode-setting and scanout. To access the buffer, you
+            first need to retrieve the offset of the buffer. The
+            <constant>DRM_IOCTL_MODE_MAP_DUMB</constant> ioctl requests the DRM
+            subsystem to prepare the buffer for memory-mapping and returns a
+            fake-offset that can be used with
+            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
+
+      <para>The <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> ioctl takes as
+            argument a structure of type
+            <structname>struct drm_mode_create_dumb</structname>:
+
+<programlisting>
+struct drm_mode_create_dumb {
+	__u32 height;
+	__u32 width;
+	__u32 bpp;
+	__u32 flags;
+
+	__u32 handle;
+	__u32 pitch;
+	__u64 size;
+};
+</programlisting>
+
+            The fields <structfield>height</structfield>,
+            <structfield>width</structfield>, <structfield>bpp</structfield> and
+            <structfield>flags</structfield> have to be provided by the caller.
+            The other fields are filled by the kernel with the return values.
+            <structfield>height</structfield> and
+            <structfield>width</structfield> are the dimensions of the
+            rectangular buffer that is created. <structfield>bpp</structfield>
+            is the number of bits-per-pixel and must be a multiple of
+            <literal>8</literal>. You most commonly want to pass
+            <literal>32</literal> here. The <structfield>flags</structfield>
+            field is currently unused and must be zeroed. Different flags to
+            modify the behavior may be added in the future. After calling the
+            ioctl, the <structfield>handle</structfield>,
+            <structfield>pitch</structfield> and <structfield>size</structfield>
+            fields are filled by the kernel. <structfield>handle</structfield>
+            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 <structfield>pitch</structfield> field is the
+            pitch (or stride) of the new buffer. Most drivers use 32bit or 64bit
+            aligned stride-values. The <structfield>size</structfield> field
+            contains the absolute size in bytes of the buffer. This can normally
+            also be computed with
+            <emphasis>(height * pitch + width) * bpp / 4</emphasis>.</para>
+
+      <para>To prepare the buffer for
+            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+            you need to use the <constant>DRM_IOCTL_MODE_MAP_DUMB</constant>
+            ioctl. It takes as argument a structure of type
+            <structname>struct drm_mode_map_dumb</structname>:
+
+<programlisting>
+struct drm_mode_map_dumb {
+	__u32 handle;
+	__u32 pad;
+
+	__u64 offset;
+};
+</programlisting>
+
+            You need to put the gem-handle that was previously retrieved via
+            <constant>DRM_IOCTL_MODE_CREATE_DUMB</constant> into the
+            <structfield>handle</structfield> field. The
+            <structfield>pad</structfield> field is unused padding and must be
+            zeroed. After completion, the <structfield>offset</structfield>
+            field will contain an offset that can be used with
+            <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+            on the DRM file-descriptor.</para>
+
+      <para>If you don't need your dumb-buffer, anymore, you have to destroy it
+            with <constant>DRM_IOCTL_MODE_DESTROY_DUMB</constant>. If you close
+            the DRM file-descriptor, all open dumb-buffers are automatically
+            destroyed. This ioctl takes as argument a structure of type
+            <structname>struct drm_mode_destroy_dumb</structname>:
+
+<programlisting>
+struct drm_mode_destroy_dumb {
+	__u32 handle;
+};
+</programlisting>
+
+            You only need to put your handle into the
+            <structfield>handle</structfield> field. After this call, the handle
+            is invalid and may be reused for new buffers by the dumb-API.</para>
+
+    </refsect2>
+
+    <refsect2>
+      <title>TTM</title>
+      <para><emphasis>TTM</emphasis> stands for
+            <emphasis>Translation Table Manager</emphasis> and is a generic
+            memory-manager 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 manpages for more
+            information on memory-management with radeon and TTM.</para>
+    </refsect2>
+
+    <refsect2>
+      <title>GEM</title>
+      <para><emphasis>GEM</emphasis> stands for
+            <emphasis>Graphics Execution Manager</emphasis> 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.</para>
+
+      <para>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.</para>
+
+      <para>All GEM APIs are defined as
+            <citerefentry><refentrytitle>ioctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+            on the DRM file descriptor. An application must be authorized via
+            <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            to the current DRM-Master to access the GEM subsystem. A driver that
+            does not support gem will return <constant>ENODEV</constant> for all
+            these ioctls. Invalid object handles return
+            <constant>EINVAL</constant> and invalid object names return
+            <constant>ENOENT</constant>.</para>
+
+      <para>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.</para>
+
+      <para>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
+            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+            infrastructure 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.</para>
+
+      <para>Gem-buffers cannot be created with a generic API. Each driver
+            provides its own API to create gem-buffers. See for example
+            <constant>DRM_I915_GEM_CREATE</constant>,
+            <constant>DRM_NOUVEAU_GEM_NEW</constant> or
+            <constant>DRM_RADEON_GEM_CREATE</constant>. Each of these ioctls
+            returns a gem-handle that can be passed to different generic ioctls.
+            The <emphasis>libgbm</emphasis> library from the
+            <emphasis>mesa3D</emphasis> 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
+            <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+            or
+            <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
+
+      <para>Gem-buffers can be closed with the
+            <constant>DRM_IOCTL_GEM_CLOSE</constant> ioctl. It takes as argument
+            a structure of type <structname>struct drm_gem_close</structname>:
+
+<programlisting>
+struct drm_gem_close {
+	__u32 handle;
+	__u32 pad;
+};
+</programlisting>
+
+            The <structfield>handle</structfield> field is the gem-handle to be
+            closed. The <structfield>pad</structfield> 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.</para>
+
+      <para>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
+            <citerefentry><refentrytitle>drmAuthMagic</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            to the current DRM-Master, can <emphasis>guess</emphasis> the name
+            and open or access the gem-object. If you want more fine-grained
+            access control, you can use the new
+            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+            API to retrieve file-descriptors for gem-handles. To create a name
+            for a gem-handle, you use the
+            <constant>DRM_IOCTL_GEM_FLINK</constant> ioctl. It takes as argument
+            a structure of type <structname>struct drm_gem_flink</structname>:
+
+<programlisting>
+struct drm_gem_flink {
+	__u32 handle;
+	__u32 name;
+};
+</programlisting>
+
+            You have to put your handle into the
+            <structfield>handle</structfield> field. After completion, the
+            kernel has put the new unique name into the
+            <structfield>name</structfield> field. You can now pass this name to
+            other processes which can then import the name with the
+            <constant>DRM_IOCTL_GEM_OPEN</constant> ioctl. It takes as argument
+            a structure of type <structname>struct drm_gem_open</structname>:
+
+<programlisting>
+struct drm_gem_open {
+	__u32 name;
+
+	__u32 handle;
+	__u32 size;
+};
+</programlisting>
+
+            You have to fill in the <structfield>name</structfield> field with
+            the name of the gem-object that you want to open. The kernel will
+            fill in the <structfield>handle</structfield> and
+            <structfield>size</structfield> 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.</para>
+
+      <para>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. The next
+            higher-level API is <emphasis>OpenGL</emphasis>. So if you want to
+            use more GPU features, you should use the
+            <emphasis>mesa3D</emphasis> library to create OpenGL contexts on DRM
+            devices. This does <emphasis>not</emphasis> 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
+            <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+            <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+            and
+            <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+            However, the
+            <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+            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.</para>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+      <para>This section includes examples for basic memory-management
+            tasks.</para>
+
+    <refsect2>
+      <title>Dumb-Buffers</title>
+        <para>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
+              <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>).</para>
+
+<programlisting>
+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(&amp;creq, 0, sizeof(creq));
+creq.width = 1920;
+creq.height = 1080;
+creq.bpp = 32;
+ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &amp;creq);
+if (ret &lt; 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, &amp;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(&amp;mreq, 0, sizeof(mreq));
+mreq.handle = creq.handle;
+ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &amp;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);
+</programlisting>
+
+    </refsect2>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Reporting Bugs</title>
+    <para>Bugs in this manual should be reported to
+          http://bugs.freedesktop.org under the "Mesa" product, with "Other" or
+          "libdrm" as the component.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>drm</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drm-kms</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drm-prime</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drmAvailable</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drmOpen</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drm-intel</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drm-radeon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>drm-nouveau</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+</refentry>

commit 8cd0c131df20d983657c4e205493109a8c71624e
Author: David Herrmann <dh.herrmann@googlemail.com>
Date:   Fri Sep 28 23:44:21 2012 +0200

    man: add drm-kms overview page
    
    This is an overview page for KMS. It is again targeted at novice users
    that need redirection to the correct function man-pages.
    
    Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
    Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>

diff --git a/man/Makefile.am b/man/Makefile.am
index 01b5699..b393072 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -6,6 +6,7 @@
 
 MANPAGES = \
 	drm.7 \
+	drm-kms.7 \
 	drmAvailable.3 \
 	drmHandleEvent.3 \
 	drmModeGetResources.3
diff --git a/man/drm-kms.xml b/man/drm-kms.xml
new file mode 100644
index 0000000..5f04157
--- /dev/null
+++ b/man/drm-kms.xml
@@ -0,0 +1,342 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd";>
+
+<!--
+  Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
+  Dedicated to the Public Domain
+-->
+
+<refentry id="drm-kms">
+  <refentryinfo>
+    <title>Direct Rendering Manager</title>
+    <productname>libdrm</productname>
+    <date>September 2012</date>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>David</firstname>
+        <surname>Herrmann</surname>
+        <email>dh.herrmann@googlemail.com</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>drm-kms</refentrytitle>
+    <manvolnum>7</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>drm-kms</refname>
+    <refpurpose>Kernel Mode-Setting</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;xf86drm.h&gt;</funcsynopsisinfo>
+      <funcsynopsisinfo>#include &lt;xf86drmMode.h&gt;</funcsynopsisinfo>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+    <para>Each DRM device provides access to manage which monitors and displays
+          are currently used and what frames to be displayed. This task is
+          called <emphasis>Kernel Mode-Setting</emphasis> (KMS). Historically,
+          this was done in user-space and called 
+          <emphasis>User-space Mode-Setting</emphasis> (UMS). Almost all
+          open-source drivers now provide the KMS kernel API to do this in the
+          kernel, however, many non-open-source binary drivers from different
+          vendors still do not support this. You can use
+          <citerefentry><refentrytitle>drmModeSettingSupported</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+          to check whether your driver supports this. To understand how KMS
+          works, we need to introduce 5 objects: <emphasis>CRTCs</emphasis>,
+          <emphasis>Planes</emphasis>, <emphasis>Encoders</emphasis>,
+          <emphasis>Connectors</emphasis> and
+          <emphasis>Framebuffers</emphasis>.
+
+      <variablelist>
+        <varlistentry>
+          <term>CRTCs</term>
+          <listitem>
+            <para>A <emphasis>CRTC</emphasis> short for
+                  <emphasis>CRT Controller</emphasis> is an abstraction
+                  representing a part of the chip that contains a pointer to a
+                  scanout buffer. Therefore, the number of CRTCs available
+                  determines how many independent scanout buffers can be active
+                  at any given time. The CRTC structure contains several fields
+                  to support this: a pointer to some video memory (abstracted as
+                  a frame-buffer object), a list of driven connectors, a display
+                  mode and an (x, y) offset into the video memory to support
+                  panning or configurations where one piece of video memory
+                  spans multiple CRTCs. A CRTC is the central point where
+                  configuration of displays happens. You select which objects to
+                  use, which modes and which parameters and then configure each
+                  CRTC via
+                  <citerefentry><refentrytitle>drmModeCrtcSet</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                  to drive the display devices.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>Planes</term>
+          <listitem>
+            <para>A <emphasis>plane</emphasis> respresents an image source that
+                  can be blended with or overlayed on top of a CRTC during the
+                  scanout process. Planes are associated with a frame-buffer to
+                  crop a portion of the image memory (source) and optionally
+                  scale it to a destination size. The result is then blended
+                  with or overlayed on top of a CRTC. Planes are not provided by
+                  all hardware and the number of available planes is limited. If
+                  planes are not available or if not enough planes are
+                  available, the user should fall back to normal software
+                  blending (via GPU or CPU).</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>Encoders</term>
+          <listitem>
+            <para>An <emphasis>encoder</emphasis> takes pixel data from a CRTC
+                  and converts it to a format suitable for any attached
+                  connectors. On some devices, it may be possible to have a CRTC
+                  send data to more than one encoder. In that case, both
+                  encoders would receive data from the same scanout buffer,
+                  resulting in a <emphasis>cloned</emphasis> display
+                  configuration across the connectors attached to each
+                  encoder.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>Connectors</term>
+          <listitem>
+            <para>A <emphasis>connector</emphasis> is the final destination of
+                  pixel-data on a device, and usually connects directly to an
+                  external display device like a monitor or laptop panel. A
+                  connector can only be attached to one encoder at a time. The
+                  connector is also the structure where information about the
+                  attached display is kept, so it contains fields for display
+                  data, <emphasis>EDID</emphasis> data,
+                  <emphasis>DPMS</emphasis> and
+                  <emphasis>connection status</emphasis>, and information about
+                  modes supported on the attached displays.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>Framebuffers</term>
+          <listitem>
+            <para><emphasis>Framebuffers</emphasis> are abstract memory objects
+                  that provide a source of pixel data to scanout to a CRTC.
+                  Applications explicitely request the creation of framebuffers
+                  and can control their behavior. Framebuffers rely on the
+                  underneath memory manager for low-level memory operations.
+                  When creating a framebuffer, applications pass a memory handle
+                  through the API which is used as backing storage. The
+                  framebuffer itself is only an abstract object with no data. It
+                  just refers to memory buffers that must be created with the
+                  <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                  API.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </para>
+
+    <refsect2>
+      <title>Mode-Setting</title>
+      <para>Before mode-setting can be performed, an application needs to call
+            <citerefentry><refentrytitle>drmSetMaster</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            to become <emphasis>DRM-Master</emphasis>. It then has exclusive
+            access to the KMS API. A call to
+            <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            returns a list of <emphasis>CRTCs</emphasis>,
+            <emphasis>Connectors</emphasis>, <emphasis>Encoders</emphasis> and
+            <emphasis>Planes</emphasis>.</para>
+
+      <para>Normal procedure now includes: First, you select which connectors
+            you want to use. Users are mostly interested in which monitor or
+            display-panel is active so you need to make sure to arrange them in
+            the correct logical order and select the correct ones to use. For
+            each connector, you need to find a CRTC to drive this connector. If
+            you want to clone output to two or more connectors, you may use a
+            single CRTC for all cloned connectors (if the hardware supports
+            this). To find a suitable CRTC, you need to iterate over the list of
+            encoders that are available for each connector. Each encoder
+            contains a list of CRTCs that it can work with and you simply select
+            one of these CRTCs. If you later program the CRTC to control a
+            connector, it automatically selects the best encoder. However, this
+            procedure is needed so your CRTC has at least one working encoder
+            for the selected connector. See the <emphasis>Examples</emphasis>
+            section below for more information.</para>
+
+      <para>All valid modes for a connector can be retrieved with a call to
+            <citerefentry><refentrytitle>drmModeGetConnector</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            You need to select the mode you want to use and save it. The first
+            mode in the list is the default mode with the highest resolution
+            possible and often a suitable choice.</para>
+
+      <para>After you have a working connector+CRTC+mode combination, you need
+            to create a framebuffer that is used for scanout. Memory buffer
+            allocation is driver-depedent and described in
+            <citerefentry><refentrytitle>drm-memory</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+            You need to create a buffer big enough for your selected mode. Now
+            you can create a framebuffer object that uses your memory-buffer as
+            scanout buffer. You can do this with
+            <citerefentry><refentrytitle>drmModeAddFB</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            and
+            <citerefentry><refentrytitle>drmModeAddFB2</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+      <para>As a last step, you want to program your CRTC to drive your selected
+            connector. You can do this with a call to
+            <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+    </refsect2>
+
+    <refsect2>
+      <title>Page-Flipping</title>
+      <para>A call to
+            <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            is executed immediately and forces the CRTC to use the new scanout
+            buffer. If you want smooth-transitions without tearing, you probably
+            use double-buffering. You need to create one framebuffer object for
+            each buffer you use. You can then call
+            <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            on the next buffer to flip. If you want to synchronize your flips
+            with <emphasis>vertical-blanks</emphasis>, you can use
+            <citerefentry><refentrytitle>drmModePageFlip</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            which schedules your page-flip for the next
+            <emphasis>vblank</emphasis>.</para>
+    </refsect2>
+
+    <refsect2>
+      <title>Planes</title>
+      <para>Planes are controlled independently from CRTCs. That is, a call to
+            <citerefentry><refentrytitle>drmModeSetCrtc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            does not affect planes. Instead, you need to call
+            <citerefentry><refentrytitle>drmModeSetPlane</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            to configure a plane. This requires the plane ID, a CRTC, a
+            framebuffer and offsets into the plane-framebuffer and the
+            CRTC-framebuffer. The CRTC then blends the content from the plane
+            over the CRTC framebuffer buffer during scanout. As this does not
+            involve any software-blending, it is way faster than traditional
+            blending. However, plane resources are limited. See
+            <citerefentry><refentrytitle>drmModeGetPlaneResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            for more information.</para>
+    </refsect2>
+
+    <refsect2>
+      <title>Cursors</title>
+      <para>Similar to planes, many hardware also supports cursors. A cursor is
+            a very small buffer with an image that is blended over the CRTC
+            framebuffer. You can set a different cursor for each CRTC with
+            <citerefentry><refentrytitle>drmModeSetCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            and move it on the screen with
+            <citerefentry><refentrytitle>drmModeMoveCursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+            This allows to move the cursor on the screen without rerendering. If
+            no hardware cursors are supported, you need to rerender for each
+            frame the cursor is moved.</para>
+    </refsect2>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <para>Some examples of how basic mode-setting can be done. See the man-page
+          of each DRM function for more information.</para>
+
+    <refsect2>
+      <title>CRTC/Encoder Selection</title>
+      <para>If you retrieved all display configuration information via
+            <citerefentry><refentrytitle>drmModeGetResources</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+            as <structname>drmModeRes</structname> *<varname>res</varname>,
+            selected a connector from the list in
+            <varname>res</varname>-><structfield>connectors</structfield>
+            and retrieved the connector-information as
+            <structname>drmModeConnector</structname> *<varname>conn</varname>
+            via


Reply to: