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