The open source OpenXR runtime
1// Copyright 2019-2023, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Independent semaphore implementation.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup comp_util
8 */
9
10#include "util/u_handles.h"
11
12#include "util/comp_semaphore.h"
13
14
15/*
16 *
17 * Member functions.
18 *
19 */
20
21#ifdef VK_KHR_timeline_semaphore
22static xrt_result_t
23semaphore_wait(struct xrt_compositor_semaphore *xcsem, uint64_t value, uint64_t timeout_ns)
24{
25 struct comp_semaphore *csem = comp_semaphore(xcsem);
26 struct vk_bundle *vk = csem->vk;
27 VkResult ret;
28
29 VkSemaphoreWaitInfo wait_info = {
30 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
31 .flags = 0,
32 .semaphoreCount = 1,
33 .pSemaphores = &csem->semaphore,
34 .pValues = &value,
35 };
36
37 ret = vk->vkWaitSemaphores( //
38 vk->device, // device
39 &wait_info, // pWaitInfo
40 timeout_ns); // timeout
41 if (ret == VK_TIMEOUT) {
42 return XRT_TIMEOUT;
43 }
44 if (ret != VK_SUCCESS) {
45 VK_ERROR(vk, "vkWaitSemaphores: %s", vk_result_string(ret));
46 return XRT_ERROR_VULKAN;
47 }
48
49 return XRT_SUCCESS;
50}
51
52static void
53semaphore_destroy(struct xrt_compositor_semaphore *xcsem)
54{
55 struct comp_semaphore *csem = comp_semaphore(xcsem);
56 struct vk_bundle *vk = csem->vk;
57
58 if (csem->semaphore != VK_NULL_HANDLE) {
59 vk->vkDestroySemaphore( //
60 vk->device, // device
61 csem->semaphore, // semaphore
62 NULL); // pAllocator
63 csem->semaphore = VK_NULL_HANDLE;
64 }
65
66 // Does invalid checking and sets to invalid.
67 u_graphics_sync_unref(&csem->handle);
68
69 // Do the final freeing.
70 free(csem);
71}
72#endif
73
74
75/*
76 *
77 * 'Exported' functions.
78 *
79 */
80
81xrt_result_t
82comp_semaphore_create(struct vk_bundle *vk,
83 xrt_graphics_sync_handle_t *out_handle,
84 struct xrt_compositor_semaphore **out_xcsem)
85{
86#ifdef VK_KHR_timeline_semaphore
87 VkResult ret;
88
89 if (!vk->features.timeline_semaphore) {
90 return XRT_ERROR_VULKAN;
91 }
92
93 VkSemaphore semaphore;
94 xrt_graphics_sync_handle_t handle;
95 ret = vk_create_timeline_semaphore_and_native(vk, &semaphore, &handle);
96 if (ret != VK_SUCCESS) {
97 return XRT_ERROR_VULKAN;
98 }
99
100 VK_NAME_SEMAPHORE(vk, semaphore, "comp_semaphore timeline");
101
102 struct comp_semaphore *csem = U_TYPED_CALLOC(struct comp_semaphore);
103
104 csem->base.reference.count = 1;
105 csem->base.destroy = semaphore_destroy;
106 csem->base.wait = semaphore_wait;
107 csem->semaphore = semaphore;
108 csem->handle = handle;
109 csem->vk = vk;
110
111 *out_xcsem = &csem->base;
112 *out_handle = handle;
113
114 return XRT_SUCCESS;
115#else
116 // How did you even get here?
117 VK_ERROR(vk, "No compile time support for VK_KHR_timeline_semaphore!");
118 return XRT_ERROR_VULKAN;
119#endif
120}