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 // CLCommandQueue.h: Defines the cl::CommandQueue class, which can be used to queue a set of OpenCL
7 // operations.
8
9 #ifndef LIBANGLE_CLCOMMANDQUEUE_H_
10 #define LIBANGLE_CLCOMMANDQUEUE_H_
11
12 #include "libANGLE/CLObject.h"
13 #include "libANGLE/cl_utils.h"
14 #include "libANGLE/renderer/CLCommandQueueImpl.h"
15
16 #include "common/SynchronizedValue.h"
17
18 #include <limits>
19
20 namespace cl
21 {
22
23 class CommandQueue final : public _cl_command_queue, public Object
24 {
25 public:
26 // Front end entry functions, only called from OpenCL entry points
27
28 angle::Result getInfo(CommandQueueInfo name,
29 size_t valueSize,
30 void *value,
31 size_t *valueSizeRet) const;
32
33 angle::Result setProperty(CommandQueueProperties properties,
34 cl_bool enable,
35 cl_command_queue_properties *oldProperties);
36
37 angle::Result enqueueReadBuffer(cl_mem buffer,
38 cl_bool blockingRead,
39 size_t offset,
40 size_t size,
41 void *ptr,
42 cl_uint numEventsInWaitList,
43 const cl_event *eventWaitList,
44 cl_event *event);
45
46 angle::Result enqueueWriteBuffer(cl_mem buffer,
47 cl_bool blockingWrite,
48 size_t offset,
49 size_t size,
50 const void *ptr,
51 cl_uint numEventsInWaitList,
52 const cl_event *eventWaitList,
53 cl_event *event);
54
55 angle::Result enqueueReadBufferRect(cl_mem buffer,
56 cl_bool blockingRead,
57 const cl::MemOffsets &bufferOrigin,
58 const cl::MemOffsets &hostOrigin,
59 const cl::Coordinate ®ion,
60 size_t bufferRowPitch,
61 size_t bufferSlicePitch,
62 size_t hostRowPitch,
63 size_t hostSlicePitch,
64 void *ptr,
65 cl_uint numEventsInWaitList,
66 const cl_event *eventWaitList,
67 cl_event *event);
68
69 angle::Result enqueueWriteBufferRect(cl_mem buffer,
70 cl_bool blockingWrite,
71 const cl::MemOffsets &bufferOrigin,
72 const cl::MemOffsets &hostOrigin,
73 const cl::Coordinate ®ion,
74 size_t bufferRowPitch,
75 size_t bufferSlicePitch,
76 size_t hostRowPitch,
77 size_t hostSlicePitch,
78 const void *ptr,
79 cl_uint numEventsInWaitList,
80 const cl_event *eventWaitList,
81 cl_event *event);
82
83 angle::Result enqueueCopyBuffer(cl_mem srcBuffer,
84 cl_mem dstBuffer,
85 size_t srcOffset,
86 size_t dstOffset,
87 size_t size,
88 cl_uint numEventsInWaitList,
89 const cl_event *eventWaitList,
90 cl_event *event);
91
92 angle::Result enqueueCopyBufferRect(cl_mem srcBuffer,
93 cl_mem dstBuffer,
94 const cl::MemOffsets &srcOrigin,
95 const cl::MemOffsets &dstOrigin,
96 const cl::Coordinate ®ion,
97 size_t srcRowPitch,
98 size_t srcSlicePitch,
99 size_t dstRowPitch,
100 size_t dstSlicePitch,
101 cl_uint numEventsInWaitList,
102 const cl_event *eventWaitList,
103 cl_event *event);
104
105 angle::Result enqueueFillBuffer(cl_mem buffer,
106 const void *pattern,
107 size_t patternSize,
108 size_t offset,
109 size_t size,
110 cl_uint numEventsInWaitList,
111 const cl_event *eventWaitList,
112 cl_event *event);
113
114 angle::Result enqueueMapBuffer(cl_mem buffer,
115 cl_bool blockingMap,
116 MapFlags mapFlags,
117 size_t offset,
118 size_t size,
119 cl_uint numEventsInWaitList,
120 const cl_event *eventWaitList,
121 cl_event *event,
122 void *&mapPtr);
123
124 angle::Result enqueueReadImage(cl_mem image,
125 cl_bool blockingRead,
126 const cl::MemOffsets &origin,
127 const cl::Coordinate ®ion,
128 size_t rowPitch,
129 size_t slicePitch,
130 void *ptr,
131 cl_uint numEventsInWaitList,
132 const cl_event *eventWaitList,
133 cl_event *event);
134
135 angle::Result enqueueWriteImage(cl_mem image,
136 cl_bool blockingWrite,
137 const cl::MemOffsets &origin,
138 const cl::Coordinate ®ion,
139 size_t inputRowPitch,
140 size_t inputSlicePitch,
141 const void *ptr,
142 cl_uint numEventsInWaitList,
143 const cl_event *eventWaitList,
144 cl_event *event);
145
146 angle::Result enqueueCopyImage(cl_mem srcImage,
147 cl_mem dstImage,
148 const cl::MemOffsets &srcOrigin,
149 const cl::MemOffsets &dstOrigin,
150 const cl::Coordinate ®ion,
151 cl_uint numEventsInWaitList,
152 const cl_event *eventWaitList,
153 cl_event *event);
154
155 angle::Result enqueueFillImage(cl_mem image,
156 const void *fillColor,
157 const cl::MemOffsets &origin,
158 const cl::Coordinate ®ion,
159 cl_uint numEventsInWaitList,
160 const cl_event *eventWaitList,
161 cl_event *event);
162
163 angle::Result enqueueCopyImageToBuffer(cl_mem srcImage,
164 cl_mem dstBuffer,
165 const cl::MemOffsets &srcOrigin,
166 const cl::Coordinate ®ion,
167 size_t dstOffset,
168 cl_uint numEventsInWaitList,
169 const cl_event *eventWaitList,
170 cl_event *event);
171
172 angle::Result enqueueCopyBufferToImage(cl_mem srcBuffer,
173 cl_mem dstImage,
174 size_t srcOffset,
175 const cl::MemOffsets &dstOrigin,
176 const cl::Coordinate ®ion,
177 cl_uint numEventsInWaitList,
178 const cl_event *eventWaitList,
179 cl_event *event);
180
181 angle::Result enqueueMapImage(cl_mem image,
182 cl_bool blockingMap,
183 MapFlags mapFlags,
184 const cl::MemOffsets &origin,
185 const cl::Coordinate ®ion,
186 size_t *imageRowPitch,
187 size_t *imageSlicePitch,
188 cl_uint numEventsInWaitList,
189 const cl_event *eventWaitList,
190 cl_event *event,
191 void *&mapPtr);
192
193 angle::Result enqueueUnmapMemObject(cl_mem memobj,
194 void *mappedPtr,
195 cl_uint numEventsInWaitList,
196 const cl_event *eventWaitList,
197 cl_event *event);
198
199 angle::Result enqueueMigrateMemObjects(cl_uint numMemObjects,
200 const cl_mem *memObjects,
201 MemMigrationFlags flags,
202 cl_uint numEventsInWaitList,
203 const cl_event *eventWaitList,
204 cl_event *event);
205
206 angle::Result enqueueNDRangeKernel(cl_kernel kernel,
207 const NDRange &ndrange,
208 cl_uint numEventsInWaitList,
209 const cl_event *eventWaitList,
210 cl_event *event);
211
212 angle::Result enqueueTask(cl_kernel kernel,
213 cl_uint numEventsInWaitList,
214 const cl_event *eventWaitList,
215 cl_event *event);
216
217 angle::Result enqueueNativeKernel(UserFunc userFunc,
218 void *args,
219 size_t cbArgs,
220 cl_uint numMemObjects,
221 const cl_mem *memList,
222 const void **argsMemLoc,
223 cl_uint numEventsInWaitList,
224 const cl_event *eventWaitList,
225 cl_event *event);
226
227 angle::Result enqueueMarkerWithWaitList(cl_uint numEventsInWaitList,
228 const cl_event *eventWaitList,
229 cl_event *event);
230
231 angle::Result enqueueMarker(cl_event *event);
232
233 angle::Result enqueueWaitForEvents(cl_uint numEvents, const cl_event *eventList);
234
235 angle::Result enqueueBarrierWithWaitList(cl_uint numEventsInWaitList,
236 const cl_event *eventWaitList,
237 cl_event *event);
238
239 angle::Result enqueueBarrier();
240
241 angle::Result flush();
242 angle::Result finish();
243
244 public:
245 using PropArray = std::vector<cl_queue_properties>;
246
247 static constexpr cl_uint kNoSize = std::numeric_limits<cl_uint>::max();
248
249 ~CommandQueue() override;
250
251 Context &getContext();
252 const Context &getContext() const;
253 const Device &getDevice() const;
254
255 // Get index of device in the context.
256 size_t getDeviceIndex() const;
257
258 CommandQueueProperties getProperties() const;
259 bool isOnHost() const;
260 bool isOnDevice() const;
261
262 bool hasSize() const;
263 cl_uint getSize() const;
264
265 template <typename T = rx::CLCommandQueueImpl>
266 T &getImpl() const;
267
268 cl_int onRelease();
269
270 private:
271 CommandQueue(Context &context,
272 Device &device,
273 PropArray &&propArray,
274 CommandQueueProperties properties,
275 cl_uint size);
276
277 CommandQueue(Context &context, Device &device, CommandQueueProperties properties);
278
279 const ContextPtr mContext;
280 const DevicePtr mDevice;
281 const PropArray mPropArray;
282 angle::SynchronizedValue<CommandQueueProperties> mProperties;
283 const cl_uint mSize = kNoSize;
284 rx::CLCommandQueueImpl::Ptr mImpl;
285
286 friend class Object;
287 };
288
getContext()289 inline Context &CommandQueue::getContext()
290 {
291 return *mContext;
292 }
293
getContext()294 inline const Context &CommandQueue::getContext() const
295 {
296 return *mContext;
297 }
298
getDevice()299 inline const Device &CommandQueue::getDevice() const
300 {
301 return *mDevice;
302 }
303
getProperties()304 inline CommandQueueProperties CommandQueue::getProperties() const
305 {
306 return *mProperties;
307 }
308
isOnHost()309 inline bool CommandQueue::isOnHost() const
310 {
311 return mProperties->excludes(CL_QUEUE_ON_DEVICE);
312 }
313
isOnDevice()314 inline bool CommandQueue::isOnDevice() const
315 {
316 return mProperties->intersects(CL_QUEUE_ON_DEVICE);
317 }
318
hasSize()319 inline bool CommandQueue::hasSize() const
320 {
321 return mSize != kNoSize;
322 }
323
getSize()324 inline cl_uint CommandQueue::getSize() const
325 {
326 return mSize;
327 }
328
329 template <typename T>
getImpl()330 inline T &CommandQueue::getImpl() const
331 {
332 return static_cast<T &>(*mImpl);
333 }
334
onRelease()335 inline cl_int CommandQueue::onRelease()
336 {
337 // Perform implicit submission on queue release
338 // https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clReleaseCommandQueue
339 if (IsError(finish()))
340 {
341 WARN() << "Failed to perform implicit submission on queue release!";
342 return CL_OUT_OF_RESOURCES;
343 }
344 return CL_SUCCESS;
345 }
346
347 } // namespace cl
348
349 #endif // LIBANGLE_CLCOMMANDQUEUE_H_
350