From 666788a6062de62aa0b3560760fbb0903167a319 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 16 Sep 2014 16:26:50 -0400 Subject: freedreno: add dmabuf import/export helpers Signed-off-by: Rob Clark --- freedreno/freedreno_bo.c | 43 +++++++++++++++++++++++++++++++++++++++++++ freedreno/freedreno_drmif.h | 2 ++ freedreno/freedreno_priv.h | 1 + 3 files changed, 46 insertions(+) diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c index 3a2e4649..b90fc567 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 7c54e04b..88fc03de 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 416a3b3c..b204e534 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; -- cgit v1.2.3