From: <ai...@ke...> - 2012-07-20 00:30:40
|
include/drm/drm.h | 12 ++++++-- intel/intel_bufmgr.h | 4 ++ intel/intel_bufmgr_gem.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ nouveau/nouveau.c | 35 ++++++++++++++++++++++++++ nouveau/nouveau.h | 3 ++ xf86drm.c | 31 +++++++++++++++++++++++ xf86drm.h | 3 ++ 7 files changed, 148 insertions(+), 3 deletions(-) New commits: commit ff65de96660965e661175f75427cd0020ef1104c Author: Dave Airlie <ai...@gm...> Date: Sun Jul 15 00:22:46 2012 +0000 intel: add prime interface for getting/setting a prime bo. (v4) This adds interfaces for the X driver to use to create a prime handle from a buffer, and create a bo from a handle. v2: use Chris's suggested naming (well from at least for consistency) v3: git commit --amend fail v4: fix as per Chris's suggestions, group assignments, add get tiling Reviewed-by: Chris Wilson <ch...@ch...> Signed-off-by: Dave Airlie <ai...@re...> 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) { commit 13c06cde4e9a4ce275c6cbf477d211344f468dbf Author: Dave Airlie <ai...@re...> Date: Mon Jul 16 02:51:37 2012 +0100 libdrm/nouveau: add prime handle->bo and bo->handle support. This adds prime support to nouveau libdrm. Signed-off-by: Dave Airlie <ai...@re...> 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; commit cc0a14575d9fd0aafe73cb4aa445eaf024436114 Author: Dave Airlie <ai...@gm...> Date: Sat Jul 14 09:52:17 2012 +0000 libdrm: add prime fd->handle and handle->fd interfaces These are just basic ioctl wrappers around the prime ioctls, along with the capability reporting. Reviewed-by: Alex Deucher <ale...@am...> Signed-off-by: Dave Airlie <ai...@re...> diff --git a/include/drm/drm.h b/include/drm/drm.h index 42133bc..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) @@ -778,6 +778,10 @@ struct drm_event_vblank { #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/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 commit 41dfb20cdc369bb0da880c371a664f25fe665adb Author: Dave Airlie <ai...@gm...> Date: Sat Jul 14 09:52:16 2012 +0000 libdrm: add missing caps from kernel to drm.h This just moves over some missing caps from the kernel. Signed-off-by: Dave Airlie <ai...@re...> Reviewed-by: Alex Deucher <ale...@am...> diff --git a/include/drm/drm.h b/include/drm/drm.h index 5e6cd29..42133bc 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -776,6 +776,8 @@ 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 /* typedef area */ typedef struct drm_clip_rect drm_clip_rect_t; |