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 // CLPlatform.cpp: Implements the cl::Platform class.
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLPlatform.h"
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLContext.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLDevice.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/cl_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker #include <cstring>
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker namespace cl
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker
IsDeviceTypeMatch(DeviceType select,DeviceType type)22*8975f5c5SAndroid Build Coastguard Worker bool IsDeviceTypeMatch(DeviceType select, DeviceType type)
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker // The type 'DeviceType' is a bitfield, so it matches if any selected bit is set.
25*8975f5c5SAndroid Build Coastguard Worker // A custom device is an exception, which only matches if it was explicitely selected, see:
26*8975f5c5SAndroid Build Coastguard Worker // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceIDs
27*8975f5c5SAndroid Build Coastguard Worker return type == CL_DEVICE_TYPE_CUSTOM ? select == CL_DEVICE_TYPE_CUSTOM
28*8975f5c5SAndroid Build Coastguard Worker : type.intersects(select);
29*8975f5c5SAndroid Build Coastguard Worker }
30*8975f5c5SAndroid Build Coastguard Worker
ParseContextProperties(const cl_context_properties * properties,Platform * & platform,bool & userSync)31*8975f5c5SAndroid Build Coastguard Worker Context::PropArray ParseContextProperties(const cl_context_properties *properties,
32*8975f5c5SAndroid Build Coastguard Worker Platform *&platform,
33*8975f5c5SAndroid Build Coastguard Worker bool &userSync)
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker Context::PropArray propArray;
36*8975f5c5SAndroid Build Coastguard Worker if (properties != nullptr)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker const cl_context_properties *propIt = properties;
39*8975f5c5SAndroid Build Coastguard Worker while (*propIt != 0)
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker switch (*propIt++)
42*8975f5c5SAndroid Build Coastguard Worker {
43*8975f5c5SAndroid Build Coastguard Worker case CL_CONTEXT_PLATFORM:
44*8975f5c5SAndroid Build Coastguard Worker platform = &reinterpret_cast<cl_platform_id>(*propIt++)->cast<Platform>();
45*8975f5c5SAndroid Build Coastguard Worker break;
46*8975f5c5SAndroid Build Coastguard Worker case CL_CONTEXT_INTEROP_USER_SYNC:
47*8975f5c5SAndroid Build Coastguard Worker userSync = *propIt++ != CL_FALSE;
48*8975f5c5SAndroid Build Coastguard Worker break;
49*8975f5c5SAndroid Build Coastguard Worker }
50*8975f5c5SAndroid Build Coastguard Worker }
51*8975f5c5SAndroid Build Coastguard Worker // Include the trailing zero
52*8975f5c5SAndroid Build Coastguard Worker ++propIt;
53*8975f5c5SAndroid Build Coastguard Worker propArray.reserve(propIt - properties);
54*8975f5c5SAndroid Build Coastguard Worker propArray.insert(propArray.cend(), properties, propIt);
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker return propArray;
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker
59*8975f5c5SAndroid Build Coastguard Worker } // namespace
60*8975f5c5SAndroid Build Coastguard Worker
Initialize(const cl_icd_dispatch & dispatch,rx::CLPlatformImpl::CreateFuncs && createFuncs)61*8975f5c5SAndroid Build Coastguard Worker void Platform::Initialize(const cl_icd_dispatch &dispatch,
62*8975f5c5SAndroid Build Coastguard Worker rx::CLPlatformImpl::CreateFuncs &&createFuncs)
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker PlatformPtrs &platforms = GetPointers();
65*8975f5c5SAndroid Build Coastguard Worker ASSERT(_cl_platform_id::sDispatch == nullptr && platforms.empty());
66*8975f5c5SAndroid Build Coastguard Worker if (_cl_platform_id::sDispatch != nullptr || !platforms.empty())
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker ERR() << "Already initialized";
69*8975f5c5SAndroid Build Coastguard Worker return;
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker Dispatch::sDispatch = &dispatch;
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Worker platforms.reserve(createFuncs.size());
74*8975f5c5SAndroid Build Coastguard Worker while (!createFuncs.empty())
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker platforms.emplace_back(new Platform(createFuncs.front()));
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker // Release initialization reference, lifetime controlled by RefPointer.
79*8975f5c5SAndroid Build Coastguard Worker platforms.back()->release();
80*8975f5c5SAndroid Build Coastguard Worker
81*8975f5c5SAndroid Build Coastguard Worker // Remove platform on any errors
82*8975f5c5SAndroid Build Coastguard Worker if (!platforms.back()->mInfo.isValid() || platforms.back()->mDevices.empty())
83*8975f5c5SAndroid Build Coastguard Worker {
84*8975f5c5SAndroid Build Coastguard Worker platforms.pop_back();
85*8975f5c5SAndroid Build Coastguard Worker }
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker createFuncs.pop_front();
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker }
90*8975f5c5SAndroid Build Coastguard Worker
GetPlatformIDs(cl_uint numEntries,cl_platform_id * platforms,cl_uint * numPlatforms)91*8975f5c5SAndroid Build Coastguard Worker angle::Result Platform::GetPlatformIDs(cl_uint numEntries,
92*8975f5c5SAndroid Build Coastguard Worker cl_platform_id *platforms,
93*8975f5c5SAndroid Build Coastguard Worker cl_uint *numPlatforms)
94*8975f5c5SAndroid Build Coastguard Worker {
95*8975f5c5SAndroid Build Coastguard Worker const PlatformPtrs &availPlatforms = GetPlatforms();
96*8975f5c5SAndroid Build Coastguard Worker if (numPlatforms != nullptr)
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker *numPlatforms = static_cast<cl_uint>(availPlatforms.size());
99*8975f5c5SAndroid Build Coastguard Worker }
100*8975f5c5SAndroid Build Coastguard Worker if (platforms != nullptr)
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker cl_uint entry = 0u;
103*8975f5c5SAndroid Build Coastguard Worker auto platformIt = availPlatforms.cbegin();
104*8975f5c5SAndroid Build Coastguard Worker while (entry < numEntries && platformIt != availPlatforms.cend())
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker platforms[entry++] = (*platformIt++).get();
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker
getInfo(PlatformInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const112*8975f5c5SAndroid Build Coastguard Worker angle::Result Platform::getInfo(PlatformInfo name,
113*8975f5c5SAndroid Build Coastguard Worker size_t valueSize,
114*8975f5c5SAndroid Build Coastguard Worker void *value,
115*8975f5c5SAndroid Build Coastguard Worker size_t *valueSizeRet) const
116*8975f5c5SAndroid Build Coastguard Worker {
117*8975f5c5SAndroid Build Coastguard Worker const void *copyValue = nullptr;
118*8975f5c5SAndroid Build Coastguard Worker size_t copySize = 0u;
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker switch (name)
121*8975f5c5SAndroid Build Coastguard Worker {
122*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::Profile:
123*8975f5c5SAndroid Build Coastguard Worker copyValue = mInfo.profile.c_str();
124*8975f5c5SAndroid Build Coastguard Worker copySize = mInfo.profile.length() + 1u;
125*8975f5c5SAndroid Build Coastguard Worker break;
126*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::Version:
127*8975f5c5SAndroid Build Coastguard Worker copyValue = mInfo.versionStr.c_str();
128*8975f5c5SAndroid Build Coastguard Worker copySize = mInfo.versionStr.length() + 1u;
129*8975f5c5SAndroid Build Coastguard Worker break;
130*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::NumericVersion:
131*8975f5c5SAndroid Build Coastguard Worker copyValue = &mInfo.version;
132*8975f5c5SAndroid Build Coastguard Worker copySize = sizeof(mInfo.version);
133*8975f5c5SAndroid Build Coastguard Worker break;
134*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::Name:
135*8975f5c5SAndroid Build Coastguard Worker copyValue = mInfo.name.c_str();
136*8975f5c5SAndroid Build Coastguard Worker copySize = mInfo.name.length() + 1u;
137*8975f5c5SAndroid Build Coastguard Worker break;
138*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::Vendor:
139*8975f5c5SAndroid Build Coastguard Worker copyValue = kVendor;
140*8975f5c5SAndroid Build Coastguard Worker copySize = sizeof(kVendor);
141*8975f5c5SAndroid Build Coastguard Worker break;
142*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::Extensions:
143*8975f5c5SAndroid Build Coastguard Worker copyValue = mInfo.extensions.c_str();
144*8975f5c5SAndroid Build Coastguard Worker copySize = mInfo.extensions.length() + 1u;
145*8975f5c5SAndroid Build Coastguard Worker break;
146*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::ExtensionsWithVersion:
147*8975f5c5SAndroid Build Coastguard Worker copyValue = mInfo.extensionsWithVersion.data();
148*8975f5c5SAndroid Build Coastguard Worker copySize = mInfo.extensionsWithVersion.size() *
149*8975f5c5SAndroid Build Coastguard Worker sizeof(decltype(mInfo.extensionsWithVersion)::value_type);
150*8975f5c5SAndroid Build Coastguard Worker break;
151*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::HostTimerResolution:
152*8975f5c5SAndroid Build Coastguard Worker copyValue = &mInfo.hostTimerRes;
153*8975f5c5SAndroid Build Coastguard Worker copySize = sizeof(mInfo.hostTimerRes);
154*8975f5c5SAndroid Build Coastguard Worker break;
155*8975f5c5SAndroid Build Coastguard Worker case PlatformInfo::IcdSuffix:
156*8975f5c5SAndroid Build Coastguard Worker copyValue = kIcdSuffix;
157*8975f5c5SAndroid Build Coastguard Worker copySize = sizeof(kIcdSuffix);
158*8975f5c5SAndroid Build Coastguard Worker break;
159*8975f5c5SAndroid Build Coastguard Worker default:
160*8975f5c5SAndroid Build Coastguard Worker ASSERT(false);
161*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker if (value != nullptr)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
167*8975f5c5SAndroid Build Coastguard Worker // as specified in the OpenCL Platform Queries table, and param_value is not a NULL value.
168*8975f5c5SAndroid Build Coastguard Worker if (valueSize < copySize)
169*8975f5c5SAndroid Build Coastguard Worker {
170*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
171*8975f5c5SAndroid Build Coastguard Worker }
172*8975f5c5SAndroid Build Coastguard Worker if (copyValue != nullptr)
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker std::memcpy(value, copyValue, copySize);
175*8975f5c5SAndroid Build Coastguard Worker }
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker if (valueSizeRet != nullptr)
178*8975f5c5SAndroid Build Coastguard Worker {
179*8975f5c5SAndroid Build Coastguard Worker *valueSizeRet = copySize;
180*8975f5c5SAndroid Build Coastguard Worker }
181*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker
getDeviceIDs(DeviceType deviceType,cl_uint numEntries,cl_device_id * devices,cl_uint * numDevices) const184*8975f5c5SAndroid Build Coastguard Worker angle::Result Platform::getDeviceIDs(DeviceType deviceType,
185*8975f5c5SAndroid Build Coastguard Worker cl_uint numEntries,
186*8975f5c5SAndroid Build Coastguard Worker cl_device_id *devices,
187*8975f5c5SAndroid Build Coastguard Worker cl_uint *numDevices) const
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker cl_uint found = 0u;
190*8975f5c5SAndroid Build Coastguard Worker for (const DevicePtr &device : mDevices)
191*8975f5c5SAndroid Build Coastguard Worker {
192*8975f5c5SAndroid Build Coastguard Worker if (IsDeviceTypeMatch(deviceType, device->getInfo().type))
193*8975f5c5SAndroid Build Coastguard Worker {
194*8975f5c5SAndroid Build Coastguard Worker if (devices != nullptr && found < numEntries)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker devices[found] = device.get();
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker ++found;
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker }
201*8975f5c5SAndroid Build Coastguard Worker if (numDevices != nullptr)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker *numDevices = found;
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker // CL_DEVICE_NOT_FOUND if no OpenCL devices that matched device_type were found.
207*8975f5c5SAndroid Build Coastguard Worker if (found == 0u)
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(CL_DEVICE_NOT_FOUND);
210*8975f5c5SAndroid Build Coastguard Worker }
211*8975f5c5SAndroid Build Coastguard Worker
212*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
213*8975f5c5SAndroid Build Coastguard Worker }
214*8975f5c5SAndroid Build Coastguard Worker
hasDeviceType(DeviceType deviceType) const215*8975f5c5SAndroid Build Coastguard Worker bool Platform::hasDeviceType(DeviceType deviceType) const
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker for (const DevicePtr &device : mDevices)
218*8975f5c5SAndroid Build Coastguard Worker {
219*8975f5c5SAndroid Build Coastguard Worker if (IsDeviceTypeMatch(deviceType, device->getInfo().type))
220*8975f5c5SAndroid Build Coastguard Worker {
221*8975f5c5SAndroid Build Coastguard Worker return true;
222*8975f5c5SAndroid Build Coastguard Worker }
223*8975f5c5SAndroid Build Coastguard Worker }
224*8975f5c5SAndroid Build Coastguard Worker return false;
225*8975f5c5SAndroid Build Coastguard Worker }
226*8975f5c5SAndroid Build Coastguard Worker
CreateContext(const cl_context_properties * properties,cl_uint numDevices,const cl_device_id * devices,ContextErrorCB notify,void * userData)227*8975f5c5SAndroid Build Coastguard Worker cl_context Platform::CreateContext(const cl_context_properties *properties,
228*8975f5c5SAndroid Build Coastguard Worker cl_uint numDevices,
229*8975f5c5SAndroid Build Coastguard Worker const cl_device_id *devices,
230*8975f5c5SAndroid Build Coastguard Worker ContextErrorCB notify,
231*8975f5c5SAndroid Build Coastguard Worker void *userData)
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker DevicePtrs devs;
234*8975f5c5SAndroid Build Coastguard Worker devs.reserve(numDevices);
235*8975f5c5SAndroid Build Coastguard Worker while (numDevices-- != 0u)
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker devs.emplace_back(&(*devices++)->cast<Device>());
238*8975f5c5SAndroid Build Coastguard Worker }
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker Platform *platform = nullptr;
241*8975f5c5SAndroid Build Coastguard Worker bool userSync = false;
242*8975f5c5SAndroid Build Coastguard Worker Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
243*8975f5c5SAndroid Build Coastguard Worker if (platform == nullptr)
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker // All devices in the list have already been validated at this point to contain the same
246*8975f5c5SAndroid Build Coastguard Worker // platform - just use/select the first device's platform.
247*8975f5c5SAndroid Build Coastguard Worker platform = &devs.front()->getPlatform();
248*8975f5c5SAndroid Build Coastguard Worker }
249*8975f5c5SAndroid Build Coastguard Worker
250*8975f5c5SAndroid Build Coastguard Worker return Object::Create<Context>(*platform, std::move(propArray), std::move(devs), notify,
251*8975f5c5SAndroid Build Coastguard Worker userData, userSync);
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker
CreateContextFromType(const cl_context_properties * properties,DeviceType deviceType,ContextErrorCB notify,void * userData)254*8975f5c5SAndroid Build Coastguard Worker cl_context Platform::CreateContextFromType(const cl_context_properties *properties,
255*8975f5c5SAndroid Build Coastguard Worker DeviceType deviceType,
256*8975f5c5SAndroid Build Coastguard Worker ContextErrorCB notify,
257*8975f5c5SAndroid Build Coastguard Worker void *userData)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker Platform *platform = nullptr;
260*8975f5c5SAndroid Build Coastguard Worker bool userSync = false;
261*8975f5c5SAndroid Build Coastguard Worker Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
262*8975f5c5SAndroid Build Coastguard Worker
263*8975f5c5SAndroid Build Coastguard Worker // Choose default platform if user does not specify in the context properties field
264*8975f5c5SAndroid Build Coastguard Worker if (platform == nullptr)
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker platform = Platform::GetDefault();
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker
269*8975f5c5SAndroid Build Coastguard Worker return Object::Create<Context>(*platform, std::move(propArray), deviceType, notify, userData,
270*8975f5c5SAndroid Build Coastguard Worker userSync);
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker
unloadCompiler()273*8975f5c5SAndroid Build Coastguard Worker angle::Result Platform::unloadCompiler()
274*8975f5c5SAndroid Build Coastguard Worker {
275*8975f5c5SAndroid Build Coastguard Worker return mImpl->unloadCompiler();
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker
278*8975f5c5SAndroid Build Coastguard Worker Platform::~Platform() = default;
279*8975f5c5SAndroid Build Coastguard Worker
Platform(const rx::CLPlatformImpl::CreateFunc & createFunc)280*8975f5c5SAndroid Build Coastguard Worker Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc)
281*8975f5c5SAndroid Build Coastguard Worker : mImpl(createFunc(*this)),
282*8975f5c5SAndroid Build Coastguard Worker mInfo(mImpl ? mImpl->createInfo() : rx::CLPlatformImpl::Info{}),
283*8975f5c5SAndroid Build Coastguard Worker mDevices(mImpl ? createDevices(mImpl->createDevices()) : DevicePtrs{}),
284*8975f5c5SAndroid Build Coastguard Worker mMultiThreadPool(mImpl ? angle::WorkerThreadPool::Create(0, ANGLEPlatformCurrent()) : nullptr)
285*8975f5c5SAndroid Build Coastguard Worker {}
286*8975f5c5SAndroid Build Coastguard Worker
createDevices(rx::CLDeviceImpl::CreateDatas && createDatas)287*8975f5c5SAndroid Build Coastguard Worker DevicePtrs Platform::createDevices(rx::CLDeviceImpl::CreateDatas &&createDatas)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker DevicePtrs devices;
290*8975f5c5SAndroid Build Coastguard Worker devices.reserve(createDatas.size());
291*8975f5c5SAndroid Build Coastguard Worker while (!createDatas.empty())
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker devices.emplace_back(
294*8975f5c5SAndroid Build Coastguard Worker new Device(*this, nullptr, createDatas.front().first, createDatas.front().second));
295*8975f5c5SAndroid Build Coastguard Worker // Release initialization reference, lifetime controlled by RefPointer.
296*8975f5c5SAndroid Build Coastguard Worker devices.back()->release();
297*8975f5c5SAndroid Build Coastguard Worker if (!devices.back()->mInfo.isValid())
298*8975f5c5SAndroid Build Coastguard Worker {
299*8975f5c5SAndroid Build Coastguard Worker devices.pop_back();
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker createDatas.pop_front();
302*8975f5c5SAndroid Build Coastguard Worker }
303*8975f5c5SAndroid Build Coastguard Worker return devices;
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker
306*8975f5c5SAndroid Build Coastguard Worker constexpr char Platform::kVendor[];
307*8975f5c5SAndroid Build Coastguard Worker constexpr char Platform::kIcdSuffix[];
308*8975f5c5SAndroid Build Coastguard Worker
309*8975f5c5SAndroid Build Coastguard Worker } // namespace cl
310