[libdrm] add libdrm prime support for core, intel, nouveau

Dave Airlie airlied at fedoraproject.org
Wed Jul 25 06:07:31 UTC 2012


commit b396f066fd6b4270ef08e5f6f5b33db7cdf0ba7e
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jul 25 16:07:00 2012 +1000

    add libdrm prime support for core, intel, nouveau

 libdrm-2.4.37-prime.patch |  246 +++++++++++++++++++++++++++++++++++++++++++++
 libdrm.spec               |    8 ++-
 2 files changed, 253 insertions(+), 1 deletions(-)
---
diff --git a/libdrm-2.4.37-prime.patch b/libdrm-2.4.37-prime.patch
new file mode 100644
index 0000000..bc7f747
--- /dev/null
+++ b/libdrm-2.4.37-prime.patch
@@ -0,0 +1,246 @@
+diff --git a/include/drm/drm.h b/include/drm/drm.h
+index 5e6cd29..a847689 100644
+--- a/include/drm/drm.h
++++ b/include/drm/drm.h
+@@ -685,6 +685,9 @@ struct drm_prime_handle {
+ #define DRM_IOCTL_UNLOCK		DRM_IOW( 0x2b, struct drm_lock)
+ #define DRM_IOCTL_FINISH		DRM_IOW( 0x2c, struct drm_lock)
+ 
++#define DRM_IOCTL_PRIME_HANDLE_TO_FD    DRM_IOWR(0x2d, struct drm_prime_handle)
++#define DRM_IOCTL_PRIME_FD_TO_HANDLE    DRM_IOWR(0x2e, struct drm_prime_handle)
++
+ #define DRM_IOCTL_AGP_ACQUIRE		DRM_IO(  0x30)
+ #define DRM_IOCTL_AGP_RELEASE		DRM_IO(  0x31)
+ #define DRM_IOCTL_AGP_ENABLE		DRM_IOW( 0x32, struct drm_agp_mode)
+@@ -697,9 +700,6 @@ struct drm_prime_handle {
+ #define DRM_IOCTL_SG_ALLOC		DRM_IOWR(0x38, struct drm_scatter_gather)
+ #define DRM_IOCTL_SG_FREE		DRM_IOW( 0x39, struct drm_scatter_gather)
+ 
+-#define DRM_IOCTL_PRIME_HANDLE_TO_FD    DRM_IOWR(0x2d, struct drm_prime_handle)
+-#define DRM_IOCTL_PRIME_FD_TO_HANDLE    DRM_IOWR(0x2e, struct drm_prime_handle)
+-
+ #define DRM_IOCTL_WAIT_VBLANK		DRM_IOWR(0x3a, union drm_wait_vblank)
+ 
+ #define DRM_IOCTL_UPDATE_DRAW		DRM_IOW(0x3f, struct drm_update_draw)
+@@ -776,6 +776,12 @@ struct drm_event_vblank {
+ 
+ #define DRM_CAP_DUMB_BUFFER 0x1
+ #define DRM_CAP_VBLANK_HIGH_CRTC   0x2
++#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3
++#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
++#define DRM_CAP_PRIME 0x5
++
++#define DRM_PRIME_CAP_IMPORT 0x1
++#define DRM_PRIME_CAP_EXPORT 0x2
+ 
+ /* typedef area */
+ typedef struct drm_clip_rect drm_clip_rect_t;
+diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
+index 9b3a483..2167e43 100644
+--- a/intel/intel_bufmgr.h
++++ b/intel/intel_bufmgr.h
+@@ -192,6 +192,10 @@ void drm_intel_gem_context_destroy(drm_intel_context *ctx);
+ int drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
+ 				  int used, unsigned int flags);
+ 
++int drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd);
++drm_intel_bo *drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr,
++						int prime_fd, int size);
++
+ /* drm_intel_bufmgr_fake.c */
+ drm_intel_bufmgr *drm_intel_bufmgr_fake_init(int fd,
+ 					     unsigned long low_offset,
+diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
+index 12a3197..eae2199 100644
+--- a/intel/intel_bufmgr_gem.c
++++ b/intel/intel_bufmgr_gem.c
+@@ -2413,6 +2413,69 @@ drm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
+ 	return 0;
+ }
+ 
++drm_intel_bo *
++drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
++{
++	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
++	int ret;
++	uint32_t handle;
++	drm_intel_bo_gem *bo_gem;
++	struct drm_i915_gem_get_tiling get_tiling;
++
++	ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
++	if (ret) {
++	  fprintf(stderr,"ret is %d %d\n", ret, errno);
++		return NULL;
++	}
++
++	bo_gem = calloc(1, sizeof(*bo_gem));
++	if (!bo_gem)
++		return NULL;
++
++	bo_gem->bo.size = size;
++	bo_gem->bo.handle = handle;
++	bo_gem->bo.bufmgr = bufmgr;
++
++	bo_gem->gem_handle = handle;
++
++	atomic_set(&bo_gem->refcount, 1);
++
++	bo_gem->name = "prime";
++	bo_gem->validate_index = -1;
++	bo_gem->reloc_tree_fences = 0;
++	bo_gem->used_as_reloc_target = false;
++	bo_gem->has_error = false;
++	bo_gem->reusable = false;
++
++	DRMINITLISTHEAD(&bo_gem->name_list);
++	DRMINITLISTHEAD(&bo_gem->vma_list);
++
++	VG_CLEAR(get_tiling);
++	get_tiling.handle = bo_gem->gem_handle;
++	ret = drmIoctl(bufmgr_gem->fd,
++		       DRM_IOCTL_I915_GEM_GET_TILING,
++		       &get_tiling);
++	if (ret != 0) {
++		drm_intel_gem_bo_unreference(&bo_gem->bo);
++		return NULL;
++	}
++	bo_gem->tiling_mode = get_tiling.tiling_mode;
++	bo_gem->swizzle_mode = get_tiling.swizzle_mode;
++	/* XXX stride is unknown */
++	drm_intel_bo_gem_set_in_aperture_size(bufmgr_gem, bo_gem);
++
++	return &bo_gem->bo;
++}
++
++int
++drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
++{
++	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
++	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
++
++	return drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle, DRM_CLOEXEC, prime_fd);
++}
++
+ static int
+ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
+ {
+diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
+index 5aa4107..940d933 100644
+--- a/nouveau/nouveau.c
++++ b/nouveau/nouveau.c
+@@ -34,6 +34,7 @@
+ #include <assert.h>
+ #include <errno.h>
+ #include <sys/mman.h>
++#include <fcntl.h>
+ 
+ #include <xf86drm.h>
+ #include <xf86atomic.h>
+@@ -442,6 +443,40 @@ nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
+ }
+ 
+ int
++nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
++			    struct nouveau_bo **bo)
++{
++	int ret;
++	unsigned int handle;
++
++	ret = drmPrimeFDToHandle(dev->fd, prime_fd, &handle);
++	if (ret) {
++		nouveau_bo_ref(NULL, bo);
++		return ret;
++	}
++
++	ret = nouveau_bo_wrap(dev, handle, bo);
++	if (ret) {
++		nouveau_bo_ref(NULL, bo);
++		return ret;
++	}
++
++	return 0;
++}
++
++int
++nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
++{
++	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
++	int ret;
++
++	ret = drmPrimeHandleToFD(bo->device->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd);
++	if (ret)
++		return ret;
++	return 0;
++}
++
++int
+ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
+ 		struct nouveau_client *client)
+ {
+diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
+index 51a9598..c42eea7 100644
+--- a/nouveau/nouveau.h
++++ b/nouveau/nouveau.h
+@@ -135,6 +135,9 @@ int  nouveau_bo_map(struct nouveau_bo *, uint32_t access,
+ 		    struct nouveau_client *);
+ int  nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
+ 		     struct nouveau_client *);
++int  nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
++				 struct nouveau_bo **);
++int  nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd);
+ 
+ struct nouveau_bufref {
+ 	struct nouveau_list thead;
+diff --git a/xf86drm.c b/xf86drm.c
+index 6ea068f..2a74c80 100644
+--- a/xf86drm.c
++++ b/xf86drm.c
+@@ -2542,3 +2542,34 @@ char *drmGetDeviceNameFromFd(int fd)
+ 
+ 	return strdup(name);
+ }
++
++int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
++{
++	struct drm_prime_handle args;
++	int ret;
++
++	args.handle = handle;
++	args.flags = flags;
++	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
++	if (ret)
++		return ret;
++
++	*prime_fd = args.fd;
++	return 0;
++}
++
++int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
++{
++	struct drm_prime_handle args;
++	int ret;
++
++	args.fd = prime_fd;
++	args.flags = 0;
++	ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
++	if (ret)
++		return ret;
++
++	*handle = args.handle;
++	return 0;
++}
++
+diff --git a/xf86drm.h b/xf86drm.h
+index 76eb94e..5ecb284 100644
+--- a/xf86drm.h
++++ b/xf86drm.h
+@@ -727,6 +727,9 @@ extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
+ 
+ extern char *drmGetDeviceNameFromFd(int fd);
+ 
++extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
++extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
++
+ #if defined(__cplusplus) || defined(c_plusplus)
+ }
+ #endif
diff --git a/libdrm.spec b/libdrm.spec
index e850364..00a9bdd 100644
--- a/libdrm.spec
+++ b/libdrm.spec
@@ -3,7 +3,7 @@
 Summary: Direct Rendering Manager runtime library
 Name: libdrm
 Version: 2.4.37
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: MIT
 Group: System Environment/Libraries
 URL: http://dri.sourceforge.net
@@ -34,6 +34,8 @@ Patch4: libdrm-2.4.0-no-bc.patch
 Patch5: libdrm-2.4.25-check-programs.patch
 # backport from upstream
 Patch6: libdrm-2.4.37-i915-hush.patch
+# backport from upstream
+Patch7: libdrm-2.4.37-prime.patch
 
 %description
 Direct Rendering Manager runtime library
@@ -62,6 +64,7 @@ Utility programs for the kernel DRM interface.  Will void your warranty.
 %patch4 -p1 -b .no-bc
 %patch5 -p1 -b .check
 %patch6 -p1 -b .hush
+%patch7 -p1 -b .prime
 
 %build
 autoreconf -v --install || exit 1
@@ -182,6 +185,9 @@ done
 %{_libdir}/pkgconfig/libdrm_nouveau.pc
 
 %changelog
+* Wed Jul 25 2012 Dave Airlie <airlied at redhat.com> 2.4.37-3
+- add libdrm prime support for core, intel, nouveau
+
 * Mon Jul 23 2012 Adam Jackson <ajax at redhat.com> 2.4.37-2
 - libdrm-2.4.37-i915-hush.patch: Silence an excessive error message
 


More information about the scm-commits mailing list