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 // CLProgram.h: Defines the cl::Program class, which consists of a set of OpenCL kernels.
7
8 #ifndef LIBANGLE_CLPROGRAM_H_
9 #define LIBANGLE_CLPROGRAM_H_
10
11 #include "libANGLE/CLDevice.h"
12 #include "libANGLE/CLKernel.h"
13 #include "libANGLE/cl_utils.h"
14 #include "libANGLE/renderer/CLProgramImpl.h"
15
16 #include "common/SynchronizedValue.h"
17
18 #include <atomic>
19
20 namespace cl
21 {
22
23 class Program final : public _cl_program, public Object
24 {
25 public:
26 // Front end entry functions, only called from OpenCL entry points
27
28 angle::Result build(cl_uint numDevices,
29 const cl_device_id *deviceList,
30 const char *options,
31 ProgramCB pfnNotify,
32 void *userData);
33
34 angle::Result compile(cl_uint numDevices,
35 const cl_device_id *deviceList,
36 const char *options,
37 cl_uint numInputHeaders,
38 const cl_program *inputHeaders,
39 const char **headerIncludeNames,
40 ProgramCB pfnNotify,
41 void *userData);
42
43 angle::Result getInfo(ProgramInfo name,
44 size_t valueSize,
45 void *value,
46 size_t *valueSizeRet) const;
47
48 angle::Result getBuildInfo(cl_device_id device,
49 ProgramBuildInfo name,
50 size_t valueSize,
51 void *value,
52 size_t *valueSizeRet) const;
53
54 cl_kernel createKernel(const char *kernel_name);
55
56 angle::Result createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
57
58 public:
59 ~Program() override;
60
61 Context &getContext();
62 const Context &getContext() const;
63 const DevicePtrs &getDevices() const;
64 const std::string &getSource() const;
65 bool hasDevice(const _cl_device_id *device) const;
66
67 bool isBuilding() const;
68 bool hasAttachedKernels() const;
69
70 template <typename T = rx::CLProgramImpl>
71 T &getImpl() const;
72
73 void callback();
74
75 private:
76 Program(Context &context, std::string &&source);
77 Program(Context &context, const void *il, size_t length);
78
79 Program(Context &context,
80 DevicePtrs &&devices,
81 const size_t *lengths,
82 const unsigned char **binaries,
83 cl_int *binaryStatus);
84
85 Program(Context &context, DevicePtrs &&devices, const char *kernelNames);
86
87 Program(Context &context,
88 const DevicePtrs &devices,
89 const char *options,
90 const cl::ProgramPtrs &inputPrograms,
91 ProgramCB pfnNotify,
92 void *userData);
93
94 using CallbackData = std::pair<ProgramCB, void *>;
95
96 const ContextPtr mContext;
97 const DevicePtrs mDevices;
98 const std::string mIL;
99
100 // mCallback might be accessed from implementation initialization
101 // and needs to be initialized first.
102 angle::SynchronizedValue<CallbackData> mCallback;
103 std::atomic<cl_uint> mNumAttachedKernels;
104
105 rx::CLProgramImpl::Ptr mImpl;
106 const std::string mSource;
107
108 friend class Kernel;
109 friend class Object;
110 };
111
getContext()112 inline Context &Program::getContext()
113 {
114 return *mContext;
115 }
116
getContext()117 inline const Context &Program::getContext() const
118 {
119 return *mContext;
120 }
121
getDevices()122 inline const DevicePtrs &Program::getDevices() const
123 {
124 return mDevices;
125 }
126
getSource()127 inline const std::string &Program::getSource() const
128 {
129 return mSource;
130 }
131
hasDevice(const _cl_device_id * device)132 inline bool Program::hasDevice(const _cl_device_id *device) const
133 {
134 return std::find(mDevices.cbegin(), mDevices.cend(), device) != mDevices.cend();
135 }
136
isBuilding()137 inline bool Program::isBuilding() const
138 {
139 for (const DevicePtr &device : getDevices())
140 {
141 cl_build_status buildStatus;
142 ANGLE_CL_IMPL_TRY(getBuildInfo(device->getNative(), ProgramBuildInfo::Status,
143 sizeof(cl_build_status), &buildStatus, nullptr));
144 if ((mCallback->first != nullptr) || (buildStatus == CL_BUILD_IN_PROGRESS))
145 {
146 return true;
147 }
148 }
149 return false;
150 }
151
hasAttachedKernels()152 inline bool Program::hasAttachedKernels() const
153 {
154 return mNumAttachedKernels != 0u;
155 }
156
157 template <typename T>
getImpl()158 inline T &Program::getImpl() const
159 {
160 return static_cast<T &>(*mImpl);
161 }
162
163 } // namespace cl
164
165 #endif // LIBANGLE_CLPROGRAM_H_
166