libdrm: Changes to 'debian-experimental'
.gitignore | 4
ChangeLog | 174 +++++++++++++++
Makefile.am | 2
configure.ac | 26 --
debian/changelog | 7
debian/libdrm-dev.install | 3
debian/libdrm-nouveau2.symbols | 1
debian/patches/02_fix_build.diff | 12 +
debian/patches/series | 1
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 -
31 files changed, 1559 insertions(+), 199 deletions(-)
New commits:
commit 9ab7a43c4e57e618854b3641101fcd707736dbf0
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Wed Jan 16 14:04:59 2013 +0100
Add 02_fix_build.diff fix a build error.
diff --git a/debian/changelog b/debian/changelog
index c1edea0..9111d6c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,7 @@ libdrm (2.4.41-1) UNRELEASED; urgency=low
[ Maarten Lankhorst ]
* New upstream release.
+ * Add 02_fix_build.diff fix a build error.
-- Julien Cristau <jcristau@debian.org> Tue, 25 Dec 2012 13:17:28 +0100
diff --git a/debian/patches/02_fix_build.diff b/debian/patches/02_fix_build.diff
new file mode 100644
index 0000000..234101b
--- /dev/null
+++ b/debian/patches/02_fix_build.diff
@@ -0,0 +1,12 @@
+diff --git a/configure.ac b/configure.ac
+index 10cc9a4..1776610 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -348,7 +348,6 @@ AC_CONFIG_FILES([
+ tests/vbltest/Makefile
+ include/Makefile
+ include/drm/Makefile
+- man/Makefile
+ libdrm.pc])
+ AC_OUTPUT
+
diff --git a/debian/patches/series b/debian/patches/series
index 2e425c0..e64f736 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
01_default_perms.diff
+02_fix_build.diff
03_build_against_librt.diff
commit ed2ab427f7d40fcd52a16e8aa0360d440fbf3385
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Wed Jan 16 13:41:45 2013 +0100
New upstream release.
Manpage building has temporarily been disabled upstream,
but when it's re-enabled we should require xsltproc.
diff --git a/ChangeLog b/ChangeLog
index 53b397c..e1df3ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,177 @@
+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
+
+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>
+
+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.
+
+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.
+
+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.
+
+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>
+
+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>
+
+commit 0a766a5388ba6ff0983ad5181a5f6644aea8050a
+Author: David Herrmann <dh.herrmann@googlemail.com>
+Date: Fri Sep 28 23:44:20 2012 +0200
+
+ man: add drm.7 overview page
+
+ The drm.xml file compiles to drm.7 and is meant as a global overview page
+ for libdrm. It is targeted to new users of libdrm and redirects to all
+ other main man-pages.
+
+ Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
+ Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit 6b7e45c7516b7fdfe85e7792f82624458dcb2ac6
+Author: David Herrmann <dh.herrmann@googlemail.com>
+Date: Fri Sep 28 23:44:19 2012 +0200
+
+ man: convert manpages to XML instead of plain troff
+
+ If we want to use the manpages in external documentation other than normal
+ manpages, we should rather use XML. Furthermore, almost no-one knows troff
+ today, anyway, and XML allows others to easily add more pages without
+ having to learn troff.
+
+ Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
+
+commit 891517f5111cd82909906d5e8ee0299db0d46762
+Author: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon Jan 7 13:07:13 2013 +1000
+
+ nouveau: disallow pushbuf BOs in multiple memory types
+
+ Under certain circumstances it's possible for libdrm to decide to move
+ a GART|VRAM pushbuf to be VRAM-only. This causes the kernel to reject
+ the command submission on GF8 and up, due to a stricter policy where
+ buffers are only allowed to move to memory types that were specified
+ at creation time.
+
+ The simplest fix for this is to force the creation-time memory type for
+ the lifetime of the push buffer.
+
+ Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+
+commit baf0a7daafc7636106e1b19267ed22e22b1a2283
+Author: Maxime Villard <rustyBSD@gmx.fr>
+Date: Wed Jan 2 10:57:07 2013 -0500
+
+ libkms: return -EINVAL on fstat error
+
+ On error fstat return -1, instead return -EINVAL to caller
+
+ Signed-off-by: Maxime Villard <rustyBSD@gmx.fr>
+ Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+
+commit 1f4b5e11e638fc87bd0ac8e3530b407211b76d45
+Author: Maxime Villard <rustyBSD@gmx.fr>
+Date: Wed Jan 2 10:55:50 2013 -0500
+
+ libkms: fix memory leak in error path
+
+ Signed-off-by: Maxime Villard <rustyBSD@gmx.fr>
+ Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+
+commit 0980633afd9c7eecc0c75ef3bea4d3c6b7aa1898
+Author: Jerome Glisse <jglisse@redhat.com>
+Date: Tue Nov 27 13:59:11 2012 -0500
+
+ drm/radeon: track global bo name and always return the same
+
+ To avoid kernel rejecting cs if we return different global name
+ for same bo keep track of global name and always return the same.
+ Seems to fix issue with suspend/resume failing and repeatly printing
+ following message :
+ [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation -35!
+
+ There might still be way for a rogue program to trigger this issue.
+
+ Signed-off-by: Jerome Glisse <jglisse@redhat.com>
+
+commit 171666e4b8127c17c68ea0d44cf4e81ec342f2d0
+Author: Alex Deucher <alexdeucher@gmail.com>
+Date: Wed Nov 21 18:45:14 2012 -0500
+
+ radeon: add new SI pci id
+
+ Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
+
+commit 7d42b49c0cf19dbb4531cd84efae51f95db2eea1
+Author: David Shao <davshao@gmail.com>
+Date: Sat Nov 10 00:24:56 2012 -0500
+
+ intel: Fix missing ETIME on BSD operating systems
+
+ Originally posted to Free Desktop bug #52549 by David Shao.
+ Resolves Gentoo Bug #433403.
+ Commit message by Richard Yao.
+
+ Reviewed-by: Richard Yao <ryao@gentoo.org>
+ Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
+ References: https://bugs.freedesktop.org/show_bug.cgi?id=52549
+
+ Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
+
commit e01d68f9f3acfc35fe164283904b5d058c2ab378
Author: Marek Olšák <maraeo@gmail.com>
Date: Tue Nov 6 01:23:53 2012 +0100
diff --git a/debian/changelog b/debian/changelog
index 806159d..c1edea0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,7 +1,11 @@
-libdrm (2.4.40-2) UNRELEASED; urgency=low
+libdrm (2.4.41-1) UNRELEASED; urgency=low
+ [ Julien Cristau ]
* Bump libdrm2 shlibs to 2.4.38.
+ [ Maarten Lankhorst ]
+ * New upstream release.
+
-- Julien Cristau <jcristau@debian.org> Tue, 25 Dec 2012 13:17:28 +0100
libdrm (2.4.40-1) experimental; urgency=low
diff --git a/debian/libdrm-dev.install b/debian/libdrm-dev.install
index e1ca993..078a4c3 100644
--- a/debian/libdrm-dev.install
+++ b/debian/libdrm-dev.install
@@ -2,4 +2,5 @@ usr/include/*
usr/lib/*/lib*.a
usr/lib/*/lib*.so
usr/lib/*/pkgconfig/*
-usr/share/man/man3
+#usr/share/man/man3
+#usr/share/man/man7
diff --git a/debian/libdrm-nouveau2.symbols b/debian/libdrm-nouveau2.symbols
index 1b5ee4c..278ee55 100644
--- a/debian/libdrm-nouveau2.symbols
+++ b/debian/libdrm-nouveau2.symbols
@@ -4,6 +4,7 @@ libdrm_nouveau.so.2 libdrm-nouveau2 #MINVER#
abi16_bo_init@Base 0 1
abi16_chan_nv04@Base 0 1
abi16_chan_nvc0@Base 0 1
+ abi16_chan_nve0@Base 0 1
abi16_engobj@Base 0 1
abi16_ntfy@Base 0 1
nouveau_bo_map@Base 2.4.34
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 <xf86drm.h></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(&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);
+</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>
Reply to: