From b396f066fd6b4270ef08e5f6f5b33db7cdf0ba7e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Jul 2012 16:07:00 +1000 Subject: [PATCH] add libdrm prime support for core, intel, nouveau --- libdrm-2.4.37-prime.patch | 246 ++++++++++++++++++++++++++++++++++++++ libdrm.spec | 8 +- 2 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 libdrm-2.4.37-prime.patch 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 + #include + #include ++#include + + #include + #include +@@ -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 2.4.37-3 +- add libdrm prime support for core, intel, nouveau + * Mon Jul 23 2012 Adam Jackson 2.4.37-2 - libdrm-2.4.37-i915-hush.patch: Silence an excessive error message