xref: /aosp_15_r20/external/mesa3d/src/intel/common/intel_bind_timeline.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2023 Intel Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "intel_bind_timeline.h"
7 
8 #include "drm-uapi/drm.h"
9 #include "intel_gem.h"
10 
intel_bind_timeline_init(struct intel_bind_timeline * bind_timeline,int fd)11 bool intel_bind_timeline_init(struct intel_bind_timeline *bind_timeline, int fd)
12 {
13    struct drm_syncobj_create syncobj_create = { .flags = DRM_SYNCOBJ_CREATE_SIGNALED };
14 
15    if (intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create))
16       return false;
17 
18    simple_mtx_init(&bind_timeline->mutex, mtx_plain);
19    bind_timeline->syncobj = syncobj_create.handle;
20    bind_timeline->point = 0;
21 
22    return true;
23 }
24 
intel_bind_timeline_finish(struct intel_bind_timeline * bind_timeline,int fd)25 void intel_bind_timeline_finish(struct intel_bind_timeline *bind_timeline, int fd)
26 {
27    if (bind_timeline->syncobj == 0)
28       return;
29 
30    uint64_t point = intel_bind_timeline_get_last_point(bind_timeline);
31    struct drm_syncobj_timeline_wait syncobj_wait = {
32       .timeout_nsec = INT64_MAX,
33       .handles = (uintptr_t)&bind_timeline->syncobj,
34       .count_handles = 1,
35       .points = (uintptr_t)&point,
36    };
37    struct drm_syncobj_destroy syncobj_destroy = {
38       .handle = bind_timeline->syncobj,
39    };
40 
41    /* Makes sure last unbind was signaled otherwise it can trigger job
42     * timeouts in KMD
43     */
44    intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &syncobj_wait);
45    intel_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy);
46 
47    simple_mtx_destroy(&bind_timeline->mutex);
48 }
49 
intel_bind_timeline_get_syncobj(struct intel_bind_timeline * bind_timeline)50 uint32_t intel_bind_timeline_get_syncobj(struct intel_bind_timeline *bind_timeline)
51 {
52    return bind_timeline->syncobj;
53 }
54 
intel_bind_timeline_bind_begin(struct intel_bind_timeline * bind_timeline)55 uint64_t intel_bind_timeline_bind_begin(struct intel_bind_timeline *bind_timeline)
56 {
57    simple_mtx_lock(&bind_timeline->mutex);
58    return ++bind_timeline->point;
59 }
60 
intel_bind_timeline_bind_end(struct intel_bind_timeline * bind_timeline)61 void intel_bind_timeline_bind_end(struct intel_bind_timeline *bind_timeline)
62 {
63    simple_mtx_unlock(&bind_timeline->mutex);
64 }
65 
66 /*
67  * Returns the timeline point that should be waited on before execute any
68  * batch buffers.
69  */
intel_bind_timeline_get_last_point(struct intel_bind_timeline * bind_timeline)70 uint64_t intel_bind_timeline_get_last_point(struct intel_bind_timeline *bind_timeline)
71 {
72    uint64_t ret;
73 
74    simple_mtx_lock(&bind_timeline->mutex);
75    ret = bind_timeline->point;
76    simple_mtx_unlock(&bind_timeline->mutex);
77 
78    return ret;
79 }
80