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