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 // CLContext.h: Defines the cl::Context class, which manages OpenCL objects such as command-queues,
7 // memory, program and kernel objects and for executing kernels on one or more devices.
8 
9 #ifndef LIBANGLE_CLCONTEXT_H_
10 #define LIBANGLE_CLCONTEXT_H_
11 
12 #include "libANGLE/CLDevice.h"
13 #include "libANGLE/CLPlatform.h"
14 #include "libANGLE/renderer/CLContextImpl.h"
15 
16 namespace cl
17 {
18 
19 class Context final : public _cl_context, public Object
20 {
21   public:
22     // Front end entry functions, only called from OpenCL entry points
23 
24     static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
25 
26     cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
27 
28     cl_command_queue createCommandQueueWithProperties(cl_device_id device,
29                                                       const cl_queue_properties *properties,
30                                                       cl_int &errorCode);
31 
32     cl_command_queue createCommandQueue(cl_device_id device,
33                                         CommandQueueProperties properties,
34                                         cl_int &errorCode);
35 
36     cl_mem createBuffer(const cl_mem_properties *properties,
37                         MemFlags flags,
38                         size_t size,
39                         void *hostPtr,
40                         cl_int &errorCode);
41 
42     cl_mem createImage(const cl_mem_properties *properties,
43                        MemFlags flags,
44                        const cl_image_format *format,
45                        const cl_image_desc *desc,
46                        void *hostPtr,
47                        cl_int &errorCode);
48 
49     cl_mem createImage2D(MemFlags flags,
50                          const cl_image_format *format,
51                          size_t width,
52                          size_t height,
53                          size_t rowPitch,
54                          void *hostPtr,
55                          cl_int &errorCode);
56 
57     cl_mem createImage3D(MemFlags flags,
58                          const cl_image_format *format,
59                          size_t width,
60                          size_t height,
61                          size_t depth,
62                          size_t rowPitch,
63                          size_t slicePitch,
64                          void *hostPtr,
65                          cl_int &errorCode);
66 
67     cl_int getSupportedImageFormats(MemFlags flags,
68                                     MemObjectType imageType,
69                                     cl_uint numEntries,
70                                     cl_image_format *imageFormats,
71                                     cl_uint *numImageFormats);
72 
73     cl_sampler createSamplerWithProperties(const cl_sampler_properties *properties,
74                                            cl_int &errorCode);
75 
76     cl_sampler createSampler(cl_bool normalizedCoords,
77                              AddressingMode addressingMode,
78                              FilterMode filterMode,
79                              cl_int &errorCode);
80 
81     cl_program createProgramWithSource(cl_uint count,
82                                        const char **strings,
83                                        const size_t *lengths,
84                                        cl_int &errorCode);
85 
86     cl_program createProgramWithIL(const void *il, size_t length, cl_int &errorCode);
87 
88     cl_program createProgramWithBinary(cl_uint numDevices,
89                                        const cl_device_id *devices,
90                                        const size_t *lengths,
91                                        const unsigned char **binaries,
92                                        cl_int *binaryStatus,
93                                        cl_int &errorCode);
94 
95     cl_program createProgramWithBuiltInKernels(cl_uint numDevices,
96                                                const cl_device_id *devices,
97                                                const char *kernelNames,
98                                                cl_int &errorCode);
99 
100     cl_program linkProgram(cl_uint numDevices,
101                            const cl_device_id *deviceList,
102                            const char *options,
103                            cl_uint numInputPrograms,
104                            const cl_program *inputPrograms,
105                            ProgramCB pfnNotify,
106                            void *userData,
107                            cl_int &errorCode);
108 
109     cl_event createUserEvent(cl_int &errorCode);
110 
111     cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
112 
113   public:
114     using PropArray = std::vector<cl_context_properties>;
115 
116     ~Context() override;
117 
118     const Platform &getPlatform() const noexcept;
119     const DevicePtrs &getDevices() const;
120     bool hasDevice(const _cl_device_id *device) const;
121 
122     template <typename T = rx::CLContextImpl>
123     T &getImpl() const;
124 
125     bool supportsImages() const;
126     bool supportsIL() const;
127     bool supportsBuiltInKernel(const std::string &name) const;
128 
129     static void CL_CALLBACK ErrorCallback(const char *errinfo,
130                                           const void *privateInfo,
131                                           size_t cb,
132                                           void *userData);
133 
134   private:
135     Context(Platform &platform,
136             PropArray &&properties,
137             DevicePtrs &&devices,
138             ContextErrorCB notify,
139             void *userData,
140             bool userSync,
141             cl_int &errorCode);
142 
143     Context(Platform &platform,
144             PropArray &&properties,
145             DeviceType deviceType,
146             ContextErrorCB notify,
147             void *userData,
148             bool userSync,
149             cl_int &errorCode);
150 
151     Platform &mPlatform;
152     const PropArray mProperties;
153     const ContextErrorCB mNotify;
154     void *const mUserData;
155     const rx::CLContextImpl::Ptr mImpl;
156     const DevicePtrs mDevices;
157 
158     friend class Object;
159 };
160 
IsValidAndVersionOrNewer(const _cl_context * context,cl_uint major,cl_uint minor)161 inline bool Context::IsValidAndVersionOrNewer(const _cl_context *context,
162                                               cl_uint major,
163                                               cl_uint minor)
164 {
165     return IsValid(context) &&
166            context->cast<Context>().getPlatform().isVersionOrNewer(major, minor);
167 }
168 
getPlatform()169 inline const Platform &Context::getPlatform() const noexcept
170 {
171     return mPlatform;
172 }
173 
getDevices()174 inline const DevicePtrs &Context::getDevices() const
175 {
176     return mDevices;
177 }
178 
hasDevice(const _cl_device_id * device)179 inline bool Context::hasDevice(const _cl_device_id *device) const
180 {
181     return std::find(mDevices.cbegin(), mDevices.cend(), device) != mDevices.cend();
182 }
183 
184 template <typename T>
getImpl()185 inline T &Context::getImpl() const
186 {
187     return static_cast<T &>(*mImpl);
188 }
189 
supportsImages()190 inline bool Context::supportsImages() const
191 {
192     return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) {
193                 return ptr->getInfo().imageSupport == CL_TRUE;
194             }) != mDevices.cend());
195 }
196 
supportsIL()197 inline bool Context::supportsIL() const
198 {
199     return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) {
200                 return !ptr->getInfo().IL_Version.empty();
201             }) != mDevices.cend());
202 }
203 
supportsBuiltInKernel(const std::string & name)204 inline bool Context::supportsBuiltInKernel(const std::string &name) const
205 {
206     return (std::find_if(mDevices.cbegin(), mDevices.cend(), [&](const DevicePtr &ptr) {
207                 return ptr->supportsBuiltInKernel(name);
208             }) != mDevices.cend());
209 }
210 
211 }  // namespace cl
212 
213 #endif  // LIBANGLE_CLCONTEXT_H_
214