• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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