d32b94ad06737f7ff06f44774dd817cb331bc636
[platform/core/uifw/vulkan-wsi-tizen.git] / wsi / synchronization.hpp
1 /*
2  * Copyright (c) 2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 /**
26  * @file
27  *
28  * @brief Contains the defintions of WSI synchronization primitives.
29  */
30
31 #pragma once
32
33 #include "util/file_descriptor.hpp"
34 #include "util/optional.hpp"
35
36 #include <vulkan/vulkan.h>
37
38 namespace layer
39 {
40    class device_private_data;
41    class instance_private_data;
42 } /* namespace layer */
43
44 namespace wsi
45 {
46
47 /**
48  * Synchronization using a Vulkan Fence object.
49  */
50 class fence_sync
51 {
52 public:
53    /**
54     * Creates a new fence synchronization object.
55     *
56     * @param device The device private data for which to create it.
57     *
58     * @return Empty optional on failure or initialized fence.
59     */
60    static util::optional<fence_sync> create(layer::device_private_data &device);
61
62    /** Default constructor provided for use with @ref util::optional */
63    fence_sync() = default;
64    fence_sync(const fence_sync &) = delete;
65    fence_sync &operator=(const fence_sync &) = delete;
66
67    fence_sync(fence_sync &&rhs);
68    fence_sync &operator=(fence_sync &&rhs);
69
70    virtual ~fence_sync();
71
72    /**
73     * Waits for any pending payload to complete execution.
74     *
75     * @note This method is not threadsafe.
76     *
77     * @param timeout Timeout for waiting in nanoseconds.
78     *
79     * @return VK_SUCCESS on success or if no payload or a completed payload is set.
80     *         Other error code on failure or timeout.
81     */
82    VkResult wait_payload(uint64_t timeout);
83
84    /**
85     * Sets the payload for the fence that would need to complete before operations that wait on it.
86     *
87     * @note This method is not threadsafe.
88     *
89     * @param     queue       The Vulkan queue that may be used to submit synchronization commands.
90     * @param[in] sem_payload Array of Vulkan Semaphores that comprise the payload.
91     * @param     sem_count   Number of elements in @p sem_payload.
92     *
93     * @return VK_SUCCESS on success or other error code on failing to set the payload.
94     */
95    VkResult set_payload(VkQueue queue, const VkSemaphore *sem_payload, uint32_t sem_count);
96
97 protected:
98    /**
99     * Non-public constructor to initialize the object with valid data.
100     *
101     * @param device   The device private data for the fence.
102     * @param vk_fence The created Vulkan fence.
103     */
104    fence_sync(layer::device_private_data &device, VkFence vk_fence);
105
106    VkFence get_fence()
107    {
108       return fence;
109    }
110
111    /**
112     * Swaps current payload. This operation could be performed when exporting or importing external fences.
113     *
114     * @param new_payload Whether a new payload is set.
115     *
116     * @return If there is an existing payload that is being replaced.
117     */
118    bool swap_payload(bool new_payload);
119
120    layer::device_private_data &get_device()
121    {
122       return *dev;
123    }
124
125 private:
126    VkFence fence{ VK_NULL_HANDLE };
127    bool has_payload{ false };
128    bool payload_finished{ false };
129    layer::device_private_data *dev{ nullptr };
130 };
131
132 /**
133  * Synchronization using a Vulkan fence exportable to a native Sync FD object.
134  */
135 class sync_fd_fence_sync : public fence_sync
136 {
137 public:
138    /** Default constructor provided for use with @ref util::optional */
139    sync_fd_fence_sync() = default;
140
141    /**
142     * Checks if a Vulkan device can support Sync FD fences.
143     *
144     * @param instance The instance private data for the physical device.
145     * @param phys_dev The physical device to check support for.
146     *
147     * @return true if supported, false otherwise.
148     */
149    static bool is_supported(layer::instance_private_data &instance, VkPhysicalDevice phys_dev);
150
151    /**
152     * Creates a new fence compatible with Sync FD.
153     *
154     * @param device The device private data for which to create the fence.
155     *
156     * @return Empty optional on failure or initialized fence.
157     */
158    static util::optional<sync_fd_fence_sync> create(layer::device_private_data &device);
159
160    /**
161     * Exports the fence to a native Sync FD.
162     *
163     * @note This method is not threadsafe.
164     *
165     * @return The exported Sync FD on success or empty optional on failure.
166     */
167    util::optional<util::fd_owner> export_sync_fd();
168
169 private:
170    /**
171     * Non-public constructor to initialize the object with valid data.
172     *
173     * @param device   The device private data for the fence.
174     * @param vk_fence The created exportable Vulkan fence.
175     */
176    sync_fd_fence_sync(layer::device_private_data &device, VkFence vk_fence);
177 };
178
179 } /* namespace wsi */