xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkSemaphoreExternalFuchsia.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
16 #define VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
17 
18 #include "System/Debug.hpp"
19 
20 #include <zircon/syscalls.h>
21 
22 // An external semaphore implementation for the Zircon kernel using a simple
23 // Zircon event handle. This matches
24 // VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA
25 
26 namespace vk {
27 
28 class ZirconEventExternalSemaphore : public BinarySemaphore::External
29 {
30 public:
~ZirconEventExternalSemaphore()31 	~ZirconEventExternalSemaphore()
32 	{
33 		zx_handle_close(handle);
34 	}
35 
init(bool initialValue)36 	VkResult init(bool initialValue) override
37 	{
38 		zx_status_t status = zx_event_create(0, &handle);
39 		if(status != ZX_OK)
40 		{
41 			TRACE("zx_event_create() returned %d", status);
42 			return VK_ERROR_INITIALIZATION_FAILED;
43 		}
44 		if(initialValue)
45 		{
46 			status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
47 			if(status != ZX_OK)
48 			{
49 				TRACE("zx_object_signal() returned %d", status);
50 				zx_handle_close(handle);
51 				handle = ZX_HANDLE_INVALID;
52 				return VK_ERROR_INITIALIZATION_FAILED;
53 			}
54 		}
55 		return VK_SUCCESS;
56 	}
57 
importHandle(zx_handle_t new_handle)58 	VkResult importHandle(zx_handle_t new_handle) override
59 	{
60 		zx_handle_close(handle);
61 		handle = new_handle;
62 		return VK_SUCCESS;
63 	}
64 
exportHandle(zx_handle_t * pHandle)65 	VkResult exportHandle(zx_handle_t *pHandle) override
66 	{
67 		zx_handle_t new_handle = ZX_HANDLE_INVALID;
68 		zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &new_handle);
69 		if(status != ZX_OK)
70 		{
71 			DABORT("zx_handle_duplicate() returned %d", status);
72 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
73 		}
74 		*pHandle = new_handle;
75 		return VK_SUCCESS;
76 	}
77 
wait()78 	void wait() override
79 	{
80 		zx_signals_t observed = 0;
81 		zx_status_t status = zx_object_wait_one(
82 		    handle, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, &observed);
83 		if(status != ZX_OK)
84 		{
85 			DABORT("zx_object_wait_one() returned %d", status);
86 			return;
87 		}
88 		if(observed != ZX_EVENT_SIGNALED)
89 		{
90 			DABORT("zx_object_wait_one() returned observed %x (%x expected)", observed, ZX_EVENT_SIGNALED);
91 			return;
92 		}
93 		// Need to unsignal the event now, as required by the Vulkan spec.
94 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
95 		if(status != ZX_OK)
96 		{
97 			DABORT("zx_object_signal() returned %d", status);
98 			return;
99 		}
100 	}
101 
tryWait()102 	bool tryWait() override
103 	{
104 		zx_signals_t observed = 0;
105 		zx_status_t status = zx_object_wait_one(
106 		    handle, ZX_EVENT_SIGNALED, zx_clock_get_monotonic(), &observed);
107 		if(status != ZX_OK && status != ZX_ERR_TIMED_OUT)
108 		{
109 			DABORT("zx_object_wait_one() returned %d", status);
110 			return false;
111 		}
112 		if(observed != ZX_EVENT_SIGNALED)
113 		{
114 			return false;
115 		}
116 		// Need to unsignal the event now, as required by the Vulkan spec.
117 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
118 		if(status != ZX_OK)
119 		{
120 			DABORT("zx_object_signal() returned %d", status);
121 			return false;
122 		}
123 		return true;
124 	}
125 
signal()126 	void signal() override
127 	{
128 		zx_status_t status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
129 		if(status != ZX_OK)
130 		{
131 			DABORT("zx_object_signal() returned %d", status);
132 		}
133 	}
134 
135 private:
136 	zx_handle_t handle = ZX_HANDLE_INVALID;
137 };
138 
139 }  // namespace vk
140 
141 #endif  // VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
142