summaryrefslogtreecommitdiff
path: root/src/sna/kgem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/kgem.c')
-rw-r--r--src/sna/kgem.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cb0c82a7..d68ad9f2 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2771,6 +2771,65 @@ struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
return bo;
}
+struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size)
+{
+#ifdef DRM_IOCTL_PRIME_FD_TO_HANDLE
+ struct drm_prime_handle args;
+ struct drm_i915_gem_get_tiling tiling;
+ struct kgem_bo *bo;
+
+ DBG(("%s(name=%d)\n", __FUNCTION__, name));
+
+ VG_CLEAR(args);
+ args.fd = name;
+ args.flags = 0;
+ if (drmIoctl(kgem->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args))
+ return NULL;
+
+ VG_CLEAR(tiling);
+ tiling.handle = args.handle;
+ if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) {
+ gem_close(kgem->fd, args.handle);
+ return NULL;
+ }
+
+ DBG(("%s: new handle=%d, tiling=%d\n", __FUNCTION__,
+ args.handle, tiling.tiling_mode));
+ bo = __kgem_bo_alloc(args.handle, NUM_PAGES(size));
+ if (bo == NULL) {
+ gem_close(kgem->fd, args.handle);
+ return NULL;
+ }
+
+ bo->tiling = tiling.tiling_mode;
+ bo->reusable = false;
+
+ debug_alloc__bo(kgem, bo);
+ return bo;
+#else
+ return NULL;
+#endif
+}
+
+int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo)
+{
+#ifdef DRM_IOCTL_PRIME_HANDLE_TO_PRIME
+ struct drm_prime_handle args;
+
+ VG_CLEAR(args);
+ args.handle = bo->handle;
+ args.flags = DRM_CLOEXEC;
+
+ if (drmIoctl(kgem->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
+ return -1;
+
+ bo->reusable = false;
+ return args.fd;
+#else
+ return -1;
+#endif
+}
+
struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags)
{
struct kgem_bo *bo;