xref: /aosp_15_r20/external/angle/src/libANGLE/CLProgram.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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