The open source OpenXR runtime
1// Copyright 2019-2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Independent @ref xrt_compositor_fence implementation.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup comp_util
8 */
9
10#include "xrt/xrt_config_os.h"
11
12#include "util/u_misc.h"
13#include "util/u_handles.h"
14#include "util/u_trace_marker.h"
15
16#include "util/comp_sync.h"
17
18#include <stdio.h>
19#include <stdlib.h>
20
21#ifndef XRT_OS_WINDOWS
22#include <unistd.h>
23#endif
24
25
26/*
27 *
28 * Structs.
29 *
30 */
31
32/*!
33 * A very simple implementation of a fence primitive.
34 */
35struct fence
36{
37 struct xrt_compositor_fence base;
38
39 struct vk_bundle *vk;
40
41 VkFence fence;
42};
43
44
45/*
46 *
47 * Fence member functions.
48 *
49 */
50
51static xrt_result_t
52fence_wait(struct xrt_compositor_fence *xcf, uint64_t timeout)
53{
54 COMP_TRACE_MARKER();
55
56 struct fence *f = (struct fence *)xcf;
57 struct vk_bundle *vk = f->vk;
58
59 // Count no handle as signled fence.
60 if (f->fence == VK_NULL_HANDLE) {
61 return XRT_SUCCESS;
62 }
63
64 VkResult ret = vk->vkWaitForFences(vk->device, 1, &f->fence, VK_TRUE, timeout);
65 if (ret == VK_TIMEOUT) {
66 return XRT_TIMEOUT;
67 }
68 if (ret != VK_SUCCESS) {
69 VK_ERROR(vk, "vkWaitForFences: %s", vk_result_string(ret));
70 return XRT_ERROR_VULKAN;
71 }
72
73 return XRT_SUCCESS;
74}
75
76static void
77fence_destroy(struct xrt_compositor_fence *xcf)
78{
79 COMP_TRACE_MARKER();
80
81 struct fence *f = (struct fence *)xcf;
82 struct vk_bundle *vk = f->vk;
83
84 if (f->fence != VK_NULL_HANDLE) {
85 vk->vkDestroyFence(vk->device, f->fence, NULL);
86 f->fence = VK_NULL_HANDLE;
87 }
88
89 free(f);
90}
91
92
93/*
94 *
95 * 'Exported' function.
96 *
97 */
98
99xrt_result_t
100comp_fence_import(struct vk_bundle *vk, xrt_graphics_sync_handle_t handle, struct xrt_compositor_fence **out_xcf)
101{
102 COMP_TRACE_MARKER();
103
104 VkFence fence = VK_NULL_HANDLE;
105
106 VkResult ret = vk_create_fence_sync_from_native(vk, handle, &fence);
107 if (ret != VK_SUCCESS) {
108 return XRT_ERROR_VULKAN;
109 }
110
111 // Name for debugging.
112 VK_NAME_FENCE(vk, fence, "Comp Sync");
113
114 struct fence *f = U_TYPED_CALLOC(struct fence);
115 f->base.wait = fence_wait;
116 f->base.destroy = fence_destroy;
117 f->fence = fence;
118 f->vk = vk;
119
120 *out_xcf = &f->base;
121
122 return XRT_SUCCESS;
123}