From 1fd381c38e0262b46ff2b35a6eb59aabe78c069a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 17 Mar 2011 11:28:05 +1000 Subject: drm: add prime support --- include/drm/drm.h | 12 ++++++++++++ intel/intel_bufmgr.h | 2 ++ intel/intel_bufmgr_gem.c | 18 ++++++++++++++++++ nouveau/nouveau_bo.c | 27 +++++++++++++++++++++++++++ nouveau/nouveau_bo.h | 4 ++++ radeon/radeon_bo.h | 2 ++ radeon/radeon_bo_gem.c | 10 +++++++++- xf86drm.c | 29 +++++++++++++++++++++++++++++ xf86drm.h | 3 ++- 9 files changed, 105 insertions(+), 2 deletions(-) diff --git a/include/drm/drm.h b/include/drm/drm.h index 416673af..0578a63b 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -618,6 +618,15 @@ struct drm_get_cap { __u64 value; }; +struct drm_prime_handle { + /** Handle for object */ + __u32 handle; + + /* prime name */ + __u32 name; +}; + + #include "drm_mode.h" #define DRM_IOCTL_BASE 'd' @@ -674,6 +683,9 @@ struct drm_get_cap { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) +#define DRM_IOCTL_PRIME_SET DRM_IOWR(0x2d, struct drm_prime_handle) +#define DRM_IOCTL_PRIME_GET 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) diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h index daa18b4c..6bd917ca 100644 --- a/intel/intel_bufmgr.h +++ b/intel/intel_bufmgr.h @@ -223,6 +223,8 @@ void drm_intel_bufmgr_fake_evict_all(drm_intel_bufmgr *bufmgr); #define intel_bufmgr_fake_contended_lock_take drm_intel_bufmgr_fake_contended_lock_take #define intel_bufmgr_fake_evict_all drm_intel_bufmgr_fake_evict_all +void +drm_intel_bufmgr_gem_set_bo_prime(drm_intel_bo *bo, uint32_t *name); /** @{ */ #endif /* INTEL_BUFMGR_H */ diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index f5ab0a6f..cdf8ca5f 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -195,6 +195,8 @@ struct _drm_intel_bo_gem { * relocations. */ int reloc_tree_fences; + + unsigned int prime_name; }; static unsigned int @@ -1783,6 +1785,22 @@ drm_intel_gem_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode, return 0; } +void +drm_intel_bufmgr_gem_set_bo_prime(drm_intel_bo *bo, uint32_t *name) +{ + drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; + int ret; + + if (!bo_gem->prime_name) { + ret = drmPrimeBufferSet(bufmgr_gem->fd, bo_gem->gem_handle, &bo_gem->prime_name); + if (ret) { + fprintf(stderr,"drm PBS failed\n"); + } + } + *name = bo_gem->prime_name; +} + static int drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name) { diff --git a/nouveau/nouveau_bo.c b/nouveau/nouveau_bo.c index d6bb22de..e261f782 100644 --- a/nouveau/nouveau_bo.c +++ b/nouveau/nouveau_bo.c @@ -321,6 +321,33 @@ nouveau_bo_handle_ref(struct nouveau_device *dev, uint32_t handle, return 0; } + +int +nouveau_bo_prime_handle_ref(struct nouveau_device *dev, uint32_t prime_handle, + struct nouveau_bo **bo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_bo_priv *nvbo; + int ret; + unsigned int handle; + + ret = drmPrimeBufferGet(nvdev->fd, prime_handle, &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; + } + + nvbo = nouveau_bo(*bo); + nvbo->base.handle = nvbo->handle; + return 0; +} + static void nouveau_bo_del(struct nouveau_bo **bo) { diff --git a/nouveau/nouveau_bo.h b/nouveau/nouveau_bo.h index 3a1f2d4a..69c6d662 100644 --- a/nouveau/nouveau_bo.h +++ b/nouveau/nouveau_bo.h @@ -79,6 +79,10 @@ int nouveau_bo_handle_ref(struct nouveau_device *, uint32_t handle, struct nouveau_bo **); +int +nouveau_bo_prime_handle_ref(struct nouveau_device *dev, uint32_t prime_handle, + struct nouveau_bo **bo); + int nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **); diff --git a/radeon/radeon_bo.h b/radeon/radeon_bo.h index 37478a0d..7d93ed1b 100644 --- a/radeon/radeon_bo.h +++ b/radeon/radeon_bo.h @@ -38,6 +38,8 @@ #define RADEON_BO_FLAGS_MICRO_TILE 2 #define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20 +#define RADEON_BO_FLAGS_SLAVE 0x80 + struct radeon_bo_manager; struct radeon_cs; diff --git a/radeon/radeon_bo_gem.c b/radeon/radeon_bo_gem.c index 719fba7c..92161475 100644 --- a/radeon/radeon_bo_gem.c +++ b/radeon/radeon_bo_gem.c @@ -84,7 +84,15 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, bo->base.ptr = NULL; atomic_set(&bo->reloc_in_cs, 0); bo->map_count = 0; - if (handle) { + if (flags & RADEON_BO_FLAGS_SLAVE) { + r = drmPrimeBufferGet(bom->fd, handle, &bo->base.handle); + if (r != 0) { + fprintf(stderr,"failed to get prime slave buffer %d\n", handle); + free(bo); + return NULL; + } + } + else if (handle) { struct drm_gem_open open_arg; memset(&open_arg, 0, sizeof(open_arg)); diff --git a/xf86drm.c b/xf86drm.c index a183eee9..aa23f406 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2542,3 +2542,32 @@ char *drmGetDeviceNameFromFd(int fd) return strdup(name); } + +int drmPrimeBufferSet(int fd, uint32_t handle, uint32_t *name) +{ + struct drm_prime_handle args; + int ret; + + args.handle = handle; + ret = drmIoctl(fd, DRM_IOCTL_PRIME_SET, &args); + if (ret) + return ret; + + *name = args.name; + return 0; +} + +int drmPrimeBufferGet(int fd, uint32_t name, uint32_t *handle) +{ + struct drm_prime_handle args; + int ret; + + args.name = name; + ret = drmIoctl(fd, DRM_IOCTL_PRIME_GET, &args); + if (ret) + return ret; + + *handle = args.handle; + return 0; +} + diff --git a/xf86drm.h b/xf86drm.h index bf0d5df8..a7e88673 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -719,5 +719,6 @@ typedef struct _drmEventContext { extern int drmHandleEvent(int fd, drmEventContextPtr evctx); extern char *drmGetDeviceNameFromFd(int fd); - +extern int drmPrimeBufferSet(int fd, uint32_t handle, uint32_t *name); +extern int drmPrimeBufferGet(int fd, uint32_t name, uint32_t *handle); #endif -- cgit v1.2.3