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 // CLPlatform.h: Defines the cl::Platform class, which provides information about platform-specific
7 // OpenCL features.
8 
9 #ifndef LIBANGLE_CLPLATFORM_H_
10 #define LIBANGLE_CLPLATFORM_H_
11 
12 #include "libANGLE/CLObject.h"
13 #include "libANGLE/renderer/CLPlatformImpl.h"
14 
15 #include "anglebase/no_destructor.h"
16 
17 namespace cl
18 {
19 
20 class Platform final : public _cl_platform_id, public Object
21 {
22   public:
23     // Front end entry functions, only called from OpenCL entry points
24 
25     static void Initialize(const cl_icd_dispatch &dispatch,
26                            rx::CLPlatformImpl::CreateFuncs &&createFuncs);
27 
28     static Platform *GetDefault();
29     static Platform *CastOrDefault(cl_platform_id platform);
30     static bool IsValidOrDefault(const _cl_platform_id *platform);
31 
32     static cl_int GetPlatformIDs(cl_uint numEntries,
33                                  cl_platform_id *platforms,
34                                  cl_uint *numPlatforms);
35 
36     cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
37 
38     cl_int getDeviceIDs(DeviceType deviceType,
39                         cl_uint numEntries,
40                         cl_device_id *devices,
41                         cl_uint *numDevices) const;
42 
43     static cl_context CreateContext(const cl_context_properties *properties,
44                                     cl_uint numDevices,
45                                     const cl_device_id *devices,
46                                     ContextErrorCB notify,
47                                     void *userData,
48                                     cl_int &errorCode);
49 
50     static cl_context CreateContextFromType(const cl_context_properties *properties,
51                                             DeviceType deviceType,
52                                             ContextErrorCB notify,
53                                             void *userData,
54                                             cl_int &errorCode);
55 
56     cl_int unloadCompiler();
57 
58   public:
59     ~Platform() override;
60 
61     const rx::CLPlatformImpl::Info &getInfo() const;
62     cl_version getVersion() const;
63     bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
64     const DevicePtrs &getDevices() const;
65 
66     template <typename T = rx::CLPlatformImpl>
67     T &getImpl() const;
68 
69     static const PlatformPtrs &GetPlatforms();
70 
71     static constexpr const char *GetVendor();
72 
73   private:
74     explicit Platform(const rx::CLPlatformImpl::CreateFunc &createFunc);
75 
76     DevicePtrs createDevices(rx::CLDeviceImpl::CreateDatas &&createDatas);
77 
78     static PlatformPtrs &GetPointers();
79 
80     const rx::CLPlatformImpl::Ptr mImpl;
81     const rx::CLPlatformImpl::Info mInfo;
82     const DevicePtrs mDevices;
83 
84     static constexpr char kVendor[]    = "ANGLE";
85     static constexpr char kIcdSuffix[] = "ANGLE";
86 };
87 
GetDefault()88 inline Platform *Platform::GetDefault()
89 {
90     return GetPlatforms().empty() ? nullptr : GetPlatforms().front().get();
91 }
92 
CastOrDefault(cl_platform_id platform)93 inline Platform *Platform::CastOrDefault(cl_platform_id platform)
94 {
95     return platform != nullptr ? &platform->cast<Platform>() : GetDefault();
96 }
97 
98 // Our CL implementation defines that a nullptr value chooses the platform that we provide as
99 // default, so this function returns true for a nullptr value if a default platform exists.
IsValidOrDefault(const _cl_platform_id * platform)100 inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform)
101 {
102     return platform != nullptr ? IsValid(platform) : GetDefault() != nullptr;
103 }
104 
getInfo()105 inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
106 {
107     return mInfo;
108 }
109 
getVersion()110 inline cl_version Platform::getVersion() const
111 {
112     return mInfo.version;
113 }
114 
isVersionOrNewer(cl_uint major,cl_uint minor)115 inline bool Platform::isVersionOrNewer(cl_uint major, cl_uint minor) const
116 {
117     return mInfo.version >= CL_MAKE_VERSION(major, minor, 0u);
118 }
119 
getDevices()120 inline const DevicePtrs &Platform::getDevices() const
121 {
122     return mDevices;
123 }
124 
125 template <typename T>
getImpl()126 inline T &Platform::getImpl() const
127 {
128     return static_cast<T &>(*mImpl);
129 }
130 
GetPlatforms()131 inline const PlatformPtrs &Platform::GetPlatforms()
132 {
133     return GetPointers();
134 }
135 
GetVendor()136 constexpr const char *Platform::GetVendor()
137 {
138     return kVendor;
139 }
140 
GetPointers()141 inline PlatformPtrs &Platform::GetPointers()
142 {
143     static angle::base::NoDestructor<PlatformPtrs> sPointers;
144     return *sPointers;
145 }
146 
147 }  // namespace cl
148 
149 #endif  // LIBANGLE_CLPLATFORM_H_
150