• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_TEMP_ZIRCON_EVENT_BIT_FUCHSIA
25 // which is not official yet but used by Fuchsia at the moment.
26 
27 namespace vk {
28 
29 class ZirconEventExternalSemaphore : public BinarySemaphore::External
30 {
31 public:
~ZirconEventExternalSemaphore()32 	~ZirconEventExternalSemaphore()
33 	{
34 		zx_handle_close(handle);
35 	}
36 
init(bool initialValue)37 	VkResult init(bool initialValue) override
38 	{
39 		zx_status_t status = zx_event_create(0, &handle);
40 		if(status != ZX_OK)
41 		{
42 			TRACE("zx_event_create() returned %d", status);
43 			return VK_ERROR_INITIALIZATION_FAILED;
44 		}
45 		if(initialValue)
46 		{
47 			status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
48 			if(status != ZX_OK)
49 			{
50 				TRACE("zx_object_signal() returned %d", status);
51 				zx_handle_close(handle);
52 				handle = ZX_HANDLE_INVALID;
53 				return VK_ERROR_INITIALIZATION_FAILED;
54 			}
55 		}
56 		return VK_SUCCESS;
57 	}
58 
importHandle(zx_handle_t new_handle)59 	VkResult importHandle(zx_handle_t new_handle) override
60 	{
61 		zx_handle_close(handle);
62 		handle = new_handle;
63 		return VK_SUCCESS;
64 	}
65 
exportHandle(zx_handle_t * pHandle)66 	VkResult exportHandle(zx_handle_t *pHandle) override
67 	{
68 		zx_handle_t new_handle = ZX_HANDLE_INVALID;
69 		zx_status_t status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &new_handle);
70 		if(status != ZX_OK)
71 		{
72 			DABORT("zx_handle_duplicate() returned %d", status);
73 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
74 		}
75 		*pHandle = new_handle;
76 		return VK_SUCCESS;
77 	}
78 
wait()79 	void wait() override
80 	{
81 		zx_signals_t observed = 0;
82 		zx_status_t status = zx_object_wait_one(
83 		    handle, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, &observed);
84 		if(status != ZX_OK)
85 		{
86 			DABORT("zx_object_wait_one() returned %d", status);
87 			return;
88 		}
89 		if(observed != ZX_EVENT_SIGNALED)
90 		{
91 			DABORT("zx_object_wait_one() returned observed %x (%x expected)", observed, ZX_EVENT_SIGNALED);
92 			return;
93 		}
94 		// Need to unsignal the event now, as required by the Vulkan spec.
95 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
96 		if(status != ZX_OK)
97 		{
98 			DABORT("zx_object_signal() returned %d", status);
99 			return;
100 		}
101 	}
102 
tryWait()103 	bool tryWait() override
104 	{
105 		zx_signals_t observed = 0;
106 		zx_status_t status = zx_object_wait_one(
107 		    handle, ZX_EVENT_SIGNALED, zx_clock_get_monotonic(), &observed);
108 		if(status != ZX_OK && status != ZX_ERR_TIMED_OUT)
109 		{
110 			DABORT("zx_object_wait_one() returned %d", status);
111 			return false;
112 		}
113 		if(observed != ZX_EVENT_SIGNALED)
114 		{
115 			return false;
116 		}
117 		// Need to unsignal the event now, as required by the Vulkan spec.
118 		status = zx_object_signal(handle, ZX_EVENT_SIGNALED, 0);
119 		if(status != ZX_OK)
120 		{
121 			DABORT("zx_object_signal() returned %d", status);
122 			return false;
123 		}
124 		return true;
125 	}
126 
signal()127 	void signal() override
128 	{
129 		zx_status_t status = zx_object_signal(handle, 0, ZX_EVENT_SIGNALED);
130 		if(status != ZX_OK)
131 		{
132 			DABORT("zx_object_signal() returned %d", status);
133 		}
134 	}
135 
136 private:
137 	zx_handle_t handle = ZX_HANDLE_INVALID;
138 };
139 
140 }  // namespace vk
141 
142 #endif  // VK_SEMAPHORE_EXTERNAL_FUCHSIA_H_
143