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:
parent
b4ef984ef3
commit
b0fe621459
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue