Mesa (main): zink: add back kms handling
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sat Jun 4 01:48:26 UTC 2022
Module: Mesa
Branch: main
Commit: b0fe621459c1b02b658f05ebbaba3ca68a7830de
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b0fe621459c1b02b658f05ebbaba3ca68a7830de
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Wed Jun 1 11:31:28 2022 -0400
zink: add back kms handling
removing this broke the ability to create system compositors
rework it a bit though so that kms handles are stored and destroyed
when the bo is freed
Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16815>
---
src/gallium/drivers/zink/meson.build | 2 +-
src/gallium/drivers/zink/zink_bo.c | 64 ++++++++++++++++++++++++++++----
src/gallium/drivers/zink/zink_bo.h | 14 +++++++
src/gallium/drivers/zink/zink_resource.c | 15 +++++++-
src/gallium/drivers/zink/zink_screen.h | 2 -
5 files changed, 85 insertions(+), 12 deletions(-)
diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build
index 78975f90e93..4621e7f983e 100644
--- a/src/gallium/drivers/zink/meson.build
+++ b/src/gallium/drivers/zink/meson.build
@@ -92,7 +92,7 @@ libzink = static_library(
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_vulkan_util, inc_zink_vk],
dependencies: [
idep_nir_headers, idep_mesautil, idep_vulkan_util_headers,
- idep_vulkan_wsi_headers, idep_vulkan_util
+ idep_vulkan_wsi_headers, idep_vulkan_util, dep_libdrm
],
c_args: zink_c_args,
)
diff --git a/src/gallium/drivers/zink/zink_bo.c b/src/gallium/drivers/zink/zink_bo.c
index 5afa5ec413e..d4b48d1b518 100644
--- a/src/gallium/drivers/zink/zink_bo.c
+++ b/src/gallium/drivers/zink/zink_bo.c
@@ -34,6 +34,11 @@
#include "zink_screen.h"
#include "util/u_hash_table.h"
+#if !defined(__APPLE__) && !defined(_WIN32)
+#define ZINK_USE_DMABUF
+#include <xf86drm.h>
+#endif
+
struct zink_bo;
struct zink_sparse_backing_chunk {
@@ -120,9 +125,19 @@ bo_destroy(struct zink_screen *screen, struct pb_buffer *pbuf)
{
struct zink_bo *bo = zink_bo(pbuf);
- simple_mtx_lock(&screen->pb.bo_export_table_lock);
- _mesa_hash_table_remove_key(screen->pb.bo_export_table, bo);
- simple_mtx_unlock(&screen->pb.bo_export_table_lock);
+#ifdef ZINK_USE_DMABUF
+ if (!bo->u.real.use_reusable_pool) {
+ simple_mtx_lock(&bo->u.real.export_lock);
+ list_for_each_entry_safe(struct bo_export, export, &bo->u.real.exports, link) {
+ struct drm_gem_close args = { .handle = export->gem_handle };
+ drmIoctl(export->drm_fd, DRM_IOCTL_GEM_CLOSE, &args);
+ list_del(&export->link);
+ free(export);
+ }
+ simple_mtx_unlock(&bo->u.real.export_lock);
+ simple_mtx_destroy(&bo->u.real.export_lock);
+ }
+#endif
if (!bo->u.real.is_user_ptr && bo->u.real.cpu_ptr) {
bo->u.real.map_count = 1;
@@ -282,6 +297,11 @@ demote:
if (init_pb_cache) {
bo->u.real.use_reusable_pool = true;
pb_cache_init_entry(&screen->pb.bo_cache, bo->cache_entry, &bo->base, heap);
+ } else {
+#ifdef ZINK_USE_DMABUF
+ list_inithead(&bo->u.real.exports);
+ simple_mtx_init(&bo->u.real.export_lock, mtx_plain);
+#endif
}
@@ -1065,6 +1085,40 @@ out:
return ok;
}
+bool
+zink_bo_get_kms_handle(struct zink_screen *screen, struct zink_bo *bo, int fd, uint32_t *handle)
+{
+#ifdef ZINK_USE_DMABUF
+ assert(bo->mem && !bo->u.real.use_reusable_pool);
+ simple_mtx_lock(&bo->u.real.export_lock);
+ list_for_each_entry(struct bo_export, export, &bo->u.real.exports, link) {
+ if (export->drm_fd == fd) {
+ simple_mtx_unlock(&bo->u.real.export_lock);
+ *handle = export->gem_handle;
+ return true;
+ }
+ }
+ struct bo_export *export = CALLOC_STRUCT(bo_export);
+ if (!export) {
+ simple_mtx_unlock(&bo->u.real.export_lock);
+ return false;
+ }
+ bool success = drmPrimeFDToHandle(screen->drm_fd, fd, handle) == 0;
+ if (success) {
+ list_addtail(&export->link, &bo->u.real.exports);
+ export->gem_handle = *handle;
+ export->drm_fd = screen->drm_fd;
+ } else {
+ mesa_loge("zink: failed drmPrimeFDToHandle %s", strerror(errno));
+ FREE(export);
+ }
+ simple_mtx_unlock(&bo->u.real.export_lock);
+ return success;
+#else
+ return false;
+#endif
+}
+
static const struct pb_vtbl bo_slab_vtbl = {
/* Cast to void* because one of the function parameters is a struct pointer instead of void*. */
(void*)bo_slab_destroy
@@ -1214,8 +1268,6 @@ zink_bo_init(struct zink_screen *screen)
min_slab_order = max_order + 1;
}
screen->pb.min_alloc_size = 1 << screen->pb.bo_slabs[0].min_order;
- screen->pb.bo_export_table = util_hash_table_create_ptr_keys();
- simple_mtx_init(&screen->pb.bo_export_table_lock, mtx_plain);
return true;
}
@@ -1227,6 +1279,4 @@ zink_bo_deinit(struct zink_screen *screen)
pb_slabs_deinit(&screen->pb.bo_slabs[i]);
}
pb_cache_deinit(&screen->pb.bo_cache);
- _mesa_hash_table_destroy(screen->pb.bo_export_table, NULL);
- simple_mtx_destroy(&screen->pb.bo_export_table_lock);
}
diff --git a/src/gallium/drivers/zink/zink_bo.h b/src/gallium/drivers/zink/zink_bo.h
index 82cedb170d4..19215a4bdc0 100644
--- a/src/gallium/drivers/zink/zink_bo.h
+++ b/src/gallium/drivers/zink/zink_bo.h
@@ -55,6 +55,15 @@ enum zink_alloc_flag {
ZINK_ALLOC_NO_SUBALLOC = 1<<1,
};
+struct bo_export {
+ /** File descriptor associated with a handle export. */
+ int drm_fd;
+
+ /** GEM handle in drm_fd */
+ uint32_t gem_handle;
+
+ struct list_head link;
+};
struct zink_bo {
struct pb_buffer base;
@@ -63,6 +72,8 @@ struct zink_bo {
struct {
void *cpu_ptr; /* for user_ptr and permanent maps */
int map_count;
+ struct list_head exports;
+ simple_mtx_t export_lock;
bool is_user_ptr;
bool use_reusable_pool;
@@ -175,6 +186,9 @@ zink_bo_deinit(struct zink_screen *screen);
struct pb_buffer *
zink_bo_create(struct zink_screen *screen, uint64_t size, unsigned alignment, enum zink_heap heap, enum zink_alloc_flag flags, const void *pNext);
+bool
+zink_bo_get_kms_handle(struct zink_screen *screen, struct zink_bo *bo, int fd, uint32_t *handle);
+
static inline uint64_t
zink_bo_get_offset(const struct zink_bo *bo)
{
diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c
index 2645450cfe7..6decdd6fefa 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -1299,14 +1299,16 @@ zink_resource_get_param(struct pipe_screen *pscreen, struct pipe_context *pctx,
break;
}
- case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS:
return false;
+ case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS:
case PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED:
case PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD: {
#ifdef ZINK_USE_DMABUF
memset(&whandle, 0, sizeof(whandle));
if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED)
whandle.type = WINSYS_HANDLE_TYPE_SHARED;
+ if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS)
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
else if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD)
whandle.type = WINSYS_HANDLE_TYPE_FD;
@@ -1342,7 +1344,7 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
struct zink_resource_object *obj = res->obj;
#if !defined(_WIN32)
- if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
+ if (whandle->type == WINSYS_HANDLE_TYPE_KMS && screen->drm_fd == -1) {
whandle->handle = -1;
} else {
if (!res->obj->exportable) {
@@ -1368,6 +1370,15 @@ zink_resource_get_handle(struct pipe_screen *pscreen,
mesa_loge("ZINK: vkGetMemoryFdKHR failed");
return false;
}
+ if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
+ uint32_t h;
+ bool ret = zink_bo_get_kms_handle(screen, obj->bo, fd, &h);
+ close(fd);
+ if (!ret)
+ return false;
+ fd = h;
+ }
+
whandle->handle = fd;
}
#else
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 142c127f3c5..bbc98f0a981 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -128,8 +128,6 @@ struct zink_screen {
struct pb_cache bo_cache;
struct pb_slabs bo_slabs[NUM_SLAB_ALLOCATORS];
unsigned min_alloc_size;
- struct hash_table *bo_export_table;
- simple_mtx_t bo_export_table_lock;
uint32_t next_bo_unique_id;
} pb;
uint8_t heap_map[VK_MAX_MEMORY_TYPES];
More information about the mesa-commit
mailing list