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@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16815>
This commit is contained in:
Mike Blumenkrantz 2022-06-01 11:31:28 -04:00 committed by Marge Bot
parent b4ef984ef3
commit b0fe621459
5 changed files with 85 additions and 12 deletions

View File

@ -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,
)

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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

View File

@ -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];