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