xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkSemaphore.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #ifndef VK_SEMAPHORE_HPP_
16*03ce13f7SAndroid Build Coastguard Worker #define VK_SEMAPHORE_HPP_
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "VkConfig.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "VkObject.hpp"
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker #include "marl/event.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "marl/mutex.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "marl/tsa.h"
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker #include "System/Synchronization.hpp"
26*03ce13f7SAndroid Build Coastguard Worker 
27*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
28*03ce13f7SAndroid Build Coastguard Worker #	include <zircon/types.h>
29*03ce13f7SAndroid Build Coastguard Worker #endif
30*03ce13f7SAndroid Build Coastguard Worker 
31*03ce13f7SAndroid Build Coastguard Worker namespace vk {
32*03ce13f7SAndroid Build Coastguard Worker 
33*03ce13f7SAndroid Build Coastguard Worker class BinarySemaphore;
34*03ce13f7SAndroid Build Coastguard Worker class TimelineSemaphore;
35*03ce13f7SAndroid Build Coastguard Worker 
36*03ce13f7SAndroid Build Coastguard Worker class Semaphore
37*03ce13f7SAndroid Build Coastguard Worker {
38*03ce13f7SAndroid Build Coastguard Worker public:
39*03ce13f7SAndroid Build Coastguard Worker 	Semaphore(VkSemaphoreType type);
40*03ce13f7SAndroid Build Coastguard Worker 
41*03ce13f7SAndroid Build Coastguard Worker 	virtual ~Semaphore() = default;
42*03ce13f7SAndroid Build Coastguard Worker 
Cast(VkSemaphore semaphore)43*03ce13f7SAndroid Build Coastguard Worker 	static inline Semaphore *Cast(VkSemaphore semaphore)
44*03ce13f7SAndroid Build Coastguard Worker 	{
45*03ce13f7SAndroid Build Coastguard Worker 		return static_cast<Semaphore *>(static_cast<void *>(semaphore));
46*03ce13f7SAndroid Build Coastguard Worker 	}
47*03ce13f7SAndroid Build Coastguard Worker 
destroy(const VkAllocationCallbacks * pAllocator)48*03ce13f7SAndroid Build Coastguard Worker 	virtual void destroy(const VkAllocationCallbacks *pAllocator)
49*03ce13f7SAndroid Build Coastguard Worker 	{
50*03ce13f7SAndroid Build Coastguard Worker 	}
51*03ce13f7SAndroid Build Coastguard Worker 
52*03ce13f7SAndroid Build Coastguard Worker 	VkSemaphoreType getSemaphoreType() const;
53*03ce13f7SAndroid Build Coastguard Worker 	// static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo *pCreateInfo);
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker protected:
56*03ce13f7SAndroid Build Coastguard Worker 	VkSemaphoreType type;
57*03ce13f7SAndroid Build Coastguard Worker 	marl::mutex mutex;
58*03ce13f7SAndroid Build Coastguard Worker };
59*03ce13f7SAndroid Build Coastguard Worker 
60*03ce13f7SAndroid Build Coastguard Worker class BinarySemaphore : public Semaphore, public Object<BinarySemaphore, VkSemaphore>
61*03ce13f7SAndroid Build Coastguard Worker {
62*03ce13f7SAndroid Build Coastguard Worker public:
63*03ce13f7SAndroid Build Coastguard Worker 	BinarySemaphore(const VkSemaphoreCreateInfo *pCreateInfo, void *mem, const VkAllocationCallbacks *pAllocator);
64*03ce13f7SAndroid Build Coastguard Worker 	void destroy(const VkAllocationCallbacks *pAllocator);
65*03ce13f7SAndroid Build Coastguard Worker 
66*03ce13f7SAndroid Build Coastguard Worker 	static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo *pCreateInfo);
67*03ce13f7SAndroid Build Coastguard Worker 
68*03ce13f7SAndroid Build Coastguard Worker 	void wait();
69*03ce13f7SAndroid Build Coastguard Worker 
wait(const VkPipelineStageFlags & flag)70*03ce13f7SAndroid Build Coastguard Worker 	void wait(const VkPipelineStageFlags &flag)
71*03ce13f7SAndroid Build Coastguard Worker 	{
72*03ce13f7SAndroid Build Coastguard Worker 		// NOTE: not sure what else to do here?
73*03ce13f7SAndroid Build Coastguard Worker 		wait();
74*03ce13f7SAndroid Build Coastguard Worker 	}
75*03ce13f7SAndroid Build Coastguard Worker 
76*03ce13f7SAndroid Build Coastguard Worker 	void signal();
77*03ce13f7SAndroid Build Coastguard Worker 
78*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
79*03ce13f7SAndroid Build Coastguard Worker 	VkResult importFd(int fd, bool temporaryImport);
80*03ce13f7SAndroid Build Coastguard Worker 	VkResult exportFd(int *pFd);
81*03ce13f7SAndroid Build Coastguard Worker #endif
82*03ce13f7SAndroid Build Coastguard Worker 
83*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
84*03ce13f7SAndroid Build Coastguard Worker 	VkResult importHandle(zx_handle_t handle, bool temporaryImport);
85*03ce13f7SAndroid Build Coastguard Worker 	VkResult exportHandle(zx_handle_t *pHandle);
86*03ce13f7SAndroid Build Coastguard Worker #endif
87*03ce13f7SAndroid Build Coastguard Worker 
88*03ce13f7SAndroid Build Coastguard Worker 	class External;
89*03ce13f7SAndroid Build Coastguard Worker 
90*03ce13f7SAndroid Build Coastguard Worker private:
91*03ce13f7SAndroid Build Coastguard Worker 	// Small technical note on how semaphores are imported/exported with Vulkan:
92*03ce13f7SAndroid Build Coastguard Worker 	//
93*03ce13f7SAndroid Build Coastguard Worker 	// - A Vulkan Semaphore objects has a "payload", corresponding to a
94*03ce13f7SAndroid Build Coastguard Worker 	//   simple atomic boolean flag.
95*03ce13f7SAndroid Build Coastguard Worker 	//
96*03ce13f7SAndroid Build Coastguard Worker 	// - A Vulkan Semaphore object can be "exported": this creates a
97*03ce13f7SAndroid Build Coastguard Worker 	//   platform-specific handle / descriptor (which can be passed to other
98*03ce13f7SAndroid Build Coastguard Worker 	//   processes), and is linked in some way to the original semaphore's
99*03ce13f7SAndroid Build Coastguard Worker 	//   payload.
100*03ce13f7SAndroid Build Coastguard Worker 	//
101*03ce13f7SAndroid Build Coastguard Worker 	// - Similarly, said handle / descriptor can be "imported" into a Vulkan
102*03ce13f7SAndroid Build Coastguard Worker 	//   Semaphore object. By default, that semaphore loses its payload, and
103*03ce13f7SAndroid Build Coastguard Worker 	//   instead uses the one referenced / shared through the descriptor.
104*03ce13f7SAndroid Build Coastguard Worker 	//
105*03ce13f7SAndroid Build Coastguard Worker 	//   Hence if semaphore A exports its payload through a descriptor that
106*03ce13f7SAndroid Build Coastguard Worker 	//   is later imported into semaphore B, then both A and B will use/share
107*03ce13f7SAndroid Build Coastguard Worker 	//   the same payload (i.e. signal flag), making cross-process
108*03ce13f7SAndroid Build Coastguard Worker 	//   synchronization possible.
109*03ce13f7SAndroid Build Coastguard Worker 	//
110*03ce13f7SAndroid Build Coastguard Worker 	// - There are also "temporary imports", where the target semaphore's
111*03ce13f7SAndroid Build Coastguard Worker 	//   payload is not lost, but is simply hidden/stashed. But the next wait()
112*03ce13f7SAndroid Build Coastguard Worker 	//   operation on the same semaphore should remove the temporary import,
113*03ce13f7SAndroid Build Coastguard Worker 	//   and restore the previous payload.
114*03ce13f7SAndroid Build Coastguard Worker 	//
115*03ce13f7SAndroid Build Coastguard Worker 	// - There are many handle / descriptor types, which are listed through
116*03ce13f7SAndroid Build Coastguard Worker 	//   the VkExternalSemaphoreHandleTypeFlagBits. A given Vulkan
117*03ce13f7SAndroid Build Coastguard Worker 	//   implementation might support onle one or several at the same time
118*03ce13f7SAndroid Build Coastguard Worker 	//   (e.g. on Linux or Android, it could support both OPAQUE_FD_BIT and
119*03ce13f7SAndroid Build Coastguard Worker 	//   SYNC_FD_BIT, while on Windows, it would be OPAQUE_WIN32_BIT +
120*03ce13f7SAndroid Build Coastguard Worker 	//   OPAQUE_WIN32_KMT_BIT + D3D12_FENCE_BIT).
121*03ce13f7SAndroid Build Coastguard Worker 	//
122*03ce13f7SAndroid Build Coastguard Worker 	// - To be able to export a semaphore, VkCreateSemaphore() must be called
123*03ce13f7SAndroid Build Coastguard Worker 	//   with a VkSemaphoreCreateInfo that lists the types of all possible
124*03ce13f7SAndroid Build Coastguard Worker 	//   platform-specific handles the semaphore could be exported to
125*03ce13f7SAndroid Build Coastguard Worker 	//   (e.g. on Linux, it is possible to specify that a semaphore might be
126*03ce13f7SAndroid Build Coastguard Worker 	//   exported as an opaque FD, or as a Linux Sync FD).
127*03ce13f7SAndroid Build Coastguard Worker 	//
128*03ce13f7SAndroid Build Coastguard Worker 	//   However, which exact type is however only determined later by the
129*03ce13f7SAndroid Build Coastguard Worker 	//   export operation itself (e.g. vkGetSemaphoreFdKHR() could be called to export
130*03ce13f7SAndroid Build Coastguard Worker 	//   either a VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT or a
131*03ce13f7SAndroid Build Coastguard Worker 	//   VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT).
132*03ce13f7SAndroid Build Coastguard Worker 	//
133*03ce13f7SAndroid Build Coastguard Worker 	//   Once a semaphore has been exported as one type, it is not possible
134*03ce13f7SAndroid Build Coastguard Worker 	//   to export the same payload with a different type (though the spec
135*03ce13f7SAndroid Build Coastguard Worker 	//   doesn't seem to be explicit about this, it's simply impossible in
136*03ce13f7SAndroid Build Coastguard Worker 	//   general).
137*03ce13f7SAndroid Build Coastguard Worker 	//
138*03ce13f7SAndroid Build Coastguard Worker 	// This leads to the following design:
139*03ce13f7SAndroid Build Coastguard Worker 	//
140*03ce13f7SAndroid Build Coastguard Worker 	//   - |internal| is a simple marl::Event that represents the semaphore's
141*03ce13f7SAndroid Build Coastguard Worker 	//     payload when it is not exported, or imported non-temporarily.
142*03ce13f7SAndroid Build Coastguard Worker 	//
143*03ce13f7SAndroid Build Coastguard Worker 	//   - |external| points to an external semaphore payload. It is created
144*03ce13f7SAndroid Build Coastguard Worker 	//     on demand if the semaphore is exported or imported non-temporarily.
145*03ce13f7SAndroid Build Coastguard Worker 	//     Note that once |external| is created, |internal| is ignored.
146*03ce13f7SAndroid Build Coastguard Worker 	//
147*03ce13f7SAndroid Build Coastguard Worker 	//   - |tempExternal| points to a linked-list of temporary external
148*03ce13f7SAndroid Build Coastguard Worker 	//     semaphore payloads. The list head corresponds to the most recent
149*03ce13f7SAndroid Build Coastguard Worker 	//     temporary import.
150*03ce13f7SAndroid Build Coastguard Worker 	//
151*03ce13f7SAndroid Build Coastguard Worker 
152*03ce13f7SAndroid Build Coastguard Worker 	// Internal template to allocate a new External implementation.
153*03ce13f7SAndroid Build Coastguard Worker 	template<class EXTERNAL>
154*03ce13f7SAndroid Build Coastguard Worker 	External *allocateExternal();
155*03ce13f7SAndroid Build Coastguard Worker 
156*03ce13f7SAndroid Build Coastguard Worker 	void deallocateExternal(External *ext);
157*03ce13f7SAndroid Build Coastguard Worker 
158*03ce13f7SAndroid Build Coastguard Worker 	// Used internally to import an external payload.
159*03ce13f7SAndroid Build Coastguard Worker 	// |temporaryImport| is true iff the import is temporary.
160*03ce13f7SAndroid Build Coastguard Worker 	// |alloc_func| is callable that allocates a new External instance of the
161*03ce13f7SAndroid Build Coastguard Worker 	// appropriate type.
162*03ce13f7SAndroid Build Coastguard Worker 	// |import_func| is callable that takes a single parameter, which
163*03ce13f7SAndroid Build Coastguard Worker 	// corresponds to the external handle/descriptor, and returns a VkResult
164*03ce13f7SAndroid Build Coastguard Worker 	// values.
165*03ce13f7SAndroid Build Coastguard Worker 	template<typename ALLOC_FUNC, typename IMPORT_FUNC>
166*03ce13f7SAndroid Build Coastguard Worker 	VkResult importPayload(bool temporaryImport,
167*03ce13f7SAndroid Build Coastguard Worker 	                       ALLOC_FUNC alloc_func,
168*03ce13f7SAndroid Build Coastguard Worker 	                       IMPORT_FUNC import_func);
169*03ce13f7SAndroid Build Coastguard Worker 
170*03ce13f7SAndroid Build Coastguard Worker 	// Used internally to export a given payload.
171*03ce13f7SAndroid Build Coastguard Worker 	// |alloc_func| is a callable that allocates a new External instance of
172*03ce13f7SAndroid Build Coastguard Worker 	// the appropriate type.
173*03ce13f7SAndroid Build Coastguard Worker 	// |export_func| is a callable that takes a pointer to an External instance,
174*03ce13f7SAndroid Build Coastguard Worker 	// and a pointer to a handle/descriptor, and returns a VkResult.
175*03ce13f7SAndroid Build Coastguard Worker 	template<typename ALLOC_FUNC, typename EXPORT_FUNC>
176*03ce13f7SAndroid Build Coastguard Worker 	VkResult exportPayload(ALLOC_FUNC alloc_func, EXPORT_FUNC export_func);
177*03ce13f7SAndroid Build Coastguard Worker 
178*03ce13f7SAndroid Build Coastguard Worker 	const VkAllocationCallbacks *allocator = nullptr;
179*03ce13f7SAndroid Build Coastguard Worker 	VkExternalSemaphoreHandleTypeFlags exportableHandleTypes = (VkExternalSemaphoreHandleTypeFlags)0;
180*03ce13f7SAndroid Build Coastguard Worker 	marl::Event internal;
181*03ce13f7SAndroid Build Coastguard Worker 	External *external GUARDED_BY(mutex) = nullptr;
182*03ce13f7SAndroid Build Coastguard Worker 	External *tempExternal GUARDED_BY(mutex) = nullptr;
183*03ce13f7SAndroid Build Coastguard Worker };
184*03ce13f7SAndroid Build Coastguard Worker 
Cast(VkSemaphore object)185*03ce13f7SAndroid Build Coastguard Worker static inline Semaphore *Cast(VkSemaphore object)
186*03ce13f7SAndroid Build Coastguard Worker {
187*03ce13f7SAndroid Build Coastguard Worker 	return Semaphore::Cast(object);
188*03ce13f7SAndroid Build Coastguard Worker }
189*03ce13f7SAndroid Build Coastguard Worker 
190*03ce13f7SAndroid Build Coastguard Worker template<typename T>
DynamicCast(VkSemaphore object)191*03ce13f7SAndroid Build Coastguard Worker static inline T *DynamicCast(VkSemaphore object)
192*03ce13f7SAndroid Build Coastguard Worker {
193*03ce13f7SAndroid Build Coastguard Worker 	Semaphore *semaphore = vk::Cast(object);
194*03ce13f7SAndroid Build Coastguard Worker 	if(semaphore == nullptr)
195*03ce13f7SAndroid Build Coastguard Worker 	{
196*03ce13f7SAndroid Build Coastguard Worker 		return nullptr;
197*03ce13f7SAndroid Build Coastguard Worker 	}
198*03ce13f7SAndroid Build Coastguard Worker 
199*03ce13f7SAndroid Build Coastguard Worker 	static_assert(std::is_same_v<T, BinarySemaphore> || std::is_same_v<T, TimelineSemaphore>);
200*03ce13f7SAndroid Build Coastguard Worker 	if constexpr(std::is_same_v<T, BinarySemaphore>)
201*03ce13f7SAndroid Build Coastguard Worker 	{
202*03ce13f7SAndroid Build Coastguard Worker 		if(semaphore->getSemaphoreType() != VK_SEMAPHORE_TYPE_BINARY)
203*03ce13f7SAndroid Build Coastguard Worker 		{
204*03ce13f7SAndroid Build Coastguard Worker 			return nullptr;
205*03ce13f7SAndroid Build Coastguard Worker 		}
206*03ce13f7SAndroid Build Coastguard Worker 	}
207*03ce13f7SAndroid Build Coastguard Worker 	else
208*03ce13f7SAndroid Build Coastguard Worker 	{
209*03ce13f7SAndroid Build Coastguard Worker 		if(semaphore->getSemaphoreType() != VK_SEMAPHORE_TYPE_TIMELINE)
210*03ce13f7SAndroid Build Coastguard Worker 		{
211*03ce13f7SAndroid Build Coastguard Worker 			return nullptr;
212*03ce13f7SAndroid Build Coastguard Worker 		}
213*03ce13f7SAndroid Build Coastguard Worker 	}
214*03ce13f7SAndroid Build Coastguard Worker 	return static_cast<T *>(semaphore);
215*03ce13f7SAndroid Build Coastguard Worker }
216*03ce13f7SAndroid Build Coastguard Worker 
217*03ce13f7SAndroid Build Coastguard Worker // This struct helps parse VkSemaphoreCreateInfo. It also looks at the pNext
218*03ce13f7SAndroid Build Coastguard Worker // structures and stores their data flatly in a single struct. The default
219*03ce13f7SAndroid Build Coastguard Worker // values of each data member are what the absence of a pNext struct implies
220*03ce13f7SAndroid Build Coastguard Worker // for those values.
221*03ce13f7SAndroid Build Coastguard Worker struct SemaphoreCreateInfo
222*03ce13f7SAndroid Build Coastguard Worker {
223*03ce13f7SAndroid Build Coastguard Worker 	bool exportSemaphore = false;
224*03ce13f7SAndroid Build Coastguard Worker 	VkExternalSemaphoreHandleTypeFlags exportHandleTypes = 0;
225*03ce13f7SAndroid Build Coastguard Worker 
226*03ce13f7SAndroid Build Coastguard Worker 	VkSemaphoreType semaphoreType = VK_SEMAPHORE_TYPE_BINARY;
227*03ce13f7SAndroid Build Coastguard Worker 	uint64_t initialPayload = 0;
228*03ce13f7SAndroid Build Coastguard Worker 
229*03ce13f7SAndroid Build Coastguard Worker 	SemaphoreCreateInfo(const VkSemaphoreCreateInfo *pCreateInfo);
230*03ce13f7SAndroid Build Coastguard Worker };
231*03ce13f7SAndroid Build Coastguard Worker 
232*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
233*03ce13f7SAndroid Build Coastguard Worker 
234*03ce13f7SAndroid Build Coastguard Worker #endif  // VK_SEMAPHORE_HPP_
235