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 // CLKernelCL.cpp: Implements the class methods for CLKernelCL.
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLKernelCL.h"
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLCommandQueueCL.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLContextCL.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLDeviceCL.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLMemoryCL.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/cl/CLSamplerCL.h"
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLCommandQueue.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLContext.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLKernel.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLMemory.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLPlatform.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLProgram.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/CLSampler.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/cl_utils.h"
24*8975f5c5SAndroid Build Coastguard Worker
25*8975f5c5SAndroid Build Coastguard Worker namespace rx
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker namespace
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetWorkGroupInfo(cl_kernel kernel,cl_device_id device,cl::KernelWorkGroupInfo name,T & value,cl_int & errorCode)32*8975f5c5SAndroid Build Coastguard Worker bool GetWorkGroupInfo(cl_kernel kernel,
33*8975f5c5SAndroid Build Coastguard Worker cl_device_id device,
34*8975f5c5SAndroid Build Coastguard Worker cl::KernelWorkGroupInfo name,
35*8975f5c5SAndroid Build Coastguard Worker T &value,
36*8975f5c5SAndroid Build Coastguard Worker cl_int &errorCode)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelWorkGroupInfo(kernel, device, cl::ToCLenum(name),
39*8975f5c5SAndroid Build Coastguard Worker sizeof(T), &value, nullptr);
40*8975f5c5SAndroid Build Coastguard Worker return errorCode == CL_SUCCESS;
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetArgInfo(cl_kernel kernel,cl_uint index,cl::KernelArgInfo name,T & value,cl_int & errorCode)44*8975f5c5SAndroid Build Coastguard Worker bool GetArgInfo(cl_kernel kernel,
45*8975f5c5SAndroid Build Coastguard Worker cl_uint index,
46*8975f5c5SAndroid Build Coastguard Worker cl::KernelArgInfo name,
47*8975f5c5SAndroid Build Coastguard Worker T &value,
48*8975f5c5SAndroid Build Coastguard Worker cl_int &errorCode)
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelArgInfo(kernel, index, cl::ToCLenum(name),
51*8975f5c5SAndroid Build Coastguard Worker sizeof(T), &value, nullptr);
52*8975f5c5SAndroid Build Coastguard Worker if (errorCode == CL_KERNEL_ARG_INFO_NOT_AVAILABLE)
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker errorCode = CL_SUCCESS;
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker return errorCode == CL_SUCCESS;
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker
59*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetKernelInfo(cl_kernel kernel,cl::KernelInfo name,T & value,cl_int & errorCode)60*8975f5c5SAndroid Build Coastguard Worker bool GetKernelInfo(cl_kernel kernel, cl::KernelInfo name, T &value, cl_int &errorCode)
61*8975f5c5SAndroid Build Coastguard Worker {
62*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelInfo(kernel, cl::ToCLenum(name), sizeof(T), &value,
63*8975f5c5SAndroid Build Coastguard Worker nullptr);
64*8975f5c5SAndroid Build Coastguard Worker return errorCode == CL_SUCCESS;
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
GetArgString(cl_kernel kernel,cl_uint index,cl::KernelArgInfo name,std::string & string,cl_int & errorCode)67*8975f5c5SAndroid Build Coastguard Worker bool GetArgString(cl_kernel kernel,
68*8975f5c5SAndroid Build Coastguard Worker cl_uint index,
69*8975f5c5SAndroid Build Coastguard Worker cl::KernelArgInfo name,
70*8975f5c5SAndroid Build Coastguard Worker std::string &string,
71*8975f5c5SAndroid Build Coastguard Worker cl_int &errorCode)
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker size_t size = 0u;
74*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelArgInfo(kernel, index, cl::ToCLenum(name), 0u,
75*8975f5c5SAndroid Build Coastguard Worker nullptr, &size);
76*8975f5c5SAndroid Build Coastguard Worker if (errorCode == CL_KERNEL_ARG_INFO_NOT_AVAILABLE)
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker errorCode = CL_SUCCESS;
79*8975f5c5SAndroid Build Coastguard Worker return true;
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker else if (errorCode != CL_SUCCESS)
82*8975f5c5SAndroid Build Coastguard Worker {
83*8975f5c5SAndroid Build Coastguard Worker return false;
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker std::vector<char> valString(size, '\0');
86*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelArgInfo(kernel, index, cl::ToCLenum(name), size,
87*8975f5c5SAndroid Build Coastguard Worker valString.data(), nullptr);
88*8975f5c5SAndroid Build Coastguard Worker if (errorCode != CL_SUCCESS)
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker return false;
91*8975f5c5SAndroid Build Coastguard Worker }
92*8975f5c5SAndroid Build Coastguard Worker string.assign(valString.data(), valString.size() - 1u);
93*8975f5c5SAndroid Build Coastguard Worker return true;
94*8975f5c5SAndroid Build Coastguard Worker }
95*8975f5c5SAndroid Build Coastguard Worker
GetKernelString(cl_kernel kernel,cl::KernelInfo name,std::string & string,cl_int & errorCode)96*8975f5c5SAndroid Build Coastguard Worker bool GetKernelString(cl_kernel kernel, cl::KernelInfo name, std::string &string, cl_int &errorCode)
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker size_t size = 0u;
99*8975f5c5SAndroid Build Coastguard Worker errorCode =
100*8975f5c5SAndroid Build Coastguard Worker kernel->getDispatch().clGetKernelInfo(kernel, cl::ToCLenum(name), 0u, nullptr, &size);
101*8975f5c5SAndroid Build Coastguard Worker if (errorCode != CL_SUCCESS)
102*8975f5c5SAndroid Build Coastguard Worker {
103*8975f5c5SAndroid Build Coastguard Worker return false;
104*8975f5c5SAndroid Build Coastguard Worker }
105*8975f5c5SAndroid Build Coastguard Worker std::vector<char> valString(size, '\0');
106*8975f5c5SAndroid Build Coastguard Worker errorCode = kernel->getDispatch().clGetKernelInfo(kernel, cl::ToCLenum(name), size,
107*8975f5c5SAndroid Build Coastguard Worker valString.data(), nullptr);
108*8975f5c5SAndroid Build Coastguard Worker if (errorCode != CL_SUCCESS)
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker return false;
111*8975f5c5SAndroid Build Coastguard Worker }
112*8975f5c5SAndroid Build Coastguard Worker string.assign(valString.data(), valString.size() - 1u);
113*8975f5c5SAndroid Build Coastguard Worker return true;
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker } // namespace
117*8975f5c5SAndroid Build Coastguard Worker
CLKernelCL(const cl::Kernel & kernel,cl_kernel native)118*8975f5c5SAndroid Build Coastguard Worker CLKernelCL::CLKernelCL(const cl::Kernel &kernel, cl_kernel native)
119*8975f5c5SAndroid Build Coastguard Worker : CLKernelImpl(kernel), mNative(native)
120*8975f5c5SAndroid Build Coastguard Worker {}
121*8975f5c5SAndroid Build Coastguard Worker
~CLKernelCL()122*8975f5c5SAndroid Build Coastguard Worker CLKernelCL::~CLKernelCL()
123*8975f5c5SAndroid Build Coastguard Worker {
124*8975f5c5SAndroid Build Coastguard Worker if (mNative->getDispatch().clReleaseKernel(mNative) != CL_SUCCESS)
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error while releasing CL kernel";
127*8975f5c5SAndroid Build Coastguard Worker }
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker
setArg(cl_uint argIndex,size_t argSize,const void * argValue)130*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelCL::setArg(cl_uint argIndex, size_t argSize, const void *argValue)
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker void *value = nullptr;
133*8975f5c5SAndroid Build Coastguard Worker if (argValue != nullptr)
134*8975f5c5SAndroid Build Coastguard Worker {
135*8975f5c5SAndroid Build Coastguard Worker // If argument is a CL object, fetch the mapped value
136*8975f5c5SAndroid Build Coastguard Worker const CLContextCL &ctx = mKernel.getProgram().getContext().getImpl<CLContextCL>();
137*8975f5c5SAndroid Build Coastguard Worker if (argSize == sizeof(cl_mem))
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker cl_mem memory = *static_cast<const cl_mem *>(argValue);
140*8975f5c5SAndroid Build Coastguard Worker if (ctx.hasMemory(memory))
141*8975f5c5SAndroid Build Coastguard Worker {
142*8975f5c5SAndroid Build Coastguard Worker value = memory->cast<cl::Memory>().getImpl<CLMemoryCL>().getNative();
143*8975f5c5SAndroid Build Coastguard Worker }
144*8975f5c5SAndroid Build Coastguard Worker }
145*8975f5c5SAndroid Build Coastguard Worker if (value == nullptr && argSize == sizeof(cl_sampler))
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker cl_sampler sampler = *static_cast<const cl_sampler *>(argValue);
148*8975f5c5SAndroid Build Coastguard Worker if (ctx.hasSampler(sampler))
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker value = sampler->cast<cl::Sampler>().getImpl<CLSamplerCL>().getNative();
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker }
153*8975f5c5SAndroid Build Coastguard Worker if (value == nullptr && argSize == sizeof(cl_command_queue))
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker cl_command_queue queue = *static_cast<const cl_command_queue *>(argValue);
156*8975f5c5SAndroid Build Coastguard Worker if (ctx.hasDeviceQueue(queue))
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker value = queue->cast<cl::CommandQueue>().getImpl<CLCommandQueueCL>().getNative();
159*8975f5c5SAndroid Build Coastguard Worker }
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker // If mapped value was found, use it instead of original value
164*8975f5c5SAndroid Build Coastguard Worker if (value != nullptr)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker argValue = &value;
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_TRY(mNative->getDispatch().clSetKernelArg(mNative, argIndex, argSize, argValue));
169*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker
createInfo(CLKernelImpl::Info * infoOut) const172*8975f5c5SAndroid Build Coastguard Worker angle::Result CLKernelCL::createInfo(CLKernelImpl::Info *infoOut) const
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker cl_int errorCode = CL_SUCCESS;
175*8975f5c5SAndroid Build Coastguard Worker const cl::Context &ctx = mKernel.getProgram().getContext();
176*8975f5c5SAndroid Build Coastguard Worker
177*8975f5c5SAndroid Build Coastguard Worker if (!GetKernelString(mNative, cl::KernelInfo::FunctionName, infoOut->functionName, errorCode) ||
178*8975f5c5SAndroid Build Coastguard Worker !GetKernelInfo(mNative, cl::KernelInfo::NumArgs, infoOut->numArgs, errorCode) ||
179*8975f5c5SAndroid Build Coastguard Worker (ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
180*8975f5c5SAndroid Build Coastguard Worker !GetKernelString(mNative, cl::KernelInfo::Attributes, infoOut->attributes, errorCode)))
181*8975f5c5SAndroid Build Coastguard Worker {
182*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(errorCode);
183*8975f5c5SAndroid Build Coastguard Worker }
184*8975f5c5SAndroid Build Coastguard Worker
185*8975f5c5SAndroid Build Coastguard Worker infoOut->workGroups.resize(ctx.getDevices().size());
186*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0u; index < ctx.getDevices().size(); ++index)
187*8975f5c5SAndroid Build Coastguard Worker {
188*8975f5c5SAndroid Build Coastguard Worker const cl_device_id device = ctx.getDevices()[index]->getImpl<CLDeviceCL>().getNative();
189*8975f5c5SAndroid Build Coastguard Worker WorkGroupInfo &workGroup = infoOut->workGroups[index];
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker if ((ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
192*8975f5c5SAndroid Build Coastguard Worker ctx.getDevices()[index]->supportsBuiltInKernel(infoOut->functionName) &&
193*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::GlobalWorkSize,
194*8975f5c5SAndroid Build Coastguard Worker workGroup.globalWorkSize, errorCode)) ||
195*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::WorkGroupSize,
196*8975f5c5SAndroid Build Coastguard Worker workGroup.workGroupSize, errorCode) ||
197*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::CompileWorkGroupSize,
198*8975f5c5SAndroid Build Coastguard Worker workGroup.compileWorkGroupSize, errorCode) ||
199*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::LocalMemSize,
200*8975f5c5SAndroid Build Coastguard Worker workGroup.localMemSize, errorCode) ||
201*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device,
202*8975f5c5SAndroid Build Coastguard Worker cl::KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple,
203*8975f5c5SAndroid Build Coastguard Worker workGroup.prefWorkGroupSizeMultiple, errorCode) ||
204*8975f5c5SAndroid Build Coastguard Worker !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::PrivateMemSize,
205*8975f5c5SAndroid Build Coastguard Worker workGroup.privateMemSize, errorCode))
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(errorCode);
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker }
210*8975f5c5SAndroid Build Coastguard Worker
211*8975f5c5SAndroid Build Coastguard Worker infoOut->args.resize(infoOut->numArgs);
212*8975f5c5SAndroid Build Coastguard Worker if (ctx.getPlatform().isVersionOrNewer(1u, 2u))
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker for (cl_uint index = 0u; index < infoOut->numArgs; ++index)
215*8975f5c5SAndroid Build Coastguard Worker {
216*8975f5c5SAndroid Build Coastguard Worker ArgInfo &arg = infoOut->args[index];
217*8975f5c5SAndroid Build Coastguard Worker if (!GetArgInfo(mNative, index, cl::KernelArgInfo::AddressQualifier,
218*8975f5c5SAndroid Build Coastguard Worker arg.addressQualifier, errorCode) ||
219*8975f5c5SAndroid Build Coastguard Worker !GetArgInfo(mNative, index, cl::KernelArgInfo::AccessQualifier, arg.accessQualifier,
220*8975f5c5SAndroid Build Coastguard Worker errorCode) ||
221*8975f5c5SAndroid Build Coastguard Worker !GetArgString(mNative, index, cl::KernelArgInfo::TypeName, arg.typeName,
222*8975f5c5SAndroid Build Coastguard Worker errorCode) ||
223*8975f5c5SAndroid Build Coastguard Worker !GetArgInfo(mNative, index, cl::KernelArgInfo::TypeQualifier, arg.typeQualifier,
224*8975f5c5SAndroid Build Coastguard Worker errorCode) ||
225*8975f5c5SAndroid Build Coastguard Worker !GetArgString(mNative, index, cl::KernelArgInfo::Name, arg.name, errorCode))
226*8975f5c5SAndroid Build Coastguard Worker {
227*8975f5c5SAndroid Build Coastguard Worker ANGLE_CL_RETURN_ERROR(errorCode);
228*8975f5c5SAndroid Build Coastguard Worker }
229*8975f5c5SAndroid Build Coastguard Worker }
230*8975f5c5SAndroid Build Coastguard Worker }
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
236