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/renderer/CLProgramImpl.h"
14
15 #include "common/Spinlock.h"
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 cl_int build(cl_uint numDevices,
29 const cl_device_id *deviceList,
30 const char *options,
31 ProgramCB pfnNotify,
32 void *userData);
33
34 cl_int 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 cl_int getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
44
45 cl_int getBuildInfo(cl_device_id device,
46 ProgramBuildInfo name,
47 size_t valueSize,
48 void *value,
49 size_t *valueSizeRet) const;
50
51 cl_kernel createKernel(const char *kernel_name, cl_int &errorCode);
52
53 cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
54
55 public:
56 ~Program() override;
57
58 Context &getContext();
59 const Context &getContext() const;
60 const DevicePtrs &getDevices() const;
61 bool hasDevice(const _cl_device_id *device) const;
62
63 bool isBuilding() const;
64 bool hasAttachedKernels() const;
65
66 template <typename T = rx::CLProgramImpl>
67 T &getImpl() const;
68
69 void callback();
70
71 private:
72 Program(Context &context, std::string &&source, cl_int &errorCode);
73 Program(Context &context, const void *il, size_t length, cl_int &errorCode);
74
75 Program(Context &context,
76 DevicePtrs &&devices,
77 const size_t *lengths,
78 const unsigned char **binaries,
79 cl_int *binaryStatus,
80 cl_int &errorCode);
81
82 Program(Context &context, DevicePtrs &&devices, const char *kernelNames, cl_int &errorCode);
83
84 Program(Context &context,
85 const DevicePtrs &devices,
86 const char *options,
87 const cl::ProgramPtrs &inputPrograms,
88 ProgramCB pfnNotify,
89 void *userData,
90 cl_int &errorCode);
91
92 using CallbackData = std::pair<ProgramCB, void *>;
93
94 const ContextPtr mContext;
95 const DevicePtrs mDevices;
96 const std::string mIL;
97
98 // mCallback might be accessed from implementation initialization
99 // and needs to be initialized first.
100 angle::SynchronizedValue<CallbackData, angle::Spinlock> mCallback;
101 std::atomic<cl_uint> mNumAttachedKernels;
102
103 const rx::CLProgramImpl::Ptr mImpl;
104 const std::string mSource;
105
106 friend class Kernel;
107 friend class Object;
108 };
109
getContext()110 inline Context &Program::getContext()
111 {
112 return *mContext;
113 }
114
getContext()115 inline const Context &Program::getContext() const
116 {
117 return *mContext;
118 }
119
getDevices()120 inline const DevicePtrs &Program::getDevices() const
121 {
122 return mDevices;
123 }
124
hasDevice(const _cl_device_id * device)125 inline bool Program::hasDevice(const _cl_device_id *device) const
126 {
127 return std::find(mDevices.cbegin(), mDevices.cend(), device) != mDevices.cend();
128 }
129
isBuilding()130 inline bool Program::isBuilding() const
131 {
132 return mCallback->first != nullptr;
133 }
134
hasAttachedKernels()135 inline bool Program::hasAttachedKernels() const
136 {
137 return mNumAttachedKernels != 0u;
138 }
139
140 template <typename T>
getImpl()141 inline T &Program::getImpl() const
142 {
143 return static_cast<T &>(*mImpl);
144 }
145
146 } // namespace cl
147
148 #endif // LIBANGLE_CLPROGRAM_H_
149