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
);
81 util_dynarray_init(&s
->bos
, s
);
86 drmSyncobjDestroy(s
->screen
->fd
, s
->out_sync
);
92 void lima_submit_free(struct lima_submit
*submit
)
94 if (submit
->in_sync_fd
>= 0)
95 close(submit
->in_sync_fd
);
96 drmSyncobjDestroy(submit
->screen
->fd
, submit
->in_sync
);
97 drmSyncobjDestroy(submit
->screen
->fd
, submit
->out_sync
);
100 bool lima_submit_add_bo(struct lima_submit
*submit
, struct lima_bo
*bo
, uint32_t flags
)
102 util_dynarray_foreach(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, gem_bo
) {
103 if (bo
->handle
== gem_bo
->handle
) {
104 gem_bo
->flags
|= flags
;
109 struct drm_lima_gem_submit_bo
*submit_bo
=
110 util_dynarray_grow(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, 1);
111 submit_bo
->handle
= bo
->handle
;
112 submit_bo
->flags
= flags
;
114 struct lima_bo
**jbo
= util_dynarray_grow(&submit
->bos
, struct lima_bo
*, 1);
117 /* prevent bo from being freed when submit start */
118 lima_bo_reference(bo
);
123 bool lima_submit_start(struct lima_submit
*submit
, void *frame
, uint32_t size
)
125 struct drm_lima_gem_submit req
= {
127 .pipe
= submit
->pipe
,
128 .nr_bos
= submit
->gem_bos
.size
/ sizeof(struct drm_lima_gem_submit_bo
),
129 .bos
= VOID2U64(util_dynarray_begin(&submit
->gem_bos
)),
130 .frame
= VOID2U64(frame
),
132 .out_sync
= submit
->out_sync
,
135 if (submit
->in_sync_fd
>= 0) {
136 int err
= drmSyncobjImportSyncFile(submit
->screen
->fd
, submit
->in_sync
,
141 req
.in_sync
[0] = submit
->in_sync
;
142 close(submit
->in_sync_fd
);
143 submit
->in_sync_fd
= -1;
146 bool ret
= drmIoctl(submit
->screen
->fd
, DRM_IOCTL_LIMA_GEM_SUBMIT
, &req
) == 0;
148 util_dynarray_foreach(&submit
->bos
, struct lima_bo
*, bo
) {
149 lima_bo_unreference(*bo
);
152 util_dynarray_clear(&submit
->gem_bos
);
153 util_dynarray_clear(&submit
->bos
);
157 bool lima_submit_wait(struct lima_submit
*submit
, uint64_t timeout_ns
)
159 int64_t abs_timeout
= os_time_get_absolute_timeout(timeout_ns
);
160 if (abs_timeout
== OS_TIMEOUT_INFINITE
)
161 abs_timeout
= INT64_MAX
;
163 return !drmSyncobjWait(submit
->screen
->fd
, &submit
->out_sync
, 1, abs_timeout
, 0, NULL
);
166 bool lima_submit_has_bo(struct lima_submit
*submit
, struct lima_bo
*bo
, bool all
)
168 util_dynarray_foreach(&submit
->gem_bos
, struct drm_lima_gem_submit_bo
, gem_bo
) {
169 if (bo
->handle
== gem_bo
->handle
) {
173 return gem_bo
->flags
& LIMA_SUBMIT_BO_WRITE
;
180 bool lima_submit_add_in_sync(struct lima_submit
*submit
, int fd
)
182 return !sync_accumulate("lima", &submit
->in_sync_fd
, fd
);
185 bool lima_submit_get_out_sync(struct lima_submit
*submit
, int *fd
)
187 return !drmSyncobjExportSyncFile(submit
->screen
->fd
, submit
->out_sync
, fd
);