From e76b1acbfecebb9cfc39b72fe55ca141114797a9 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 5 Nov 2024 11:56:52 -0800 Subject: [PATCH] util: Add drmSyncobj shim Signed-off-by: Rob Clark Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Part-of: --- src/util/meson.build | 5 ++ src/util/u_sync_provider.c | 142 +++++++++++++++++++++++++++++++++++++ src/util/u_sync_provider.h | 53 ++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 src/util/u_sync_provider.c create mode 100644 src/util/u_sync_provider.h diff --git a/src/util/meson.build b/src/util/meson.build index e1be8c54999..1fd00c38428 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -238,6 +238,11 @@ deps_for_libmesa_util = [ idep_mesautilformat, ] +if dep_libdrm.found() + files_mesa_util += files('u_sync_provider.c', 'u_sync_provider.h') + deps_for_libmesa_util += dep_libdrm +endif + if with_platform_android deps_for_libmesa_util += dep_android files_debug_stack = files('u_debug_stack_android.cpp') diff --git a/src/util/u_sync_provider.c b/src/util/u_sync_provider.c new file mode 100644 index 00000000000..e002080d7d4 --- /dev/null +++ b/src/util/u_sync_provider.c @@ -0,0 +1,142 @@ +/* + * Copyright © 2024 Google, Inc. + * SPDX-License-Identifier: MIT + */ + +#include "util/u_memory.h" +#include "util/u_sync_provider.h" +#include + +struct util_sync_provider_drm { + struct util_sync_provider base; + int drm_fd; +}; + +static int +drm_fd(struct util_sync_provider *p) +{ + struct util_sync_provider_drm *d = (struct util_sync_provider_drm *)p; + return d->drm_fd; +} + +static int +drm_syncobj_create(struct util_sync_provider *p, uint32_t flags, uint32_t *handle) +{ + return drmSyncobjCreate(drm_fd(p), flags, handle); +} + +static int +drm_syncobj_destroy(struct util_sync_provider *p, uint32_t handle) +{ + return drmSyncobjDestroy(drm_fd(p), handle); +} + +static int +drm_syncobj_handle_to_fd(struct util_sync_provider *p, uint32_t handle, int *out_obj_fd) +{ + return drmSyncobjHandleToFD(drm_fd(p), handle, out_obj_fd); +} + +static int +drm_syncobj_fd_to_handle(struct util_sync_provider *p, int obj_fd, uint32_t *handle) +{ + return drmSyncobjFDToHandle(drm_fd(p), obj_fd, handle); +} + +static int +drm_syncobj_import_sync_file(struct util_sync_provider *p, uint32_t handle, int sync_file_fd) +{ + return drmSyncobjImportSyncFile(drm_fd(p), handle, sync_file_fd); +} + +static int +drm_syncobj_export_sync_file(struct util_sync_provider *p, uint32_t handle, int *out_sync_file_fd) +{ + return drmSyncobjExportSyncFile(drm_fd(p), handle, out_sync_file_fd); +} + +static int +drm_syncobj_wait(struct util_sync_provider *p, uint32_t *handles, unsigned num_handles, + int64_t timeout_nsec, unsigned flags, uint32_t *first_signaled) +{ + return drmSyncobjWait(drm_fd(p), handles, num_handles, timeout_nsec, flags, first_signaled); +} + +static int +drm_syncobj_reset(struct util_sync_provider *p, const uint32_t *handles, uint32_t handle_count) +{ + return drmSyncobjReset(drm_fd(p), handles, handle_count); +} + +static int +drm_syncobj_signal(struct util_sync_provider *p, const uint32_t *handles, uint32_t handle_count) +{ + return drmSyncobjSignal(drm_fd(p), handles, handle_count); +} + +static int +drm_syncobj_timeline_signal(struct util_sync_provider *p, const uint32_t *handles, + uint64_t *points, uint32_t handle_count) +{ + return drmSyncobjTimelineSignal(drm_fd(p), handles, points, handle_count); +} + +static int +drm_syncobj_timeline_wait(struct util_sync_provider *p, uint32_t *handles, uint64_t *points, + unsigned num_handles, int64_t timeout_nsec, unsigned flags, + uint32_t *first_signaled) +{ + return drmSyncobjTimelineWait(drm_fd(p), handles, points, num_handles, timeout_nsec, flags, first_signaled); +} + +static int +drm_syncobj_query(struct util_sync_provider *p, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags) +{ + return drmSyncobjQuery2(drm_fd(p), handles, points, handle_count, flags); +} + +static int +drm_syncobj_transfer(struct util_sync_provider *p, uint32_t dst_handle, uint64_t dst_point, + uint32_t src_handle, uint64_t src_point, uint32_t flags) +{ + return drmSyncobjTransfer(drm_fd(p), dst_handle, dst_point, src_handle, src_point, flags); +} + +static void +drm_syncobj_finalize(struct util_sync_provider *p) +{ + free(p); +} + + +struct util_sync_provider * +util_sync_provider_drm(int drm_fd) +{ + struct util_sync_provider_drm *d = CALLOC_STRUCT(util_sync_provider_drm); + + d->drm_fd = drm_fd; + d->base = (struct util_sync_provider) { + .create = drm_syncobj_create, + .destroy = drm_syncobj_destroy, + .handle_to_fd = drm_syncobj_handle_to_fd, + .fd_to_handle = drm_syncobj_fd_to_handle, + .import_sync_file = drm_syncobj_import_sync_file, + .export_sync_file = drm_syncobj_export_sync_file, + .wait = drm_syncobj_wait, + .reset = drm_syncobj_reset, + .signal = drm_syncobj_signal, + .query = drm_syncobj_query, + .transfer = drm_syncobj_transfer, + .finalize = drm_syncobj_finalize, + }; + + uint64_t cap; + int err = drmGetCap(drm_fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap); + if (err == 0 && cap != 0) { + d->base.timeline_signal = drm_syncobj_timeline_signal; + d->base.timeline_wait = drm_syncobj_timeline_wait; + } + + return &d->base; +} diff --git a/src/util/u_sync_provider.h b/src/util/u_sync_provider.h new file mode 100644 index 00000000000..21c1f47f2cc --- /dev/null +++ b/src/util/u_sync_provider.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2024 Google, Inc. + * SPDX-License-Identifier: MIT + */ + +#include + +#ifndef U_SYNC_PROVIDER_H +#define U_SYNC_PROVIDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct util_sync_provider { + int (*create)(struct util_sync_provider *p, uint32_t flags, uint32_t *handle); + int (*destroy)(struct util_sync_provider *p, uint32_t handle); + int (*handle_to_fd)(struct util_sync_provider *p, uint32_t handle, int *out_obj_fd); + int (*fd_to_handle)(struct util_sync_provider *p, int obj_fd, uint32_t *handle); + int (*import_sync_file)(struct util_sync_provider *p, uint32_t handle, int sync_file_fd); + int (*export_sync_file)(struct util_sync_provider *p, uint32_t handle, int *out_sync_file_fd); + int (*wait)(struct util_sync_provider *p, uint32_t *handles, unsigned num_handles, + int64_t timeout_nsec, unsigned flags, uint32_t *first_signaled); + int (*reset)(struct util_sync_provider *p, const uint32_t *handles, uint32_t handle_count); + int (*signal)(struct util_sync_provider *p, const uint32_t *handles, uint32_t handle_count); + int (*timeline_signal)(struct util_sync_provider *p, const uint32_t *handles, + uint64_t *points, uint32_t handle_count); + int (*timeline_wait)(struct util_sync_provider *p, uint32_t *handles, uint64_t *points, + unsigned num_handles, int64_t timeout_nsec, unsigned flags, + uint32_t *first_signaled); + int (*query)(struct util_sync_provider *p, uint32_t *handles, uint64_t *points, + uint32_t handle_count, uint32_t flags); + int (*transfer)(struct util_sync_provider *p, uint32_t dst_handle, uint64_t dst_point, + uint32_t src_handle, uint64_t src_point, uint32_t flags); + + void (*finalize)(struct util_sync_provider *p); +}; + +#if HAVE_LIBDRM +struct util_sync_provider * util_sync_provider_drm(int drm_fd); +#else +static inline struct util_sync_provider * +util_sync_provider_drm(int drm_fd) +{ + return NULL; +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* U_SYNC_PROVIDER_H */