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 // CLKernel.cpp: Implements the cl::Kernel class.
7
8 #include "libANGLE/CLKernel.h"
9
10 #include "libANGLE/CLContext.h"
11 #include "libANGLE/CLProgram.h"
12 #include "libANGLE/cl_utils.h"
13
14 #include <cstring>
15
16 namespace cl
17 {
18
setArg(cl_uint argIndex,size_t argSize,const void * argValue)19 angle::Result Kernel::setArg(cl_uint argIndex, size_t argSize, const void *argValue)
20 {
21 return mImpl->setArg(argIndex, argSize, argValue);
22 }
23
getInfo(KernelInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const24 angle::Result Kernel::getInfo(KernelInfo name,
25 size_t valueSize,
26 void *value,
27 size_t *valueSizeRet) const
28 {
29 cl_uint valUInt = 0u;
30 void *valPointer = nullptr;
31 const void *copyValue = nullptr;
32 size_t copySize = 0u;
33
34 switch (name)
35 {
36 case KernelInfo::FunctionName:
37 copyValue = mInfo.functionName.c_str();
38 copySize = mInfo.functionName.length() + 1u;
39 break;
40 case KernelInfo::NumArgs:
41 copyValue = &mInfo.numArgs;
42 copySize = sizeof(mInfo.numArgs);
43 break;
44 case KernelInfo::ReferenceCount:
45 valUInt = getRefCount();
46 copyValue = &valUInt;
47 copySize = sizeof(valUInt);
48 break;
49 case KernelInfo::Context:
50 valPointer = mProgram->getContext().getNative();
51 copyValue = &valPointer;
52 copySize = sizeof(valPointer);
53 break;
54 case KernelInfo::Program:
55 valPointer = mProgram->getNative();
56 copyValue = &valPointer;
57 copySize = sizeof(valPointer);
58 break;
59 case KernelInfo::Attributes:
60 copyValue = mInfo.attributes.c_str();
61 copySize = mInfo.attributes.length() + 1u;
62 break;
63 default:
64 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
65 }
66
67 if (value != nullptr)
68 {
69 // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
70 // as described in the Kernel Object Queries table and param_value is not NULL.
71 if (valueSize < copySize)
72 {
73 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
74 }
75 if (copyValue != nullptr)
76 {
77 std::memcpy(value, copyValue, copySize);
78 }
79 }
80 if (valueSizeRet != nullptr)
81 {
82 *valueSizeRet = copySize;
83 }
84 return angle::Result::Continue;
85 }
86
getWorkGroupInfo(cl_device_id device,KernelWorkGroupInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const87 angle::Result Kernel::getWorkGroupInfo(cl_device_id device,
88 KernelWorkGroupInfo name,
89 size_t valueSize,
90 void *value,
91 size_t *valueSizeRet) const
92 {
93 size_t index = 0u;
94 if (device != nullptr)
95 {
96 const DevicePtrs &devices = mProgram->getContext().getDevices();
97 while (index < devices.size() && devices[index] != device)
98 {
99 ++index;
100 }
101 if (index == devices.size())
102 {
103 ANGLE_CL_RETURN_ERROR(CL_INVALID_DEVICE);
104 }
105 }
106 const rx::CLKernelImpl::WorkGroupInfo &info = mInfo.workGroups[index];
107
108 const void *copyValue = nullptr;
109 size_t copySize = 0u;
110
111 switch (name)
112 {
113 case KernelWorkGroupInfo::GlobalWorkSize:
114 copyValue = &info.globalWorkSize;
115 copySize = sizeof(info.globalWorkSize);
116 break;
117 case KernelWorkGroupInfo::WorkGroupSize:
118 copyValue = &info.workGroupSize;
119 copySize = sizeof(info.workGroupSize);
120 break;
121 case KernelWorkGroupInfo::CompileWorkGroupSize:
122 copyValue = &info.compileWorkGroupSize;
123 copySize = sizeof(info.compileWorkGroupSize);
124 break;
125 case KernelWorkGroupInfo::LocalMemSize:
126 copyValue = &info.localMemSize;
127 copySize = sizeof(info.localMemSize);
128 break;
129 case KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple:
130 copyValue = &info.prefWorkGroupSizeMultiple;
131 copySize = sizeof(info.prefWorkGroupSizeMultiple);
132 break;
133 case KernelWorkGroupInfo::PrivateMemSize:
134 copyValue = &info.privateMemSize;
135 copySize = sizeof(info.privateMemSize);
136 break;
137 default:
138 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
139 }
140
141 if (value != nullptr)
142 {
143 // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
144 // as described in the Kernel Object Device Queries table and param_value is not NULL.
145 if (valueSize < copySize)
146 {
147 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
148 }
149 if (copyValue != nullptr)
150 {
151 std::memcpy(value, copyValue, copySize);
152 }
153 }
154 if (valueSizeRet != nullptr)
155 {
156 *valueSizeRet = copySize;
157 }
158 return angle::Result::Continue;
159 }
160
getArgInfo(cl_uint argIndex,KernelArgInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const161 angle::Result Kernel::getArgInfo(cl_uint argIndex,
162 KernelArgInfo name,
163 size_t valueSize,
164 void *value,
165 size_t *valueSizeRet) const
166 {
167 const rx::CLKernelImpl::ArgInfo &info = mInfo.args[argIndex];
168 const void *copyValue = nullptr;
169 size_t copySize = 0u;
170
171 switch (name)
172 {
173 case KernelArgInfo::AddressQualifier:
174 copyValue = &info.addressQualifier;
175 copySize = sizeof(info.addressQualifier);
176 break;
177 case KernelArgInfo::AccessQualifier:
178 copyValue = &info.accessQualifier;
179 copySize = sizeof(info.accessQualifier);
180 break;
181 case KernelArgInfo::TypeName:
182 copyValue = info.typeName.c_str();
183 copySize = info.typeName.length() + 1u;
184 break;
185 case KernelArgInfo::TypeQualifier:
186 copyValue = &info.typeQualifier;
187 copySize = sizeof(info.typeQualifier);
188 break;
189 case KernelArgInfo::Name:
190 copyValue = info.name.c_str();
191 copySize = info.name.length() + 1u;
192 break;
193 default:
194 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
195 }
196
197 if (value != nullptr)
198 {
199 // CL_INVALID_VALUE if size in bytes specified by param_value size is < size of return type
200 // as described in the Kernel Argument Queries table and param_value is not NULL.
201 if (valueSize < copySize)
202 {
203 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
204 }
205 if (copyValue != nullptr)
206 {
207 std::memcpy(value, copyValue, copySize);
208 }
209 }
210 if (valueSizeRet != nullptr)
211 {
212 *valueSizeRet = copySize;
213 }
214 return angle::Result::Continue;
215 }
216
~Kernel()217 Kernel::~Kernel()
218 {
219 --mProgram->mNumAttachedKernels;
220 }
221
Kernel(Program & program,const char * name)222 Kernel::Kernel(Program &program, const char *name) : mProgram(&program), mImpl(nullptr)
223 {
224 if (!IsError(program.getImpl().createKernel(*this, name, &mImpl)))
225 {
226 ANGLE_CL_IMPL_TRY(mImpl->createInfo(&mInfo));
227 }
228 ++mProgram->mNumAttachedKernels;
229 }
230
Kernel(Program & program,const rx::CLKernelImpl::CreateFunc & createFunc)231 Kernel::Kernel(Program &program, const rx::CLKernelImpl::CreateFunc &createFunc)
232 : mProgram(&program), mImpl(createFunc(*this))
233 {
234 if (mImpl)
235 {
236 ANGLE_CL_IMPL_TRY(mImpl->createInfo(&mInfo));
237 }
238 ++mProgram->mNumAttachedKernels;
239 }
240
241 } // namespace cl
242