1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 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 #include "VkSemaphore.hpp"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include "VkConfig.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "VkStringify.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "VkTimelineSemaphore.hpp"
20*03ce13f7SAndroid Build Coastguard Worker
21*03ce13f7SAndroid Build Coastguard Worker #include "marl/blockingcall.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "marl/conditionvariable.h"
23*03ce13f7SAndroid Build Coastguard Worker
24*03ce13f7SAndroid Build Coastguard Worker #include <functional>
25*03ce13f7SAndroid Build Coastguard Worker #include <memory>
26*03ce13f7SAndroid Build Coastguard Worker #include <utility>
27*03ce13f7SAndroid Build Coastguard Worker
28*03ce13f7SAndroid Build Coastguard Worker namespace vk {
29*03ce13f7SAndroid Build Coastguard Worker
30*03ce13f7SAndroid Build Coastguard Worker // This is a base abstract class for all external semaphore implementations
31*03ce13f7SAndroid Build Coastguard Worker // used in this source file.
32*03ce13f7SAndroid Build Coastguard Worker class BinarySemaphore::External
33*03ce13f7SAndroid Build Coastguard Worker {
34*03ce13f7SAndroid Build Coastguard Worker public:
35*03ce13f7SAndroid Build Coastguard Worker virtual ~External() = default;
36*03ce13f7SAndroid Build Coastguard Worker
37*03ce13f7SAndroid Build Coastguard Worker // Initialize new instance with a given initial state.
38*03ce13f7SAndroid Build Coastguard Worker virtual VkResult init(bool initialState) = 0;
39*03ce13f7SAndroid Build Coastguard Worker
40*03ce13f7SAndroid Build Coastguard Worker virtual bool tryWait() = 0;
41*03ce13f7SAndroid Build Coastguard Worker virtual void wait() = 0;
42*03ce13f7SAndroid Build Coastguard Worker virtual void signal() = 0;
43*03ce13f7SAndroid Build Coastguard Worker
44*03ce13f7SAndroid Build Coastguard Worker // For VK_KHR_external_semaphore_fd
importOpaqueFd(int fd)45*03ce13f7SAndroid Build Coastguard Worker virtual VkResult importOpaqueFd(int fd)
46*03ce13f7SAndroid Build Coastguard Worker {
47*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
48*03ce13f7SAndroid Build Coastguard Worker }
49*03ce13f7SAndroid Build Coastguard Worker
exportOpaqueFd(int * pFd)50*03ce13f7SAndroid Build Coastguard Worker virtual VkResult exportOpaqueFd(int *pFd)
51*03ce13f7SAndroid Build Coastguard Worker {
52*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
53*03ce13f7SAndroid Build Coastguard Worker }
54*03ce13f7SAndroid Build Coastguard Worker
55*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
56*03ce13f7SAndroid Build Coastguard Worker // For VK_FUCHSIA_external_semaphore
importHandle(zx_handle_t handle)57*03ce13f7SAndroid Build Coastguard Worker virtual VkResult importHandle(zx_handle_t handle)
58*03ce13f7SAndroid Build Coastguard Worker {
59*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
60*03ce13f7SAndroid Build Coastguard Worker }
exportHandle(zx_handle_t * pHandle)61*03ce13f7SAndroid Build Coastguard Worker virtual VkResult exportHandle(zx_handle_t *pHandle)
62*03ce13f7SAndroid Build Coastguard Worker {
63*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
64*03ce13f7SAndroid Build Coastguard Worker }
65*03ce13f7SAndroid Build Coastguard Worker #endif
66*03ce13f7SAndroid Build Coastguard Worker // Pointer to previous temporary external instanc,e used for |tempExternal| only.
67*03ce13f7SAndroid Build Coastguard Worker External *previous = nullptr;
68*03ce13f7SAndroid Build Coastguard Worker };
69*03ce13f7SAndroid Build Coastguard Worker
70*03ce13f7SAndroid Build Coastguard Worker } // namespace vk
71*03ce13f7SAndroid Build Coastguard Worker
72*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
73*03ce13f7SAndroid Build Coastguard Worker # if defined(__linux__) || defined(__ANDROID__)
74*03ce13f7SAndroid Build Coastguard Worker # include "VkSemaphoreExternalLinux.hpp"
75*03ce13f7SAndroid Build Coastguard Worker # else
76*03ce13f7SAndroid Build Coastguard Worker # error "Missing VK_KHR_external_semaphore_fd implementation for this platform!"
77*03ce13f7SAndroid Build Coastguard Worker # endif
78*03ce13f7SAndroid Build Coastguard Worker #elif VK_USE_PLATFORM_FUCHSIA
79*03ce13f7SAndroid Build Coastguard Worker # include "VkSemaphoreExternalFuchsia.hpp"
80*03ce13f7SAndroid Build Coastguard Worker #endif
81*03ce13f7SAndroid Build Coastguard Worker
82*03ce13f7SAndroid Build Coastguard Worker namespace vk {
83*03ce13f7SAndroid Build Coastguard Worker
84*03ce13f7SAndroid Build Coastguard Worker // The bitmask of all external semaphore handle types supported by this source file.
85*03ce13f7SAndroid Build Coastguard Worker static const VkExternalSemaphoreHandleTypeFlags kSupportedTypes =
86*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
87*03ce13f7SAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT |
88*03ce13f7SAndroid Build Coastguard Worker #endif
89*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
90*03ce13f7SAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA |
91*03ce13f7SAndroid Build Coastguard Worker #endif
92*03ce13f7SAndroid Build Coastguard Worker 0;
93*03ce13f7SAndroid Build Coastguard Worker
94*03ce13f7SAndroid Build Coastguard Worker // Create a new instance. The external instance will be allocated only
95*03ce13f7SAndroid Build Coastguard Worker // the pCreateInfo->pNext chain indicates it needs to be exported.
SemaphoreCreateInfo(const VkSemaphoreCreateInfo * pCreateInfo)96*03ce13f7SAndroid Build Coastguard Worker SemaphoreCreateInfo::SemaphoreCreateInfo(const VkSemaphoreCreateInfo *pCreateInfo)
97*03ce13f7SAndroid Build Coastguard Worker {
98*03ce13f7SAndroid Build Coastguard Worker for(const auto *nextInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
99*03ce13f7SAndroid Build Coastguard Worker nextInfo != nullptr; nextInfo = nextInfo->pNext)
100*03ce13f7SAndroid Build Coastguard Worker {
101*03ce13f7SAndroid Build Coastguard Worker switch(nextInfo->sType)
102*03ce13f7SAndroid Build Coastguard Worker {
103*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO:
104*03ce13f7SAndroid Build Coastguard Worker {
105*03ce13f7SAndroid Build Coastguard Worker const auto *exportInfo = reinterpret_cast<const VkExportSemaphoreCreateInfo *>(nextInfo);
106*03ce13f7SAndroid Build Coastguard Worker exportSemaphore = true;
107*03ce13f7SAndroid Build Coastguard Worker exportHandleTypes = exportInfo->handleTypes;
108*03ce13f7SAndroid Build Coastguard Worker if((exportHandleTypes & ~kSupportedTypes) != 0)
109*03ce13f7SAndroid Build Coastguard Worker {
110*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("exportInfo->handleTypes 0x%08X (supports 0x%08X)",
111*03ce13f7SAndroid Build Coastguard Worker int(exportHandleTypes),
112*03ce13f7SAndroid Build Coastguard Worker int(kSupportedTypes));
113*03ce13f7SAndroid Build Coastguard Worker }
114*03ce13f7SAndroid Build Coastguard Worker }
115*03ce13f7SAndroid Build Coastguard Worker break;
116*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO:
117*03ce13f7SAndroid Build Coastguard Worker {
118*03ce13f7SAndroid Build Coastguard Worker const auto *tlsInfo = reinterpret_cast<const VkSemaphoreTypeCreateInfo *>(nextInfo);
119*03ce13f7SAndroid Build Coastguard Worker semaphoreType = tlsInfo->semaphoreType;
120*03ce13f7SAndroid Build Coastguard Worker initialPayload = tlsInfo->initialValue;
121*03ce13f7SAndroid Build Coastguard Worker }
122*03ce13f7SAndroid Build Coastguard Worker break;
123*03ce13f7SAndroid Build Coastguard Worker default:
124*03ce13f7SAndroid Build Coastguard Worker WARN("nextInfo->sType = %s", vk::Stringify(nextInfo->sType).c_str());
125*03ce13f7SAndroid Build Coastguard Worker break;
126*03ce13f7SAndroid Build Coastguard Worker }
127*03ce13f7SAndroid Build Coastguard Worker }
128*03ce13f7SAndroid Build Coastguard Worker }
129*03ce13f7SAndroid Build Coastguard Worker
Semaphore(VkSemaphoreType type)130*03ce13f7SAndroid Build Coastguard Worker Semaphore::Semaphore(VkSemaphoreType type)
131*03ce13f7SAndroid Build Coastguard Worker : type(type)
132*03ce13f7SAndroid Build Coastguard Worker {
133*03ce13f7SAndroid Build Coastguard Worker }
134*03ce13f7SAndroid Build Coastguard Worker
getSemaphoreType() const135*03ce13f7SAndroid Build Coastguard Worker VkSemaphoreType Semaphore::getSemaphoreType() const
136*03ce13f7SAndroid Build Coastguard Worker {
137*03ce13f7SAndroid Build Coastguard Worker return type;
138*03ce13f7SAndroid Build Coastguard Worker }
139*03ce13f7SAndroid Build Coastguard Worker
wait()140*03ce13f7SAndroid Build Coastguard Worker void BinarySemaphore::wait()
141*03ce13f7SAndroid Build Coastguard Worker {
142*03ce13f7SAndroid Build Coastguard Worker marl::lock lock(mutex);
143*03ce13f7SAndroid Build Coastguard Worker External *ext = tempExternal ? tempExternal : external;
144*03ce13f7SAndroid Build Coastguard Worker if(ext)
145*03ce13f7SAndroid Build Coastguard Worker {
146*03ce13f7SAndroid Build Coastguard Worker if(!ext->tryWait())
147*03ce13f7SAndroid Build Coastguard Worker {
148*03ce13f7SAndroid Build Coastguard Worker // Dispatch the ext wait to a background thread.
149*03ce13f7SAndroid Build Coastguard Worker // Even if this creates a new thread on each
150*03ce13f7SAndroid Build Coastguard Worker // call, it is assumed that this is negligible
151*03ce13f7SAndroid Build Coastguard Worker // compared with the actual semaphore wait()
152*03ce13f7SAndroid Build Coastguard Worker // operation.
153*03ce13f7SAndroid Build Coastguard Worker lock.unlock_no_tsa();
154*03ce13f7SAndroid Build Coastguard Worker marl::blocking_call([ext]() {
155*03ce13f7SAndroid Build Coastguard Worker ext->wait();
156*03ce13f7SAndroid Build Coastguard Worker });
157*03ce13f7SAndroid Build Coastguard Worker lock.lock_no_tsa();
158*03ce13f7SAndroid Build Coastguard Worker }
159*03ce13f7SAndroid Build Coastguard Worker
160*03ce13f7SAndroid Build Coastguard Worker // If the import was temporary, reset the semaphore to its previous state.
161*03ce13f7SAndroid Build Coastguard Worker // See "6.4.5. Importing BinarySemaphore Payloads" in Vulkan 1.1 spec.
162*03ce13f7SAndroid Build Coastguard Worker if(ext == tempExternal)
163*03ce13f7SAndroid Build Coastguard Worker {
164*03ce13f7SAndroid Build Coastguard Worker tempExternal = ext->previous;
165*03ce13f7SAndroid Build Coastguard Worker deallocateExternal(ext);
166*03ce13f7SAndroid Build Coastguard Worker }
167*03ce13f7SAndroid Build Coastguard Worker }
168*03ce13f7SAndroid Build Coastguard Worker else
169*03ce13f7SAndroid Build Coastguard Worker {
170*03ce13f7SAndroid Build Coastguard Worker internal.wait();
171*03ce13f7SAndroid Build Coastguard Worker }
172*03ce13f7SAndroid Build Coastguard Worker }
173*03ce13f7SAndroid Build Coastguard Worker
signal()174*03ce13f7SAndroid Build Coastguard Worker void BinarySemaphore::signal()
175*03ce13f7SAndroid Build Coastguard Worker {
176*03ce13f7SAndroid Build Coastguard Worker ASSERT(type == VK_SEMAPHORE_TYPE_BINARY);
177*03ce13f7SAndroid Build Coastguard Worker marl::lock lock(mutex);
178*03ce13f7SAndroid Build Coastguard Worker External *ext = tempExternal ? tempExternal : external;
179*03ce13f7SAndroid Build Coastguard Worker if(ext)
180*03ce13f7SAndroid Build Coastguard Worker {
181*03ce13f7SAndroid Build Coastguard Worker // Assumes that signalling an external semaphore is non-blocking,
182*03ce13f7SAndroid Build Coastguard Worker // so it can be performed directly either from a fiber or thread.
183*03ce13f7SAndroid Build Coastguard Worker ext->signal();
184*03ce13f7SAndroid Build Coastguard Worker }
185*03ce13f7SAndroid Build Coastguard Worker else
186*03ce13f7SAndroid Build Coastguard Worker {
187*03ce13f7SAndroid Build Coastguard Worker internal.signal();
188*03ce13f7SAndroid Build Coastguard Worker }
189*03ce13f7SAndroid Build Coastguard Worker }
190*03ce13f7SAndroid Build Coastguard Worker
BinarySemaphore(const VkSemaphoreCreateInfo * pCreateInfo,void * mem,const VkAllocationCallbacks * pAllocator)191*03ce13f7SAndroid Build Coastguard Worker BinarySemaphore::BinarySemaphore(const VkSemaphoreCreateInfo *pCreateInfo, void *mem, const VkAllocationCallbacks *pAllocator)
192*03ce13f7SAndroid Build Coastguard Worker : Semaphore(VK_SEMAPHORE_TYPE_BINARY)
193*03ce13f7SAndroid Build Coastguard Worker , allocator(pAllocator)
194*03ce13f7SAndroid Build Coastguard Worker {
195*03ce13f7SAndroid Build Coastguard Worker SemaphoreCreateInfo info(pCreateInfo);
196*03ce13f7SAndroid Build Coastguard Worker exportableHandleTypes = info.exportHandleTypes;
197*03ce13f7SAndroid Build Coastguard Worker ASSERT(info.semaphoreType == VK_SEMAPHORE_TYPE_BINARY);
198*03ce13f7SAndroid Build Coastguard Worker type = info.semaphoreType;
199*03ce13f7SAndroid Build Coastguard Worker }
200*03ce13f7SAndroid Build Coastguard Worker
destroy(const VkAllocationCallbacks * pAllocator)201*03ce13f7SAndroid Build Coastguard Worker void BinarySemaphore::destroy(const VkAllocationCallbacks *pAllocator)
202*03ce13f7SAndroid Build Coastguard Worker {
203*03ce13f7SAndroid Build Coastguard Worker marl::lock lock(mutex);
204*03ce13f7SAndroid Build Coastguard Worker while(tempExternal)
205*03ce13f7SAndroid Build Coastguard Worker {
206*03ce13f7SAndroid Build Coastguard Worker External *ext = tempExternal;
207*03ce13f7SAndroid Build Coastguard Worker tempExternal = ext->previous;
208*03ce13f7SAndroid Build Coastguard Worker deallocateExternal(ext);
209*03ce13f7SAndroid Build Coastguard Worker }
210*03ce13f7SAndroid Build Coastguard Worker if(external)
211*03ce13f7SAndroid Build Coastguard Worker {
212*03ce13f7SAndroid Build Coastguard Worker deallocateExternal(external);
213*03ce13f7SAndroid Build Coastguard Worker external = nullptr;
214*03ce13f7SAndroid Build Coastguard Worker }
215*03ce13f7SAndroid Build Coastguard Worker }
216*03ce13f7SAndroid Build Coastguard Worker
ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo * pCreateInfo)217*03ce13f7SAndroid Build Coastguard Worker size_t BinarySemaphore::ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo *pCreateInfo)
218*03ce13f7SAndroid Build Coastguard Worker {
219*03ce13f7SAndroid Build Coastguard Worker // Semaphore::External instance is created and destroyed on demand so return 0 here.
220*03ce13f7SAndroid Build Coastguard Worker return 0;
221*03ce13f7SAndroid Build Coastguard Worker }
222*03ce13f7SAndroid Build Coastguard Worker
223*03ce13f7SAndroid Build Coastguard Worker template<class EXTERNAL>
allocateExternal()224*03ce13f7SAndroid Build Coastguard Worker BinarySemaphore::External *BinarySemaphore::allocateExternal()
225*03ce13f7SAndroid Build Coastguard Worker {
226*03ce13f7SAndroid Build Coastguard Worker auto *ext = reinterpret_cast<BinarySemaphore::External *>(
227*03ce13f7SAndroid Build Coastguard Worker vk::allocateHostMemory(sizeof(EXTERNAL), alignof(EXTERNAL), allocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
228*03ce13f7SAndroid Build Coastguard Worker new(ext) EXTERNAL();
229*03ce13f7SAndroid Build Coastguard Worker return ext;
230*03ce13f7SAndroid Build Coastguard Worker }
231*03ce13f7SAndroid Build Coastguard Worker
deallocateExternal(BinarySemaphore::External * ext)232*03ce13f7SAndroid Build Coastguard Worker void BinarySemaphore::deallocateExternal(BinarySemaphore::External *ext)
233*03ce13f7SAndroid Build Coastguard Worker {
234*03ce13f7SAndroid Build Coastguard Worker ext->~External();
235*03ce13f7SAndroid Build Coastguard Worker vk::freeHostMemory(ext, allocator);
236*03ce13f7SAndroid Build Coastguard Worker }
237*03ce13f7SAndroid Build Coastguard Worker
238*03ce13f7SAndroid Build Coastguard Worker template<typename ALLOC_FUNC, typename IMPORT_FUNC>
importPayload(bool temporaryImport,ALLOC_FUNC alloc_func,IMPORT_FUNC import_func)239*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::importPayload(bool temporaryImport,
240*03ce13f7SAndroid Build Coastguard Worker ALLOC_FUNC alloc_func,
241*03ce13f7SAndroid Build Coastguard Worker IMPORT_FUNC import_func)
242*03ce13f7SAndroid Build Coastguard Worker {
243*03ce13f7SAndroid Build Coastguard Worker marl::lock lock(mutex);
244*03ce13f7SAndroid Build Coastguard Worker
245*03ce13f7SAndroid Build Coastguard Worker // Create new External instance if needed.
246*03ce13f7SAndroid Build Coastguard Worker External *ext = external;
247*03ce13f7SAndroid Build Coastguard Worker if(temporaryImport || !ext)
248*03ce13f7SAndroid Build Coastguard Worker {
249*03ce13f7SAndroid Build Coastguard Worker ext = alloc_func();
250*03ce13f7SAndroid Build Coastguard Worker }
251*03ce13f7SAndroid Build Coastguard Worker VkResult result = import_func(ext);
252*03ce13f7SAndroid Build Coastguard Worker if(result != VK_SUCCESS)
253*03ce13f7SAndroid Build Coastguard Worker {
254*03ce13f7SAndroid Build Coastguard Worker if(temporaryImport || !external)
255*03ce13f7SAndroid Build Coastguard Worker {
256*03ce13f7SAndroid Build Coastguard Worker deallocateExternal(ext);
257*03ce13f7SAndroid Build Coastguard Worker }
258*03ce13f7SAndroid Build Coastguard Worker return result;
259*03ce13f7SAndroid Build Coastguard Worker }
260*03ce13f7SAndroid Build Coastguard Worker
261*03ce13f7SAndroid Build Coastguard Worker if(temporaryImport)
262*03ce13f7SAndroid Build Coastguard Worker {
263*03ce13f7SAndroid Build Coastguard Worker ext->previous = tempExternal;
264*03ce13f7SAndroid Build Coastguard Worker tempExternal = ext;
265*03ce13f7SAndroid Build Coastguard Worker }
266*03ce13f7SAndroid Build Coastguard Worker else if(!external)
267*03ce13f7SAndroid Build Coastguard Worker {
268*03ce13f7SAndroid Build Coastguard Worker external = ext;
269*03ce13f7SAndroid Build Coastguard Worker }
270*03ce13f7SAndroid Build Coastguard Worker return VK_SUCCESS;
271*03ce13f7SAndroid Build Coastguard Worker }
272*03ce13f7SAndroid Build Coastguard Worker
273*03ce13f7SAndroid Build Coastguard Worker template<typename ALLOC_FUNC, typename EXPORT_FUNC>
exportPayload(ALLOC_FUNC alloc_func,EXPORT_FUNC export_func)274*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::exportPayload(ALLOC_FUNC alloc_func, EXPORT_FUNC export_func)
275*03ce13f7SAndroid Build Coastguard Worker {
276*03ce13f7SAndroid Build Coastguard Worker marl::lock lock(mutex);
277*03ce13f7SAndroid Build Coastguard Worker // Sanity check, do not try to export a semaphore that has a temporary import.
278*03ce13f7SAndroid Build Coastguard Worker if(tempExternal != nullptr)
279*03ce13f7SAndroid Build Coastguard Worker {
280*03ce13f7SAndroid Build Coastguard Worker TRACE("Cannot export semaphore with a temporary import!");
281*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
282*03ce13f7SAndroid Build Coastguard Worker }
283*03ce13f7SAndroid Build Coastguard Worker // Allocate |external| if it doesn't exist yet.
284*03ce13f7SAndroid Build Coastguard Worker if(!external)
285*03ce13f7SAndroid Build Coastguard Worker {
286*03ce13f7SAndroid Build Coastguard Worker External *ext = alloc_func();
287*03ce13f7SAndroid Build Coastguard Worker VkResult result = ext->init(internal.isSignalled());
288*03ce13f7SAndroid Build Coastguard Worker if(result != VK_SUCCESS)
289*03ce13f7SAndroid Build Coastguard Worker {
290*03ce13f7SAndroid Build Coastguard Worker deallocateExternal(ext);
291*03ce13f7SAndroid Build Coastguard Worker return result;
292*03ce13f7SAndroid Build Coastguard Worker }
293*03ce13f7SAndroid Build Coastguard Worker external = ext;
294*03ce13f7SAndroid Build Coastguard Worker }
295*03ce13f7SAndroid Build Coastguard Worker return export_func(external);
296*03ce13f7SAndroid Build Coastguard Worker }
297*03ce13f7SAndroid Build Coastguard Worker
298*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
importFd(int fd,bool temporaryImport)299*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::importFd(int fd, bool temporaryImport)
300*03ce13f7SAndroid Build Coastguard Worker {
301*03ce13f7SAndroid Build Coastguard Worker return importPayload(
302*03ce13f7SAndroid Build Coastguard Worker temporaryImport,
303*03ce13f7SAndroid Build Coastguard Worker [this]() {
304*03ce13f7SAndroid Build Coastguard Worker return allocateExternal<OpaqueFdExternalSemaphore>();
305*03ce13f7SAndroid Build Coastguard Worker },
306*03ce13f7SAndroid Build Coastguard Worker [fd](External *ext) {
307*03ce13f7SAndroid Build Coastguard Worker return ext->importOpaqueFd(fd);
308*03ce13f7SAndroid Build Coastguard Worker });
309*03ce13f7SAndroid Build Coastguard Worker }
310*03ce13f7SAndroid Build Coastguard Worker
exportFd(int * pFd)311*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::exportFd(int *pFd)
312*03ce13f7SAndroid Build Coastguard Worker {
313*03ce13f7SAndroid Build Coastguard Worker if((exportableHandleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) == 0)
314*03ce13f7SAndroid Build Coastguard Worker {
315*03ce13f7SAndroid Build Coastguard Worker TRACE("Cannot export semaphore as opaque FD (exportableHandleType = 0x%08X, want 0x%08X)",
316*03ce13f7SAndroid Build Coastguard Worker exportableHandleTypes,
317*03ce13f7SAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
318*03ce13f7SAndroid Build Coastguard Worker
319*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
320*03ce13f7SAndroid Build Coastguard Worker }
321*03ce13f7SAndroid Build Coastguard Worker
322*03ce13f7SAndroid Build Coastguard Worker return exportPayload([this]() { return allocateExternal<OpaqueFdExternalSemaphore>(); },
323*03ce13f7SAndroid Build Coastguard Worker [pFd](External *ext) {
324*03ce13f7SAndroid Build Coastguard Worker return ext->exportOpaqueFd(pFd);
325*03ce13f7SAndroid Build Coastguard Worker });
326*03ce13f7SAndroid Build Coastguard Worker }
327*03ce13f7SAndroid Build Coastguard Worker #endif // SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
328*03ce13f7SAndroid Build Coastguard Worker
329*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
importHandle(zx_handle_t handle,bool temporaryImport)330*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::importHandle(zx_handle_t handle, bool temporaryImport)
331*03ce13f7SAndroid Build Coastguard Worker {
332*03ce13f7SAndroid Build Coastguard Worker return importPayload(
333*03ce13f7SAndroid Build Coastguard Worker temporaryImport,
334*03ce13f7SAndroid Build Coastguard Worker [this]() {
335*03ce13f7SAndroid Build Coastguard Worker return allocateExternal<ZirconEventExternalSemaphore>();
336*03ce13f7SAndroid Build Coastguard Worker },
337*03ce13f7SAndroid Build Coastguard Worker [handle](External *ext) {
338*03ce13f7SAndroid Build Coastguard Worker return ext->importHandle(handle);
339*03ce13f7SAndroid Build Coastguard Worker });
340*03ce13f7SAndroid Build Coastguard Worker }
341*03ce13f7SAndroid Build Coastguard Worker
exportHandle(zx_handle_t * pHandle)342*03ce13f7SAndroid Build Coastguard Worker VkResult BinarySemaphore::exportHandle(zx_handle_t *pHandle)
343*03ce13f7SAndroid Build Coastguard Worker {
344*03ce13f7SAndroid Build Coastguard Worker if((exportableHandleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA) == 0)
345*03ce13f7SAndroid Build Coastguard Worker {
346*03ce13f7SAndroid Build Coastguard Worker TRACE("Cannot export semaphore as Zircon handle (exportableHandleType = 0x%X, want 0x%X)",
347*03ce13f7SAndroid Build Coastguard Worker exportableHandleTypes,
348*03ce13f7SAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA);
349*03ce13f7SAndroid Build Coastguard Worker
350*03ce13f7SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
351*03ce13f7SAndroid Build Coastguard Worker }
352*03ce13f7SAndroid Build Coastguard Worker
353*03ce13f7SAndroid Build Coastguard Worker return exportPayload([this]() { return allocateExternal<ZirconEventExternalSemaphore>(); },
354*03ce13f7SAndroid Build Coastguard Worker [pHandle](External *ext) {
355*03ce13f7SAndroid Build Coastguard Worker return ext->exportHandle(pHandle);
356*03ce13f7SAndroid Build Coastguard Worker });
357*03ce13f7SAndroid Build Coastguard Worker }
358*03ce13f7SAndroid Build Coastguard Worker #endif // VK_USE_PLATFORM_FUCHSIA
359*03ce13f7SAndroid Build Coastguard Worker
360*03ce13f7SAndroid Build Coastguard Worker } // namespace vk
361