Mesa (main): crocus: hook up memory object creation from handle
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 00:13:26 UTC 2021
Module: Mesa
Branch: main
Commit: 8bf662df52aeb42b1f9852d2ae66ee1dea4694e1
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8bf662df52aeb42b1f9852d2ae66ee1dea4694e1
Author: Dave Airlie <airlied at gmail.com>
Date: Mon Jun 14 12:27:49 2021 +1000
crocus: hook up memory object creation from handle
Port cdb5a727644e9fd0195519f81ce34f79a99ae432 from iris
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11352>
---
src/gallium/drivers/crocus/crocus_bufmgr.c | 53 +++++++++++++++++++++++
src/gallium/drivers/crocus/crocus_bufmgr.h | 2 +
src/gallium/drivers/crocus/crocus_resource.c | 63 ++++++++++++++++++++++++++++
src/gallium/drivers/crocus/crocus_resource.h | 8 ++++
4 files changed, 126 insertions(+)
diff --git a/src/gallium/drivers/crocus/crocus_bufmgr.c b/src/gallium/drivers/crocus/crocus_bufmgr.c
index e013cbf9854..c0f87116a40 100644
--- a/src/gallium/drivers/crocus/crocus_bufmgr.c
+++ b/src/gallium/drivers/crocus/crocus_bufmgr.c
@@ -1289,6 +1289,59 @@ err:
return NULL;
}
+struct crocus_bo *
+crocus_bo_import_dmabuf_no_mods(struct crocus_bufmgr *bufmgr,
+ int prime_fd)
+{
+ uint32_t handle;
+ struct crocus_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 = 0;
+ bo->gem_handle = handle;
+ _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo);
+
+out:
+ mtx_unlock(&bufmgr->lock);
+ return bo;
+}
+
static void
crocus_bo_make_external_locked(struct crocus_bo *bo)
{
diff --git a/src/gallium/drivers/crocus/crocus_bufmgr.h b/src/gallium/drivers/crocus/crocus_bufmgr.h
index 21595e8117a..0ec2af5bc69 100644
--- a/src/gallium/drivers/crocus/crocus_bufmgr.h
+++ b/src/gallium/drivers/crocus/crocus_bufmgr.h
@@ -307,6 +307,8 @@ void crocus_destroy_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);
int crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd);
struct crocus_bo *crocus_bo_import_dmabuf(struct crocus_bufmgr *bufmgr,
int prime_fd, uint64_t modifier);
+struct crocus_bo *crocus_bo_import_dmabuf_no_mods(struct crocus_bufmgr *bufmgr,
+ int prime_fd);
/**
* Exports a bo as a GEM handle into a given DRM file descriptor
diff --git a/src/gallium/drivers/crocus/crocus_resource.c b/src/gallium/drivers/crocus/crocus_resource.c
index cc3f6a4f583..f6f828c13ff 100644
--- a/src/gallium/drivers/crocus/crocus_resource.c
+++ b/src/gallium/drivers/crocus/crocus_resource.c
@@ -43,6 +43,7 @@
#include "util/u_transfer_helper.h"
#include "util/u_upload_mgr.h"
#include "util/ralloc.h"
+#include "util/u_memory.h"
#include "crocus_batch.h"
#include "crocus_context.h"
#include "crocus_resource.h"
@@ -1889,6 +1890,66 @@ crocus_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier
return util_format_get_num_planes(format);
}
+static struct pipe_memory_object *
+crocus_memobj_create_from_handle(struct pipe_screen *pscreen,
+ struct winsys_handle *whandle,
+ bool dedicated)
+{
+ struct crocus_screen *screen = (struct crocus_screen *)pscreen;
+ struct crocus_memory_object *memobj = CALLOC_STRUCT(crocus_memory_object);
+ struct crocus_bo *bo;
+ const struct isl_drm_modifier_info *mod_inf;
+
+ if (!memobj)
+ return NULL;
+
+ switch (whandle->type) {
+ case WINSYS_HANDLE_TYPE_SHARED:
+ bo = crocus_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 = crocus_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 = crocus_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;
+
+ crocus_bo_reference(memobj->bo);
+
+ return &memobj->b;
+}
+
+static void
+crocus_memobj_destroy(struct pipe_screen *pscreen,
+ struct pipe_memory_object *pmemobj)
+{
+ struct crocus_memory_object *memobj = (struct crocus_memory_object *)pmemobj;
+
+ crocus_bo_unreference(memobj->bo);
+ free(memobj);
+}
+
void
crocus_init_screen_resource_functions(struct pipe_screen *pscreen)
{
@@ -1904,6 +1965,8 @@ crocus_init_screen_resource_functions(struct pipe_screen *pscreen)
pscreen->resource_get_handle = crocus_resource_get_handle;
pscreen->resource_get_param = crocus_resource_get_param;
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
+ pscreen->memobj_create_from_handle = crocus_memobj_create_from_handle;
+ pscreen->memobj_destroy = crocus_memobj_destroy;
pscreen->transfer_helper =
u_transfer_helper_create(&transfer_vtbl, screen->devinfo.ver >= 6,
screen->devinfo.ver >= 6, false, true);
diff --git a/src/gallium/drivers/crocus/crocus_resource.h b/src/gallium/drivers/crocus/crocus_resource.h
index 8eb49118f54..86ccb25e79d 100644
--- a/src/gallium/drivers/crocus/crocus_resource.h
+++ b/src/gallium/drivers/crocus/crocus_resource.h
@@ -282,6 +282,14 @@ struct crocus_transfer {
void (*unmap)(struct crocus_transfer *);
};
+/**
+ * Memory Object
+ */
+struct crocus_memory_object {
+ struct pipe_memory_object b;
+ struct crocus_bo *bo;
+};
+
/**
* Unwrap a pipe_resource to get the underlying crocus_bo (for convenience).
*/
More information about the mesa-commit
mailing list