1 /*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <unistd.h>
27 #include <vulkan/vulkan.h>
28 #include <xf86drm.h>
29
30 #include "drm-uapi/pvr_drm.h"
31 #include "pvr_drm.h"
32 #include "pvr_drm_job_null.h"
33 #include "pvr_winsys.h"
34 #include "util/libsync.h"
35 #include "vk_alloc.h"
36 #include "vk_drm_syncobj.h"
37 #include "vk_log.h"
38 #include "vk_sync.h"
39 #include "vk_util.h"
40
pvr_drm_winsys_null_job_submit(struct pvr_winsys * ws,struct vk_sync_wait * waits,uint32_t wait_count,struct vk_sync_signal * signal_sync)41 VkResult pvr_drm_winsys_null_job_submit(struct pvr_winsys *ws,
42 struct vk_sync_wait *waits,
43 uint32_t wait_count,
44 struct vk_sync_signal *signal_sync)
45 {
46 const struct pvr_drm_winsys *drm_ws = to_pvr_drm_winsys(ws);
47 uint32_t tmp_syncobj;
48 VkResult result;
49 int ret;
50
51 if (wait_count == 1) {
52 struct vk_sync *src_sync = waits[0].sync;
53 struct vk_sync *dst_sync = signal_sync->sync;
54
55 ret = drmSyncobjTransfer(drm_ws->base.render_fd,
56 vk_sync_as_drm_syncobj(dst_sync)->syncobj,
57 signal_sync->signal_value,
58 vk_sync_as_drm_syncobj(src_sync)->syncobj,
59 waits[0].wait_value,
60 0);
61 if (ret) {
62 return vk_errorf(NULL,
63 VK_ERROR_OUT_OF_DEVICE_MEMORY,
64 "Failed to submit transfer syncobj. Errno: %d - %s.",
65 errno,
66 strerror(errno));
67 }
68
69 return VK_SUCCESS;
70 }
71
72 ret = drmSyncobjCreate(drm_ws->base.render_fd,
73 wait_count == 0 ? DRM_SYNCOBJ_CREATE_SIGNALED : 0,
74 &tmp_syncobj);
75 if (ret) {
76 return vk_errorf(NULL,
77 VK_ERROR_OUT_OF_DEVICE_MEMORY,
78 "Failed to create temporary syncobj. Errno: %d - %s.",
79 errno,
80 strerror(errno));
81 }
82
83 for (uint32_t i = 0; i < wait_count; i++) {
84 struct vk_sync *src_sync = waits[i].sync;
85
86 if (!src_sync)
87 continue;
88
89 ret = drmSyncobjTransfer(drm_ws->base.render_fd,
90 tmp_syncobj,
91 i + 1,
92 vk_sync_as_drm_syncobj(src_sync)->syncobj,
93 waits[i].wait_value,
94 0);
95 if (ret) {
96 result =
97 vk_errorf(NULL,
98 VK_ERROR_OUT_OF_DEVICE_MEMORY,
99 "Failed to create temporary syncobj. Errno: %d - %s.",
100 errno,
101 strerror(errno));
102 goto out_destroy_tmp_syncobj;
103 }
104 }
105
106 ret = drmSyncobjTransfer(drm_ws->base.render_fd,
107 vk_sync_as_drm_syncobj(signal_sync->sync)->syncobj,
108 signal_sync->signal_value,
109 tmp_syncobj,
110 wait_count,
111 0);
112 if (ret) {
113 result = vk_errorf(NULL,
114 VK_ERROR_OUT_OF_DEVICE_MEMORY,
115 "Syncobj transfer failed. Errno: %d - %s.",
116 errno,
117 strerror(errno));
118 } else {
119 result = VK_SUCCESS;
120 }
121
122 out_destroy_tmp_syncobj:
123 drmSyncobjDestroy(drm_ws->base.render_fd, tmp_syncobj);
124 return result;
125 }
126