1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2021 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker // dispatch.cpp: Implements a function to fetch the ANGLE OpenCL dispatch table. 7*8975f5c5SAndroid Build Coastguard Worker 8*8975f5c5SAndroid Build Coastguard Worker #include "libOpenCL/dispatch.h" 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/no_destructor.h" 11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h" 12*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h" 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker #include <memory> 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker #ifdef _WIN32 17*8975f5c5SAndroid Build Coastguard Worker # include <windows.h> 18*8975f5c5SAndroid Build Coastguard Worker #endif 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard Worker namespace cl 21*8975f5c5SAndroid Build Coastguard Worker { 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker namespace 24*8975f5c5SAndroid Build Coastguard Worker { 25*8975f5c5SAndroid Build Coastguard Worker EntryPointsLib()26*8975f5c5SAndroid Build Coastguard Workerstd::unique_ptr<angle::Library> &EntryPointsLib() 27*8975f5c5SAndroid Build Coastguard Worker { 28*8975f5c5SAndroid Build Coastguard Worker static angle::base::NoDestructor<std::unique_ptr<angle::Library>> sEntryPointsLib; 29*8975f5c5SAndroid Build Coastguard Worker return *sEntryPointsLib; 30*8975f5c5SAndroid Build Coastguard Worker } 31*8975f5c5SAndroid Build Coastguard Worker CreateDispatch()32*8975f5c5SAndroid Build Coastguard WorkerIcdDispatch CreateDispatch() 33*8975f5c5SAndroid Build Coastguard Worker { 34*8975f5c5SAndroid Build Coastguard Worker const cl_icd_dispatch *clIcdDispatch = nullptr; 35*8975f5c5SAndroid Build Coastguard Worker const char *error = nullptr; 36*8975f5c5SAndroid Build Coastguard Worker 37*8975f5c5SAndroid Build Coastguard Worker // Try to find ANGLE's GLESv2 library in the consistent way, which might fail 38*8975f5c5SAndroid Build Coastguard Worker // if the current library or a link to it is not in ANGLE's binary directory 39*8975f5c5SAndroid Build Coastguard Worker EntryPointsLib().reset( 40*8975f5c5SAndroid Build Coastguard Worker angle::OpenSharedLibrary(ANGLE_GLESV2_LIBRARY_NAME, angle::SearchType::ModuleDir)); 41*8975f5c5SAndroid Build Coastguard Worker if (EntryPointsLib() && EntryPointsLib()->getNative() != nullptr) 42*8975f5c5SAndroid Build Coastguard Worker { 43*8975f5c5SAndroid Build Coastguard Worker EntryPointsLib()->getAs("gCLIcdDispatchTable", &clIcdDispatch); 44*8975f5c5SAndroid Build Coastguard Worker if (clIcdDispatch == nullptr) 45*8975f5c5SAndroid Build Coastguard Worker { 46*8975f5c5SAndroid Build Coastguard Worker INFO() << "Found system's instead of ANGLE's GLESv2 library"; 47*8975f5c5SAndroid Build Coastguard Worker } 48*8975f5c5SAndroid Build Coastguard Worker } 49*8975f5c5SAndroid Build Coastguard Worker else 50*8975f5c5SAndroid Build Coastguard Worker { 51*8975f5c5SAndroid Build Coastguard Worker error = "Not able to find GLESv2 library"; 52*8975f5c5SAndroid Build Coastguard Worker } 53*8975f5c5SAndroid Build Coastguard Worker 54*8975f5c5SAndroid Build Coastguard Worker // If not found try to find ANGLE's GLESv2 library in build path 55*8975f5c5SAndroid Build Coastguard Worker if (clIcdDispatch == nullptr) 56*8975f5c5SAndroid Build Coastguard Worker { 57*8975f5c5SAndroid Build Coastguard Worker #ifdef _WIN32 58*8975f5c5SAndroid Build Coastguard Worker // On Windows the build path 'ANGLE_GLESV2_LIBRARY_PATH' is provided by the build system 59*8975f5c5SAndroid Build Coastguard Worker const char path[] = ANGLE_GLESV2_LIBRARY_PATH "\\" ANGLE_GLESV2_LIBRARY_NAME ".dll"; 60*8975f5c5SAndroid Build Coastguard Worker // This function allows to load further dependent libraries from the same directory 61*8975f5c5SAndroid Build Coastguard Worker HMODULE handle = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 62*8975f5c5SAndroid Build Coastguard Worker if (handle != nullptr) 63*8975f5c5SAndroid Build Coastguard Worker { 64*8975f5c5SAndroid Build Coastguard Worker clIcdDispatch = reinterpret_cast<const cl_icd_dispatch *>( 65*8975f5c5SAndroid Build Coastguard Worker GetProcAddress(handle, "gCLIcdDispatchTable")); 66*8975f5c5SAndroid Build Coastguard Worker if (clIcdDispatch == nullptr) 67*8975f5c5SAndroid Build Coastguard Worker { 68*8975f5c5SAndroid Build Coastguard Worker error = "Error loading CL dispatch table."; 69*8975f5c5SAndroid Build Coastguard Worker } 70*8975f5c5SAndroid Build Coastguard Worker } 71*8975f5c5SAndroid Build Coastguard Worker #else 72*8975f5c5SAndroid Build Coastguard Worker // On posix-compatible systems this will also search in the rpath, which is the build path 73*8975f5c5SAndroid Build Coastguard Worker EntryPointsLib().reset( 74*8975f5c5SAndroid Build Coastguard Worker angle::OpenSharedLibrary(ANGLE_GLESV2_LIBRARY_NAME, angle::SearchType::SystemDir)); 75*8975f5c5SAndroid Build Coastguard Worker if (EntryPointsLib() && EntryPointsLib()->getNative() != nullptr) 76*8975f5c5SAndroid Build Coastguard Worker { 77*8975f5c5SAndroid Build Coastguard Worker EntryPointsLib()->getAs("gCLIcdDispatchTable", &clIcdDispatch); 78*8975f5c5SAndroid Build Coastguard Worker if (clIcdDispatch == nullptr) 79*8975f5c5SAndroid Build Coastguard Worker { 80*8975f5c5SAndroid Build Coastguard Worker INFO() << "Found system's instead of ANGLE's GLESv2 library"; 81*8975f5c5SAndroid Build Coastguard Worker } 82*8975f5c5SAndroid Build Coastguard Worker } 83*8975f5c5SAndroid Build Coastguard Worker #endif 84*8975f5c5SAndroid Build Coastguard Worker } 85*8975f5c5SAndroid Build Coastguard Worker 86*8975f5c5SAndroid Build Coastguard Worker IcdDispatch dispatch; 87*8975f5c5SAndroid Build Coastguard Worker if (clIcdDispatch != nullptr) 88*8975f5c5SAndroid Build Coastguard Worker { 89*8975f5c5SAndroid Build Coastguard Worker static_cast<cl_icd_dispatch &>(dispatch) = *clIcdDispatch; 90*8975f5c5SAndroid Build Coastguard Worker dispatch.clIcdGetPlatformIDsKHR = reinterpret_cast<clIcdGetPlatformIDsKHR_fn>( 91*8975f5c5SAndroid Build Coastguard Worker clIcdDispatch->clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR")); 92*8975f5c5SAndroid Build Coastguard Worker } 93*8975f5c5SAndroid Build Coastguard Worker else if (error != nullptr) 94*8975f5c5SAndroid Build Coastguard Worker { 95*8975f5c5SAndroid Build Coastguard Worker ERR() << error; 96*8975f5c5SAndroid Build Coastguard Worker } 97*8975f5c5SAndroid Build Coastguard Worker return dispatch; 98*8975f5c5SAndroid Build Coastguard Worker } 99*8975f5c5SAndroid Build Coastguard Worker 100*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace 101*8975f5c5SAndroid Build Coastguard Worker GetDispatch()102*8975f5c5SAndroid Build Coastguard Workerconst IcdDispatch &GetDispatch() 103*8975f5c5SAndroid Build Coastguard Worker { 104*8975f5c5SAndroid Build Coastguard Worker static const IcdDispatch sDispatch(CreateDispatch()); 105*8975f5c5SAndroid Build Coastguard Worker return sDispatch; 106*8975f5c5SAndroid Build Coastguard Worker } 107*8975f5c5SAndroid Build Coastguard Worker 108*8975f5c5SAndroid Build Coastguard Worker } // namespace cl 109