2 * Copyright (C) 2017-2019 Lima Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
29 #include "drm-uapi/lima_drm.h"
31 #include "util/ralloc.h"
32 #include "util/u_dynarray.h"
33 #include "util/os_time.h"
35 #include "lima_screen.h"
36 #include "lima_context.h"
37 #include "lima_submit.h"
39 #include "lima_util.h"
42 struct lima_screen
*screen
;
50 struct util_dynarray gem_bos
;
51 struct util_dynarray bos
;
55 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
57 struct lima_submit
*lima_submit_create(struct lima_context
*ctx
, uint32_t pipe
)
59 struct lima_submit
*s
;
61 s
= rzalloc(ctx
, struct lima_submit
);
65 s
->screen
= lima_screen(ctx
->base
.screen
);
70 int err
= drmSyncobjCreate(s
->screen
->fd
, DRM_SYNCOBJ_CREATE_SIGNALED
,
75 err
= drmSyncobjCreate(s
->screen
->fd
, DRM_SYNCOBJ_CREATE_SIGNALED
,
80 util_dynarray_init(&s
->gem_bos
, s
);
85 drmSyncobjDestroy(s
->screen
->fd
, s
->out_sync
);
91 void lima_submit_free(struct lima_submit
*submit
)
93 if (submit
->in_sync_fd
>= 0)
94 close(submit
->in_sync_fd
);
95 drmSyncobjDestroy(submit
->screen
->fd
, submit
->in_sync
);
96 drmSyncobjDestroy(submit
->screen
->fd
, submit
->out_sync
);
99 bool lima_submit_add_bo(struct lima_submit
*submit
, struct lima_bo
*bo
, uint32_t flags
)
101 util_dynarray_foreach(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, gem_bo
) {
102 if (bo
->handle
== gem_bo
->handle
) {
103 gem_bo
->flags
|= flags
;
108 struct drm_lima_gem_submit_bo
*submit_bo
=
109 util_dynarray_grow(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, 1);
110 submit_bo
->handle
= bo
->handle
;
111 submit_bo
->flags
= flags
;
113 struct lima_bo
**jbo
= util_dynarray_grow(&submit
->bos
, struct lima_bo
*, 1);
116 /* prevent bo from being freed when submit start */
117 lima_bo_reference(bo
);
122 bool lima_submit_start(struct lima_submit
*submit
, void *frame
, uint32_t size
)
124 struct drm_lima_gem_submit req
= {
126 .pipe
= submit
->pipe
,
127 .nr_bos
= submit
->gem_bos
.size
/ sizeof(struct drm_lima_gem_submit_bo
),
128 .bos
= VOID2U64(util_dynarray_begin(&submit
->gem_bos
)),
129 .frame
= VOID2U64(frame
),
133 if (submit
->in_sync_fd
>= 0) {
134 int err
= drmSyncobjImportSyncFile(submit
->screen
->fd
, submit
->in_sync
,
139 req
.in_sync
[0] = submit
->in_sync
;
140 close(submit
->in_sync_fd
);
141 submit
->in_sync_fd
= -1;
144 bool ret
= drmIoctl(submit
->screen
->fd
, DRM_IOCTL_LIMA_GEM_SUBMIT
, &req
) == 0;
146 util_dynarray_foreach(&submit
->bos
, struct lima_bo
*, bo
) {
150 util_dynarray_clear(&submit
->gem_bos
);
151 util_dynarray_clear(&submit
->bos
);
155 bool lima_submit_wait(struct lima_submit
*submit
, uint64_t timeout_ns
)
157 int64_t abs_timeout
= os_time_get_absolute_timeout(timeout_ns
);
158 if (abs_timeout
== OS_TIMEOUT_INFINITE
)
159 abs_timeout
= INT64_MAX
;
161 return !drmSyncobjWait(submit
->screen
->fd
, &submit
->out_sync
, 1, abs_timeout
, 0, NULL
);
164 bool lima_submit_has_bo(struct lima_submit
*submit
, struct lima_bo
*bo
, bool all
)
166 util_dynarray_foreach(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, gem_bo
) {
167 if (bo
->handle
== gem_bo
->handle
) {
171 return gem_bo
->flags
& LIMA_SUBMIT_BO_WRITE
;
178 bool lima_submit_add_in_sync(struct lima_submit
*submit
, int fd
)
180 return !sync_accumulate("lima", &submit
->in_sync_fd
, fd
);
183 bool lima_submit_get_out_sync(struct lima_submit
*submit
, int *fd
)
185 return !drmSyncobjExportSyncFile(submit
->screen
->fd
, submit
->out_sync
, fd
);