freedreno: add dmabuf import/export helpers
authorRob Clark <robclark@freedesktop.org>
Tue, 16 Sep 2014 20:26:50 +0000 (16:26 -0400)
committerRob Clark <robclark@freedesktop.org>
Mon, 22 Sep 2014 02:16:37 +0000 (22:16 -0400)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
freedreno/freedreno_bo.c
freedreno/freedreno_drmif.h
freedreno/freedreno_priv.h

index 3a2e464..b90fc56 100644 (file)
@@ -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;
index 7c54e04..88fc03d 100644 (file)
@@ -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);
index 416a3b3..b204e53 100644 (file)
@@ -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;