diff options
author | Rob Clark <robclark@freedesktop.org> | 2014-09-16 16:26:50 -0400 |
---|---|---|
committer | Rob Clark <robclark@freedesktop.org> | 2014-09-21 22:16:37 -0400 |
commit | 666788a6062de62aa0b3560760fbb0903167a319 (patch) | |
tree | c393c7f8e6fb3c6065455aac4e65e6d3995f7e80 /freedreno | |
parent | 77dce9a012c2bb9d152fe32458f17d3d5fc715a7 (diff) |
freedreno: add dmabuf import/export helpers
Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'freedreno')
-rw-r--r-- | freedreno/freedreno_bo.c | 43 | ||||
-rw-r--r-- | freedreno/freedreno_drmif.h | 2 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 1 |
3 files changed, 46 insertions, 0 deletions
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c index 3a2e4649282e..b90fc5679648 100644 --- a/freedreno/freedreno_bo.c +++ b/freedreno/freedreno_bo.c @@ -209,6 +209,25 @@ fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) return bo; } +drm_public struct fd_bo * +fd_bo_from_dmabuf(struct fd_device *dev, int fd) +{ + struct drm_prime_handle req = { + .fd = fd, + }; + int ret, size; + + ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req); + if (ret) { + return NULL; + } + + /* hmm, would be nice if we had a way to figure out the size.. */ + size = 0; + + return fd_bo_from_handle(dev, req.handle, size); +} + drm_public struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name) { struct drm_gem_open req = { @@ -255,6 +274,11 @@ drm_public void fd_bo_del(struct fd_bo *bo) if (!atomic_dec_and_test(&bo->refcnt)) return; + if (bo->fd) { + close(bo->fd); + bo->fd = 0; + } + pthread_mutex_lock(&table_lock); if (bo->bo_reuse) { @@ -335,6 +359,25 @@ drm_public uint32_t fd_bo_handle(struct fd_bo *bo) return bo->handle; } +drm_public int fd_bo_dmabuf(struct fd_bo *bo) +{ + if (!bo->fd) { + struct drm_prime_handle req = { + .handle = bo->handle, + .flags = DRM_CLOEXEC, + }; + int ret; + + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req); + if (ret) { + return ret; + } + + bo->fd = req.fd; + } + return dup(bo->fd); +} + drm_public uint32_t fd_bo_size(struct fd_bo *bo) { return bo->size; diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h index 7c54e04b90e8..88fc03ded9dd 100644 --- a/freedreno/freedreno_drmif.h +++ b/freedreno/freedreno_drmif.h @@ -98,10 +98,12 @@ struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, struct fd_bo *fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size); struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); +struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); struct fd_bo * fd_bo_ref(struct fd_bo *bo); void fd_bo_del(struct fd_bo *bo); int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); uint32_t fd_bo_handle(struct fd_bo *bo); +int fd_bo_dmabuf(struct fd_bo *bo); uint32_t fd_bo_size(struct fd_bo *bo); void * fd_bo_map(struct fd_bo *bo); int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 416a3b3cf862..b204e5344bd0 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -139,6 +139,7 @@ struct fd_bo { uint32_t size; uint32_t handle; uint32_t name; + int fd; /* dmabuf handle */ void *map; atomic_t refcnt; struct fd_bo_funcs *funcs; |