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