/* * Copyright 2023 Intel Corporation * SPDX-License-Identifier: MIT */ #include "intel_bind_timeline.h" #include "drm-uapi/drm.h" #include "intel_gem.h" bool intel_bind_timeline_init(struct intel_bind_timeline *bind_timeline, int fd) { struct drm_syncobj_create syncobj_create = { .flags = DRM_SYNCOBJ_CREATE_SIGNALED }; if (intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create)) return false; simple_mtx_init(&bind_timeline->mutex, mtx_plain); bind_timeline->syncobj = syncobj_create.handle; bind_timeline->point = 0; return true; } void intel_bind_timeline_finish(struct intel_bind_timeline *bind_timeline, int fd) { if (bind_timeline->syncobj == 0) return; uint64_t point = intel_bind_timeline_get_last_point(bind_timeline); struct drm_syncobj_timeline_wait syncobj_wait = { .timeout_nsec = INT64_MAX, .handles = (uintptr_t)&bind_timeline->syncobj, .count_handles = 1, .points = (uintptr_t)&point, }; struct drm_syncobj_destroy syncobj_destroy = { .handle = bind_timeline->syncobj, }; /* Makes sure last unbind was signaled otherwise it can trigger job * timeouts in KMD */ intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &syncobj_wait); intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy); simple_mtx_destroy(&bind_timeline->mutex); } uint32_t intel_bind_timeline_get_syncobj(struct intel_bind_timeline *bind_timeline) { return bind_timeline->syncobj; } uint64_t intel_bind_timeline_bind_begin(struct intel_bind_timeline *bind_timeline) { simple_mtx_lock(&bind_timeline->mutex); return ++bind_timeline->point; } void intel_bind_timeline_bind_end(struct intel_bind_timeline *bind_timeline) { simple_mtx_unlock(&bind_timeline->mutex); } /* * Returns the timeline point that should be waited on before execute any * batch buffers. */ uint64_t intel_bind_timeline_get_last_point(struct intel_bind_timeline *bind_timeline) { uint64_t ret; simple_mtx_lock(&bind_timeline->mutex); ret = bind_timeline->point; simple_mtx_unlock(&bind_timeline->mutex); return ret; }