Mesa (master): iris: hook up memory object creation from handle

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 20 14:11:14 UTC 2021


Module: Mesa
Branch: master
Commit: cdb5a727644e9fd0195519f81ce34f79a99ae432
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cdb5a727644e9fd0195519f81ce34f79a99ae432

Author: Juan A. Suarez Romero <jasuarez at igalia.com>
Date:   Thu Mar 26 16:16:25 2020 +0100

iris: hook up memory object creation from handle

v2: use iris_bo_import_dmabuf (Tapani)
v3: included "util/u_memory.h" to fixed compilation errors caused by
    using the CALLOC_STRUCT macro
v4: implemented iris_memobj_destroy (pscreen->memobj_destroy) callback
v5: removed iris_bo_from_handle and changed the approach for setting the
    tiling: Instead of querying the kernel and call
    iris_bo_import_dmabuf to create the bo, we call
    iris_bo_import_dmabuf_no_mods that imports the bo but without
    setting the tiling mode. We are going to update it when we create
    the resource. Also: implemented the iris_bo_import_dmabuf_no_mods.
v6: rebase to iris_bo_import_dmabuf changes and take a reference
    to memobj->bo (Tapani Pälli)

Signed-off-by: Juan A. Suarez Romero <jasuarez at igalia.com>
Signed-off-by: Eleni Maria Stea <estea at igalia.com>
Co-authored-by: Eleni Maria Stea <estea at igalia.com>
Reviewed-by: Rohan Garg <rohan.garg at collabora.com>
Reviewed-by: Tapani Pälli <tapani.palli at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4337>

---

 src/gallium/drivers/iris/iris_bufmgr.c   | 54 +++++++++++++++++++++++++++
 src/gallium/drivers/iris/iris_bufmgr.h   |  3 ++
 src/gallium/drivers/iris/iris_resource.c | 63 ++++++++++++++++++++++++++++++++
 src/gallium/drivers/iris/iris_resource.h |  8 ++++
 4 files changed, 128 insertions(+)

diff --git a/src/gallium/drivers/iris/iris_bufmgr.c b/src/gallium/drivers/iris/iris_bufmgr.c
index 24fcb22cb36..d3f8295de97 100644
--- a/src/gallium/drivers/iris/iris_bufmgr.c
+++ b/src/gallium/drivers/iris/iris_bufmgr.c
@@ -1480,6 +1480,60 @@ err:
    return NULL;
 }
 
