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