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