+struct iris_bo *
+iris_bo_import_dmabuf_no_mods(struct iris_bufmgr *bufmgr,
+                              int prime_fd)
+{
+   uint32_t handle;
+   struct iris_bo *bo;
+
+   mtx_lock(&bufmgr->lock);
+   int ret = drmPrimeFDToHandle(bufmgr->fd, prime_fd, &handle);
+   if (ret) {
+      DBG("import_dmabuf: failed to obtain handle from fd: %s\n",
+          strerror(errno));
+      mtx_unlock(&bufmgr->lock);
+      return NULL;
+   }
+
+   /*
+    * See if the kernel has already returned this buffer to us. Just as
+    * for named buffers, we must not create two bo's pointing at the same
+    * kernel object
+    */
+   bo = find_and_ref_external_bo(bufmgr->handle_table, handle);
+   if (bo)
+      goto out;
+
+   bo = bo_calloc();
+   if (!bo)
+      goto out;
+
+   p_atomic_set(&bo->refcount, 1);
+
+   /* Determine size of bo.  The fd-to-handle ioctl really should
+    * return the size, but it doesn't.  If we have kernel 3.12 or
+    * later, we can lseek on the prime fd to get the size.  Older
+    * kernels will just fail, in which case we fall back to the
+    * provided (estimated or guess size). */
+   ret = lseek(prime_fd, 0, SEEK_END);
+   if (ret != -1)
+      bo->size = ret;
+
+   bo->bufmgr = bufmgr;
+   bo->name = "prime";
+   bo->reusable = false;
+   bo->external = true;
+   bo->kflags = EXEC_OBJECT_SUPPORTS_48B_ADDRESS | EXEC_OBJECT_PINNED;
+   bo->gtt_offset = vma_alloc(bufmgr, IRIS_MEMZONE_OTHER, bo->size, 1);
+   bo->gem_handle = handle;
+   _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
+
+out:
+   mtx_unlock(&bufmgr->lock);
+   return bo;
+}
+
 static void
 iris_bo_make_external_locked(struct iris_bo *bo)
 {
diff --git a/src/gallium/drivers/iris/iris_bufmgr.h b/src/gallium/drivers/iris/iris_bufmgr.h
index 91c03ab35e3..7991e3cbaac 100644
--- a/src/gallium/drivers/iris/iris_bufmgr.h
+++ b/src/gallium/drivers/iris/iris_bufmgr.h
@@ -410,6 +410,9 @@ struct iris_bo *iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd,
 int iris_bo_export_gem_handle_for_device(struct iris_bo *bo, int drm_fd,
                                          uint32_t *out_handle);
 
+struct iris_bo *iris_bo_import_dmabuf_no_mods(struct iris_bufmgr *bufmgr,
+                                              int prime_fd);
+
 uint32_t iris_bo_export_gem_handle(struct iris_bo *bo);
 
 int iris_reg_read(struct iris_bufmgr *bufmgr, uint32_t offset, uint64_t *out);
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 632085aeb46..95c4c1ee6cb 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -38,6 +38,7 @@
 #include "util/u_cpu_detect.h"
 #include "util/u_inlines.h"
 #include "util/format/u_format.h"
+#include "util/u_memory.h"
 #include "util/u_threaded_context.h"
 #include "util/u_transfer.h"
 #include "util/u_transfer_helper.h"
@@ -293,6 +294,66 @@ iris_image_view_get_format(struct iris_context *ice,
    return isl_fmt;
 }
 
+static struct pipe_memory_object *
+iris_memobj_create_from_handle(struct pipe_screen *pscreen,
+                               struct winsys_handle *whandle,
+                               bool dedicated)
+{
+   struct iris_screen *screen = (struct iris_screen *)pscreen;
+   struct iris_memory_object *memobj = CALLOC_STRUCT(iris_memory_object);
+   struct iris_bo *bo;
+   const struct isl_drm_modifier_info *mod_inf;
+
+   if (!memobj)
+      return NULL;
+
+   switch (whandle->type) {
+   case WINSYS_HANDLE_TYPE_SHARED:
+      bo = iris_bo_gem_create_from_name(screen->bufmgr, "winsys image",
+                                        whandle->handle);
+      break;
+   case WINSYS_HANDLE_TYPE_FD:
+      mod_inf = isl_drm_modifier_get_info(whandle->modifier);
+      if (mod_inf) {
+         bo = iris_bo_import_dmabuf(screen->bufmgr, whandle->handle,
+                                    whandle->modifier);
+      } else {
+         /* If we can't get information about the tiling from the
+          * kernel we ignore it. We are going to set it when we
+          * create the resource.
+          */
+         bo = iris_bo_import_dmabuf_no_mods(screen->bufmgr,
+                                            whandle->handle);
+      }
+
+      break;
+   default:
+      unreachable("invalid winsys handle type");
+   }
+
+   if (!bo) {
+      free(memobj);
+      return NULL;
+   }
+
+   memobj->b.dedicated = dedicated;
+   memobj->bo = bo;
+
+   iris_bo_reference(memobj->bo);
+
+   return &memobj->b;
+}
+
+static void
+iris_memobj_destroy(struct pipe_screen *pscreen,
+                    struct pipe_memory_object *pmemobj)
+{
+   struct iris_memory_object *memobj = (struct iris_memory_object *)pmemobj;
+
+   iris_bo_unreference(memobj->bo);
+   free(memobj);
+}
+
 struct pipe_resource *
 iris_resource_get_separate_stencil(struct pipe_resource *p_res)
 {
@@ -2289,6 +2350,8 @@ iris_init_screen_resource_functions(struct pipe_screen *pscreen)
    pscreen->resource_get_handle = iris_resource_get_handle;
    pscreen->resource_get_param = iris_resource_get_param;
    pscreen->resource_destroy = u_transfer_helper_resource_destroy;
+   pscreen->memobj_create_from_handle = iris_memobj_create_from_handle;
+   pscreen->memobj_destroy = iris_memobj_destroy;
    pscreen->transfer_helper =
       u_transfer_helper_create(&transfer_vtbl, true, true, false, true);
 }
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index caed44ab2ac..69867e0741e 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -277,6 +277,14 @@ struct iris_transfer {
    void (*unmap)(struct iris_transfer *);
 };
 
+/**
+ * Memory Object
+ */
+struct iris_memory_object {
+   struct pipe_memory_object b;
+   struct iris_bo *bo;
+};
+
 /**
  * Unwrap a pipe_resource to get the underlying iris_bo (for convenience).
  */



More information about the mesa-commit mailing list