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 // CLDeviceCL.cpp: Implements the class methods for CLDeviceCL.
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLDeviceCL.h"
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/cl_util.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLDevice.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/cl_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker namespace rx
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker // Object information is queried in OpenCL by providing allocated memory into which the requested
22*8975f5c5SAndroid Build Coastguard Worker // data is copied. If the size of the data is unknown, it can be queried first with an additional
23*8975f5c5SAndroid Build Coastguard Worker // call to the same function, but without requesting the data itself. This function provides the
24*8975f5c5SAndroid Build Coastguard Worker // functionality to request and validate the size and the data.
25*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetDeviceInfo(cl_device_id device,cl::DeviceInfo name,std::vector<T> & vector)26*8975f5c5SAndroid Build Coastguard Worker bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, std::vector<T> &vector)
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker size_t size = 0u;
29*8975f5c5SAndroid Build Coastguard Worker if (device->getDispatch().clGetDeviceInfo(device, cl::ToCLenum(name), 0u, nullptr, &size) ==
30*8975f5c5SAndroid Build Coastguard Worker CL_SUCCESS &&
31*8975f5c5SAndroid Build Coastguard Worker (size % sizeof(T)) == 0u) // size has to be a multiple of the data type
32*8975f5c5SAndroid Build Coastguard Worker {
33*8975f5c5SAndroid Build Coastguard Worker vector.resize(size / sizeof(T));
34*8975f5c5SAndroid Build Coastguard Worker if (device->getDispatch().clGetDeviceInfo(device, cl::ToCLenum(name), size, vector.data(),
35*8975f5c5SAndroid Build Coastguard Worker nullptr) == CL_SUCCESS)
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker return true;
38*8975f5c5SAndroid Build Coastguard Worker }
39*8975f5c5SAndroid Build Coastguard Worker }
40*8975f5c5SAndroid Build Coastguard Worker ERR() << "Failed to query CL device info for " << name;
41*8975f5c5SAndroid Build Coastguard Worker return false;
42*8975f5c5SAndroid Build Coastguard Worker }
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker // This queries the OpenCL device info for value types with known size
45*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetDeviceInfo(cl_device_id device,cl::DeviceInfo name,T & value)46*8975f5c5SAndroid Build Coastguard Worker bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, T &value)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker if (device->getDispatch().clGetDeviceInfo(device, cl::ToCLenum(name), sizeof(T), &value,
49*8975f5c5SAndroid Build Coastguard Worker nullptr) != CL_SUCCESS)
50*8975f5c5SAndroid Build Coastguard Worker {
51*8975f5c5SAndroid Build Coastguard Worker ERR() << "Failed to query CL device info for " << name;
52*8975f5c5SAndroid Build Coastguard Worker return false;
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker return true;
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker } // namespace
58*8975f5c5SAndroid Build Coastguard Worker
~CLDeviceCL()59*8975f5c5SAndroid Build Coastguard Worker CLDeviceCL::~CLDeviceCL()
60*8975f5c5SAndroid Build Coastguard Worker {
61*8975f5c5SAndroid Build Coastguard Worker if (!mDevice.isRoot() && mNative->getDispatch().clReleaseDevice(mNative) != CL_SUCCESS)
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error while releasing CL device";
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
createInfo(cl::DeviceType type) const67*8975f5c5SAndroid Build Coastguard Worker CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker Info info(type);
70*8975f5c5SAndroid Build Coastguard Worker std::vector<char> valString;
71*8975f5c5SAndroid Build Coastguard Worker
72*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.maxWorkItemSizes))
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker return Info{};
75*8975f5c5SAndroid Build Coastguard Worker }
76*8975f5c5SAndroid Build Coastguard Worker // From the OpenCL specification for info name CL_DEVICE_MAX_WORK_ITEM_SIZES:
77*8975f5c5SAndroid Build Coastguard Worker // "The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM."
78*8975f5c5SAndroid Build Coastguard Worker // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo
79*8975f5c5SAndroid Build Coastguard Worker // Custom devices are currently not supported by this back end.
80*8975f5c5SAndroid Build Coastguard Worker if (info.maxWorkItemSizes.size() < 3u || info.maxWorkItemSizes[0] == 0u ||
81*8975f5c5SAndroid Build Coastguard Worker info.maxWorkItemSizes[1] == 0u || info.maxWorkItemSizes[2] == 0u)
82*8975f5c5SAndroid Build Coastguard Worker {
83*8975f5c5SAndroid Build Coastguard Worker ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES";
84*8975f5c5SAndroid Build Coastguard Worker return Info{};
85*8975f5c5SAndroid Build Coastguard Worker }
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.maxMemAllocSize) ||
88*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::ImageSupport, info.imageSupport) ||
89*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxWidth, info.image2D_MaxWidth) ||
90*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.image2D_MaxHeight) ||
91*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.image3D_MaxWidth) ||
92*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.image3D_MaxHeight) ||
93*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.image3D_MaxDepth) ||
94*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.memBaseAddrAlign) ||
95*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::ExecutionCapabilities, info.execCapabilities))
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker return Info{};
98*8975f5c5SAndroid Build Coastguard Worker }
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::Version, valString))
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker return Info{};
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker info.versionStr.assign(valString.data());
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker return Info{};
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker std::string extensionStr(valString.data());
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker // TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/42264583
113*8975f5c5SAndroid Build Coastguard Worker if (info.versionStr.compare(0u, 15u, "OpenCL 3.0 CUDA", 15u) == 0)
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker extensionStr.append(" cl_khr_depth_images cl_khr_image2d_from_buffer");
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker info.version = ExtractCLVersion(info.versionStr);
119*8975f5c5SAndroid Build Coastguard Worker if (info.version == 0u)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker return Info{};
122*8975f5c5SAndroid Build Coastguard Worker }
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker RemoveUnsupportedCLExtensions(extensionStr);
125*8975f5c5SAndroid Build Coastguard Worker info.initializeExtensions(std::move(extensionStr));
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker if (info.version >= CL_MAKE_VERSION(1, 2, 0))
128*8975f5c5SAndroid Build Coastguard Worker {
129*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxBufferSize, info.imageMaxBufferSize) ||
130*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxArraySize, info.imageMaxArraySize) ||
131*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernels, valString))
132*8975f5c5SAndroid Build Coastguard Worker {
133*8975f5c5SAndroid Build Coastguard Worker return Info{};
134*8975f5c5SAndroid Build Coastguard Worker }
135*8975f5c5SAndroid Build Coastguard Worker info.builtInKernels.assign(valString.data());
136*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties,
137*8975f5c5SAndroid Build Coastguard Worker info.partitionProperties) ||
138*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.partitionType))
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker return Info{};
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker }
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Worker if (info.version >= CL_MAKE_VERSION(2, 0, 0) &&
145*8975f5c5SAndroid Build Coastguard Worker (!GetDeviceInfo(mNative, cl::DeviceInfo::ImagePitchAlignment, info.imagePitchAlignment) ||
146*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::ImageBaseAddressAlignment,
147*8975f5c5SAndroid Build Coastguard Worker info.imageBaseAddressAlignment) ||
148*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::QueueOnDeviceMaxSize, info.queueOnDeviceMaxSize)))
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker return Info{};
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker if (info.version >= CL_MAKE_VERSION(2, 1, 0))
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker if (!GetDeviceInfo(mNative, cl::DeviceInfo::IL_Version, valString))
156*8975f5c5SAndroid Build Coastguard Worker {
157*8975f5c5SAndroid Build Coastguard Worker return Info{};
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker info.IL_Version.assign(valString.data());
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker if (info.version >= CL_MAKE_VERSION(3, 0, 0) &&
163*8975f5c5SAndroid Build Coastguard Worker (!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.ILsWithVersion) ||
164*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernelsWithVersion,
165*8975f5c5SAndroid Build Coastguard Worker info.builtInKernelsWithVersion) ||
166*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions, info.OpenCL_C_AllVersions) ||
167*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.OpenCL_C_Features) ||
168*8975f5c5SAndroid Build Coastguard Worker !GetDeviceInfo(mNative, cl::DeviceInfo::ExtensionsWithVersion,
169*8975f5c5SAndroid Build Coastguard Worker info.extensionsWithVersion)))
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker return Info{};
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker RemoveUnsupportedCLExtensions(info.extensionsWithVersion);
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker return info;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
getInfoUInt(cl::DeviceInfo name,cl_uint * value) const178*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
181*8975f5c5SAndroid Build Coastguard Worker value, nullptr));
182*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
183*8975f5c5SAndroid Build Coastguard Worker }
184*8975f5c5SAndroid Build Coastguard Worker
getInfoULong(cl::DeviceInfo name,cl_ulong * value) const185*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::getInfoULong(cl::DeviceInfo name, cl_ulong *value) const
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
188*8975f5c5SAndroid Build Coastguard Worker value, nullptr));
189*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker
getInfoSizeT(cl::DeviceInfo name,size_t * value) const192*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::getInfoSizeT(cl::DeviceInfo name, size_t *value) const
193*8975f5c5SAndroid Build Coastguard Worker {
194*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
195*8975f5c5SAndroid Build Coastguard Worker value, nullptr));
196*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker
getInfoStringLength(cl::DeviceInfo name,size_t * value) const199*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::getInfoStringLength(cl::DeviceInfo name, size_t *value) const
200*8975f5c5SAndroid Build Coastguard Worker {
201*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(
202*8975f5c5SAndroid Build Coastguard Worker mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), 0u, nullptr, value));
203*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker
getInfoString(cl::DeviceInfo name,size_t size,char * value) const206*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::getInfoString(cl::DeviceInfo name, size_t size, char *value) const
207*8975f5c5SAndroid Build Coastguard Worker {
208*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(
209*8975f5c5SAndroid Build Coastguard Worker mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), size, value, nullptr));
210*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
211*8975f5c5SAndroid Build Coastguard Worker }
212*8975f5c5SAndroid Build Coastguard Worker
createSubDevices(const cl_device_partition_property * properties,cl_uint numDevices,CreateFuncs & createFuncs,cl_uint * numDevicesRet)213*8975f5c5SAndroid Build Coastguard Worker angle::Result CLDeviceCL::createSubDevices(const cl_device_partition_property *properties,
214*8975f5c5SAndroid Build Coastguard Worker cl_uint numDevices,
215*8975f5c5SAndroid Build Coastguard Worker CreateFuncs &createFuncs,
216*8975f5c5SAndroid Build Coastguard Worker cl_uint *numDevicesRet)
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker if (numDevices == 0u)
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clCreateSubDevices(mNative, properties, 0u, nullptr,
221*8975f5c5SAndroid Build Coastguard Worker numDevicesRet));
222*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
223*8975f5c5SAndroid Build Coastguard Worker }
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker std::vector<cl_device_id> nativeSubDevices(numDevices, nullptr);
226*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clCreateSubDevices(mNative, properties, numDevices,
227*8975f5c5SAndroid Build Coastguard Worker nativeSubDevices.data(), nullptr));
228*8975f5c5SAndroid Build Coastguard Worker
229*8975f5c5SAndroid Build Coastguard Worker for (cl_device_id nativeSubDevice : nativeSubDevices)
230*8975f5c5SAndroid Build Coastguard Worker {
231*8975f5c5SAndroid Build Coastguard Worker createFuncs.emplace_back([nativeSubDevice](const cl::Device &device) {
232*8975f5c5SAndroid Build Coastguard Worker return Ptr(new CLDeviceCL(device, nativeSubDevice));
233*8975f5c5SAndroid Build Coastguard Worker });
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
236*8975f5c5SAndroid Build Coastguard Worker }
237*8975f5c5SAndroid Build Coastguard Worker
CLDeviceCL(const cl::Device & device,cl_device_id native)238*8975f5c5SAndroid Build Coastguard Worker CLDeviceCL::CLDeviceCL(const cl::Device &device, cl_device_id native)
239*8975f5c5SAndroid Build Coastguard Worker : CLDeviceImpl(device), mNative(native)
240*8975f5c5SAndroid Build Coastguard Worker {}
241*8975f5c5SAndroid Build Coastguard Worker
242*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
243