xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkSemaphoreExternalFuchsia.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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 #ifndef VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
16*03ce13f7SAndroid Build Coastguard Worker #define VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp"
19*03ce13f7SAndroid Build Coastguard Worker 
20*03ce13f7SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
21*03ce13f7SAndroid Build Coastguard Worker 
22*03ce13f7SAndroid Build Coastguard Worker // An external semaphore implementation for the Zircon kernel using a simple
23*03ce13f7SAndroid Build Coastguard Worker // Zircon event handle. This matches
24*03ce13f7SAndroid Build Coastguard Worker // VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker namespace vk {
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker class ZirconEventExternalSemaphore : public BinarySemaphore::External
29*03ce13f7SAndroid Build Coastguard Worker {
30*03ce13f7SAndroid Build Coastguard Worker public:
~ZirconEventExternalSemaphore()31*03ce13f7SAndroid Build Coastguard Worker 	~ZirconEventExternalSemaphore()
32*03ce13f7SAndroid Build Coastguard Worker 	{
33*03ce13f7SAndroid Build Coastguard Worker 		zx_handle_close(handle);
34*03ce13f7SAndroid Build Coastguard Worker 	}
35*03ce13f7SAndroid Build Coastguard Worker 
init(bool initialValue)36*03ce13f7SAndroid Build Coastguard Worker 	VkResult init(bool initialValue) override
37*03ce13f7SAndroid Build Coastguard Worker 	{
38*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_event_create(0, &handle);
39*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
40*03ce13f7SAndroid Build Coastguard Worker 		{
41*03ce13f7SAndroid Build Coastguard Worker 			TRACE("zx_event_create() returned %d", status);
42*03ce13f7SAndroid Build Coastguard Worker 			return VK_ERROR_INITIALIZATION_FAILED;
43*03ce13f7SAndroid Build Coastguard Worker 		}
44*03ce13f7SAndroid Build Coastguard Worker 		if(initialValue)
45*03ce13f7SAndroid Build Coastguard Worker 		{
46*03ce13f7SAndroid Build Coastguard Worker 			status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
47*03ce13f7SAndroid Build Coastguard Worker 			if(status != ZX_OK)
48*03ce13f7SAndroid Build Coastguard Worker 			{
49*03ce13f7SAndroid Build Coastguard Worker 				TRACE("zx_object_signal() returned %d", status);
50*03ce13f7SAndroid Build Coastguard Worker 				zx_handle_close(handle);
51*03ce13f7SAndroid Build Coastguard Worker 				handle = ZX_HANDLE_INVALID;
52*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_INITIALIZATION_FAILED;
53*03ce13f7SAndroid Build Coastguard Worker 			}
54*03ce13f7SAndroid Build Coastguard Worker 		}
55*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
56*03ce13f7SAndroid Build Coastguard Worker 	}
57*03ce13f7SAndroid Build Coastguard Worker 
importHandle(zx_handle_t new_handle)58*03ce13f7SAndroid Build Coastguard Worker 	VkResult importHandle(zx_handle_t new_handle) override
59*03ce13f7SAndroid Build Coastguard Worker 	{
60*03ce13f7SAndroid Build Coastguard Worker 		zx_handle_close(handle);
61*03ce13f7SAndroid Build Coastguard Worker 		handle = new_handle;
62*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
63*03ce13f7SAndroid Build Coastguard Worker 	}
64*03ce13f7SAndroid Build Coastguard Worker 
exportHandle(zx_handle_t * pHandle)65*03ce13f7SAndroid Build Coastguard Worker 	VkResult exportHandle(zx_handle_t *pHandle) override
66*03ce13f7SAndroid Build Coastguard Worker 	{
67*03ce13f7SAndroid Build Coastguard Worker 		zx_handle_t new_handle = ZX_HANDLE_INVALID;
68*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &new_handle);
69*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
70*03ce13f7SAndroid Build Coastguard Worker 		{
71*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_handle_duplicate() returned %d", status);
72*03ce13f7SAndroid Build Coastguard Worker 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
73*03ce13f7SAndroid Build Coastguard Worker 		}
74*03ce13f7SAndroid Build Coastguard Worker 		*pHandle = new_handle;
75*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
76*03ce13f7SAndroid Build Coastguard Worker 	}
77*03ce13f7SAndroid Build Coastguard Worker 
wait()78*03ce13f7SAndroid Build Coastguard Worker 	void wait() override
79*03ce13f7SAndroid Build Coastguard Worker 	{
80*03ce13f7SAndroid Build Coastguard Worker 		zx_signals_t observed = 0;
81*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_object_wait_one(
82*03ce13f7SAndroid Build Coastguard Worker 		    handle, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, &observed);
83*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
84*03ce13f7SAndroid Build Coastguard Worker 		{
85*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_wait_one() returned %d", status);
86*03ce13f7SAndroid Build Coastguard Worker 			return;
87*03ce13f7SAndroid Build Coastguard Worker 		}
88*03ce13f7SAndroid Build Coastguard Worker 		if(observed != ZX_EVENT_SIGNALED)
89*03ce13f7SAndroid Build Coastguard Worker 		{
90*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_wait_one() returned observed %x (%x expected)", observed, ZX_EVENT_SIGNALED);
91*03ce13f7SAndroid Build Coastguard Worker 			return;
92*03ce13f7SAndroid Build Coastguard Worker 		}
93*03ce13f7SAndroid Build Coastguard Worker 		// Need to unsignal the event now, as required by the Vulkan spec.
94*03ce13f7SAndroid Build Coastguard Worker 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
95*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
96*03ce13f7SAndroid Build Coastguard Worker 		{
97*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_signal() returned %d", status);
98*03ce13f7SAndroid Build Coastguard Worker 			return;
99*03ce13f7SAndroid Build Coastguard Worker 		}
100*03ce13f7SAndroid Build Coastguard Worker 	}
101*03ce13f7SAndroid Build Coastguard Worker 
tryWait()102*03ce13f7SAndroid Build Coastguard Worker 	bool tryWait() override
103*03ce13f7SAndroid Build Coastguard Worker 	{
104*03ce13f7SAndroid Build Coastguard Worker 		zx_signals_t observed = 0;
105*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_object_wait_one(
106*03ce13f7SAndroid Build Coastguard Worker 		    handle, ZX_EVENT_SIGNALED, zx_clock_get_monotonic(), &observed);
107*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK && status != ZX_ERR_TIMED_OUT)
108*03ce13f7SAndroid Build Coastguard Worker 		{
109*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_wait_one() returned %d", status);
110*03ce13f7SAndroid Build Coastguard Worker 			return false;
111*03ce13f7SAndroid Build Coastguard Worker 		}
112*03ce13f7SAndroid Build Coastguard Worker 		if(observed != ZX_EVENT_SIGNALED)
113*03ce13f7SAndroid Build Coastguard Worker 		{
114*03ce13f7SAndroid Build Coastguard Worker 			return false;
115*03ce13f7SAndroid Build Coastguard Worker 		}
116*03ce13f7SAndroid Build Coastguard Worker 		// Need to unsignal the event now, as required by the Vulkan spec.
117*03ce13f7SAndroid Build Coastguard Worker 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
118*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
119*03ce13f7SAndroid Build Coastguard Worker 		{
120*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_signal() returned %d", status);
121*03ce13f7SAndroid Build Coastguard Worker 			return false;
122*03ce13f7SAndroid Build Coastguard Worker 		}
123*03ce13f7SAndroid Build Coastguard Worker 		return true;
124*03ce13f7SAndroid Build Coastguard Worker 	}
125*03ce13f7SAndroid Build Coastguard Worker 
signal()126*03ce13f7SAndroid Build Coastguard Worker 	void signal() override
127*03ce13f7SAndroid Build Coastguard Worker 	{
128*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
129*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
130*03ce13f7SAndroid Build Coastguard Worker 		{
131*03ce13f7SAndroid Build Coastguard Worker 			DABORT("zx_object_signal() returned %d", status);
132*03ce13f7SAndroid Build Coastguard Worker 		}
133*03ce13f7SAndroid Build Coastguard Worker 	}
134*03ce13f7SAndroid Build Coastguard Worker 
135*03ce13f7SAndroid Build Coastguard Worker private:
136*03ce13f7SAndroid Build Coastguard Worker 	zx_handle_t handle = ZX_HANDLE_INVALID;
137*03ce13f7SAndroid Build Coastguard Worker };
138*03ce13f7SAndroid Build Coastguard Worker 
139*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
140*03ce13f7SAndroid Build Coastguard Worker 
141*03ce13f7SAndroid Build Coastguard Worker #endif  // VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
142