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.cpp: Implements the cl::CommandQueue class.
7
8 #include "libANGLE/CLCommandQueue.h"
9
10 #include "libANGLE/CLBuffer.h"
11 #include "libANGLE/CLContext.h"
12 #include "libANGLE/CLDevice.h"
13 #include "libANGLE/CLEvent.h"
14 #include "libANGLE/CLImage.h"
15 #include "libANGLE/CLKernel.h"
16 #include "libANGLE/CLMemory.h"
17
18 #include <cstring>
19
20 namespace cl
21 {
22
23 namespace
24 {
25
InitializeOutputEvent(cl_event * event)26 void InitializeOutputEvent(cl_event *event)
27 {
28 if (event != nullptr)
29 {
30 *event = nullptr;
31 }
32 }
33
CheckCreateEvent(CommandQueue & queue,cl_command_type commandType,const rx::CLEventImpl::CreateFunc & createFunc,cl_event * event)34 void CheckCreateEvent(CommandQueue &queue,
35 cl_command_type commandType,
36 const rx::CLEventImpl::CreateFunc &createFunc,
37 cl_event *event)
38 {
39 if (event != nullptr)
40 {
41 ASSERT(createFunc);
42 *event = Object::Create<Event>(queue, commandType, createFunc);
43 }
44 }
45
46 } // namespace
47
getInfo(CommandQueueInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const48 angle::Result CommandQueue::getInfo(CommandQueueInfo name,
49 size_t valueSize,
50 void *value,
51 size_t *valueSizeRet) const
52 {
53 cl_command_queue_properties properties = 0u;
54 cl_uint valUInt = 0u;
55 void *valPointer = nullptr;
56 const void *copyValue = nullptr;
57 size_t copySize = 0u;
58
59 switch (name)
60 {
61 case CommandQueueInfo::Context:
62 valPointer = mContext->getNative();
63 copyValue = &valPointer;
64 copySize = sizeof(valPointer);
65 break;
66 case CommandQueueInfo::Device:
67 valPointer = mDevice->getNative();
68 copyValue = &valPointer;
69 copySize = sizeof(valPointer);
70 break;
71 case CommandQueueInfo::ReferenceCount:
72 valUInt = getRefCount();
73 copyValue = &valUInt;
74 copySize = sizeof(valUInt);
75 break;
76 case CommandQueueInfo::Properties:
77 properties = mProperties->get();
78 copyValue = &properties;
79 copySize = sizeof(properties);
80 break;
81 case CommandQueueInfo::PropertiesArray:
82 copyValue = mPropArray.data();
83 copySize = mPropArray.size() * sizeof(decltype(mPropArray)::value_type);
84 break;
85 case CommandQueueInfo::Size:
86 copyValue = &mSize;
87 copySize = sizeof(mSize);
88 break;
89 case CommandQueueInfo::DeviceDefault:
90 valPointer = CommandQueue::CastNative(*mDevice->mDefaultCommandQueue);
91 copyValue = &valPointer;
92 copySize = sizeof(valPointer);
93 break;
94 default:
95 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
96 }
97
98 if (value != nullptr)
99 {
100 // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
101 // as specified in the Command Queue Parameter table, and param_value is not a NULL value.
102 if (valueSize < copySize)
103 {
104 ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
105 }
106 if (copyValue != nullptr)
107 {
108 std::memcpy(value, copyValue, copySize);
109 }
110 }
111 if (valueSizeRet != nullptr)
112 {
113 *valueSizeRet = copySize;
114 }
115 return angle::Result::Continue;
116 }
117
setProperty(CommandQueueProperties properties,cl_bool enable,cl_command_queue_properties * oldProperties)118 angle::Result CommandQueue::setProperty(CommandQueueProperties properties,
119 cl_bool enable,
120 cl_command_queue_properties *oldProperties)
121 {
122 auto props = mProperties.synchronize();
123 if (oldProperties != nullptr)
124 {
125 *oldProperties = props->get();
126 }
127
128 ANGLE_TRY(mImpl->setProperty(properties, enable));
129
130 if (enable == CL_FALSE)
131 {
132 props->clear(properties);
133 }
134 else
135 {
136 props->set(properties);
137 }
138 return angle::Result::Continue;
139 }
140
enqueueReadBuffer(cl_mem buffer,cl_bool blockingRead,size_t offset,size_t size,void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)141 angle::Result CommandQueue::enqueueReadBuffer(cl_mem buffer,
142 cl_bool blockingRead,
143 size_t offset,
144 size_t size,
145 void *ptr,
146 cl_uint numEventsInWaitList,
147 const cl_event *eventWaitList,
148 cl_event *event)
149 {
150 const Buffer &buf = buffer->cast<Buffer>();
151 const bool blocking = blockingRead != CL_FALSE;
152 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
153 rx::CLEventImpl::CreateFunc eventCreateFunc;
154 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
155 event != nullptr ? &eventCreateFunc : nullptr;
156 InitializeOutputEvent(event);
157
158 ANGLE_TRY(
159 mImpl->enqueueReadBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr));
160
161 CheckCreateEvent(*this, CL_COMMAND_READ_BUFFER, eventCreateFunc, event);
162 return angle::Result::Continue;
163 }
164
enqueueWriteBuffer(cl_mem buffer,cl_bool blockingWrite,size_t offset,size_t size,const void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)165 angle::Result CommandQueue::enqueueWriteBuffer(cl_mem buffer,
166 cl_bool blockingWrite,
167 size_t offset,
168 size_t size,
169 const void *ptr,
170 cl_uint numEventsInWaitList,
171 const cl_event *eventWaitList,
172 cl_event *event)
173 {
174 const Buffer &buf = buffer->cast<Buffer>();
175 const bool blocking = blockingWrite != CL_FALSE;
176 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
177 rx::CLEventImpl::CreateFunc eventCreateFunc;
178 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
179 event != nullptr ? &eventCreateFunc : nullptr;
180 InitializeOutputEvent(event);
181
182 ANGLE_TRY(mImpl->enqueueWriteBuffer(buf, blocking, offset, size, ptr, waitEvents,
183 eventCreateFuncPtr));
184
185 CheckCreateEvent(*this, CL_COMMAND_WRITE_BUFFER, eventCreateFunc, event);
186 return angle::Result::Continue;
187 }
188
enqueueReadBufferRect(cl_mem buffer,cl_bool blockingRead,const cl::MemOffsets & bufferOrigin,const cl::MemOffsets & hostOrigin,const cl::Coordinate & region,size_t bufferRowPitch,size_t bufferSlicePitch,size_t hostRowPitch,size_t hostSlicePitch,void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)189 angle::Result CommandQueue::enqueueReadBufferRect(cl_mem buffer,
190 cl_bool blockingRead,
191 const cl::MemOffsets &bufferOrigin,
192 const cl::MemOffsets &hostOrigin,
193 const cl::Coordinate ®ion,
194 size_t bufferRowPitch,
195 size_t bufferSlicePitch,
196 size_t hostRowPitch,
197 size_t hostSlicePitch,
198 void *ptr,
199 cl_uint numEventsInWaitList,
200 const cl_event *eventWaitList,
201 cl_event *event)
202 {
203 const Buffer &buf = buffer->cast<Buffer>();
204 const bool blocking = blockingRead != CL_FALSE;
205 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
206 rx::CLEventImpl::CreateFunc eventCreateFunc;
207 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
208 event != nullptr ? &eventCreateFunc : nullptr;
209 InitializeOutputEvent(event);
210
211 ANGLE_TRY(mImpl->enqueueReadBufferRect(buf, blocking, bufferOrigin, hostOrigin, region,
212 bufferRowPitch, bufferSlicePitch, hostRowPitch,
213 hostSlicePitch, ptr, waitEvents, eventCreateFuncPtr));
214
215 CheckCreateEvent(*this, CL_COMMAND_READ_BUFFER_RECT, eventCreateFunc, event);
216 return angle::Result::Continue;
217 }
218
enqueueWriteBufferRect(cl_mem buffer,cl_bool blockingWrite,const cl::MemOffsets & bufferOrigin,const cl::MemOffsets & hostOrigin,const cl::Coordinate & region,size_t bufferRowPitch,size_t bufferSlicePitch,size_t hostRowPitch,size_t hostSlicePitch,const void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)219 angle::Result CommandQueue::enqueueWriteBufferRect(cl_mem buffer,
220 cl_bool blockingWrite,
221 const cl::MemOffsets &bufferOrigin,
222 const cl::MemOffsets &hostOrigin,
223 const cl::Coordinate ®ion,
224 size_t bufferRowPitch,
225 size_t bufferSlicePitch,
226 size_t hostRowPitch,
227 size_t hostSlicePitch,
228 const void *ptr,
229 cl_uint numEventsInWaitList,
230 const cl_event *eventWaitList,
231 cl_event *event)
232 {
233 const Buffer &buf = buffer->cast<Buffer>();
234 const bool blocking = blockingWrite != CL_FALSE;
235 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
236 rx::CLEventImpl::CreateFunc eventCreateFunc;
237 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
238 event != nullptr ? &eventCreateFunc : nullptr;
239 InitializeOutputEvent(event);
240
241 ANGLE_TRY(mImpl->enqueueWriteBufferRect(buf, blocking, bufferOrigin, hostOrigin, region,
242 bufferRowPitch, bufferSlicePitch, hostRowPitch,
243 hostSlicePitch, ptr, waitEvents, eventCreateFuncPtr));
244
245 CheckCreateEvent(*this, CL_COMMAND_WRITE_BUFFER_RECT, eventCreateFunc, event);
246 return angle::Result::Continue;
247 }
248
enqueueCopyBuffer(cl_mem srcBuffer,cl_mem dstBuffer,size_t srcOffset,size_t dstOffset,size_t size,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)249 angle::Result CommandQueue::enqueueCopyBuffer(cl_mem srcBuffer,
250 cl_mem dstBuffer,
251 size_t srcOffset,
252 size_t dstOffset,
253 size_t size,
254 cl_uint numEventsInWaitList,
255 const cl_event *eventWaitList,
256 cl_event *event)
257 {
258 const Buffer &src = srcBuffer->cast<Buffer>();
259 const Buffer &dst = dstBuffer->cast<Buffer>();
260 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
261 rx::CLEventImpl::CreateFunc eventCreateFunc;
262 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
263 event != nullptr ? &eventCreateFunc : nullptr;
264 InitializeOutputEvent(event);
265
266 ANGLE_TRY(mImpl->enqueueCopyBuffer(src, dst, srcOffset, dstOffset, size, waitEvents,
267 eventCreateFuncPtr));
268
269 CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER, eventCreateFunc, event);
270 return angle::Result::Continue;
271 }
272
enqueueCopyBufferRect(cl_mem srcBuffer,cl_mem dstBuffer,const cl::MemOffsets & srcOrigin,const cl::MemOffsets & dstOrigin,const cl::Coordinate & region,size_t srcRowPitch,size_t srcSlicePitch,size_t dstRowPitch,size_t dstSlicePitch,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)273 angle::Result CommandQueue::enqueueCopyBufferRect(cl_mem srcBuffer,
274 cl_mem dstBuffer,
275 const cl::MemOffsets &srcOrigin,
276 const cl::MemOffsets &dstOrigin,
277 const cl::Coordinate ®ion,
278 size_t srcRowPitch,
279 size_t srcSlicePitch,
280 size_t dstRowPitch,
281 size_t dstSlicePitch,
282 cl_uint numEventsInWaitList,
283 const cl_event *eventWaitList,
284 cl_event *event)
285 {
286 const Buffer &src = srcBuffer->cast<Buffer>();
287 const Buffer &dst = dstBuffer->cast<Buffer>();
288 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
289 rx::CLEventImpl::CreateFunc eventCreateFunc;
290 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
291 event != nullptr ? &eventCreateFunc : nullptr;
292 InitializeOutputEvent(event);
293
294 ANGLE_TRY(mImpl->enqueueCopyBufferRect(src, dst, srcOrigin, dstOrigin, region, srcRowPitch,
295 srcSlicePitch, dstRowPitch, dstSlicePitch, waitEvents,
296 eventCreateFuncPtr));
297
298 CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER_RECT, eventCreateFunc, event);
299 return angle::Result::Continue;
300 }
301
enqueueFillBuffer(cl_mem buffer,const void * pattern,size_t patternSize,size_t offset,size_t size,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)302 angle::Result CommandQueue::enqueueFillBuffer(cl_mem buffer,
303 const void *pattern,
304 size_t patternSize,
305 size_t offset,
306 size_t size,
307 cl_uint numEventsInWaitList,
308 const cl_event *eventWaitList,
309 cl_event *event)
310 {
311 const Buffer &buf = buffer->cast<Buffer>();
312 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
313 rx::CLEventImpl::CreateFunc eventCreateFunc;
314 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
315 event != nullptr ? &eventCreateFunc : nullptr;
316 InitializeOutputEvent(event);
317
318 ANGLE_TRY(mImpl->enqueueFillBuffer(buf, pattern, patternSize, offset, size, waitEvents,
319 eventCreateFuncPtr));
320
321 CheckCreateEvent(*this, CL_COMMAND_FILL_BUFFER, eventCreateFunc, event);
322 return angle::Result::Continue;
323 }
324
enqueueMapBuffer(cl_mem buffer,cl_bool blockingMap,MapFlags mapFlags,size_t offset,size_t size,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event,void * & mapPtr)325 angle::Result CommandQueue::enqueueMapBuffer(cl_mem buffer,
326 cl_bool blockingMap,
327 MapFlags mapFlags,
328 size_t offset,
329 size_t size,
330 cl_uint numEventsInWaitList,
331 const cl_event *eventWaitList,
332 cl_event *event,
333 void *&mapPtr)
334 {
335 const Buffer &buf = buffer->cast<Buffer>();
336 const bool blocking = blockingMap != CL_FALSE;
337 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
338 rx::CLEventImpl::CreateFunc eventCreateFunc;
339 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
340 event != nullptr ? &eventCreateFunc : nullptr;
341 InitializeOutputEvent(event);
342
343 ANGLE_TRY(mImpl->enqueueMapBuffer(buf, blocking, mapFlags, offset, size, waitEvents,
344 eventCreateFuncPtr, mapPtr));
345
346 CheckCreateEvent(*this, CL_COMMAND_MAP_BUFFER, eventCreateFunc, event);
347 return angle::Result::Continue;
348 }
349
enqueueReadImage(cl_mem image,cl_bool blockingRead,const cl::MemOffsets & origin,const cl::Coordinate & region,size_t rowPitch,size_t slicePitch,void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)350 angle::Result CommandQueue::enqueueReadImage(cl_mem image,
351 cl_bool blockingRead,
352 const cl::MemOffsets &origin,
353 const cl::Coordinate ®ion,
354 size_t rowPitch,
355 size_t slicePitch,
356 void *ptr,
357 cl_uint numEventsInWaitList,
358 const cl_event *eventWaitList,
359 cl_event *event)
360 {
361 const Image &img = image->cast<Image>();
362 const bool blocking = blockingRead != CL_FALSE;
363 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
364 rx::CLEventImpl::CreateFunc eventCreateFunc;
365 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
366 event != nullptr ? &eventCreateFunc : nullptr;
367 InitializeOutputEvent(event);
368
369 ANGLE_TRY(mImpl->enqueueReadImage(img, blocking, origin, region, rowPitch, slicePitch, ptr,
370 waitEvents, eventCreateFuncPtr));
371
372 CheckCreateEvent(*this, CL_COMMAND_READ_IMAGE, eventCreateFunc, event);
373 return angle::Result::Continue;
374 }
375
enqueueWriteImage(cl_mem image,cl_bool blockingWrite,const cl::MemOffsets & origin,const cl::Coordinate & region,size_t inputRowPitch,size_t inputSlicePitch,const void * ptr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)376 angle::Result CommandQueue::enqueueWriteImage(cl_mem image,
377 cl_bool blockingWrite,
378 const cl::MemOffsets &origin,
379 const cl::Coordinate ®ion,
380 size_t inputRowPitch,
381 size_t inputSlicePitch,
382 const void *ptr,
383 cl_uint numEventsInWaitList,
384 const cl_event *eventWaitList,
385 cl_event *event)
386 {
387 const Image &img = image->cast<Image>();
388 const bool blocking = blockingWrite != CL_FALSE;
389 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
390 rx::CLEventImpl::CreateFunc eventCreateFunc;
391 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
392 event != nullptr ? &eventCreateFunc : nullptr;
393 InitializeOutputEvent(event);
394
395 ANGLE_TRY(mImpl->enqueueWriteImage(img, blocking, origin, region, inputRowPitch,
396 inputSlicePitch, ptr, waitEvents, eventCreateFuncPtr));
397
398 CheckCreateEvent(*this, CL_COMMAND_WRITE_IMAGE, eventCreateFunc, event);
399 return angle::Result::Continue;
400 }
401
enqueueCopyImage(cl_mem srcImage,cl_mem dstImage,const cl::MemOffsets & srcOrigin,const cl::MemOffsets & dstOrigin,const cl::Coordinate & region,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)402 angle::Result CommandQueue::enqueueCopyImage(cl_mem srcImage,
403 cl_mem dstImage,
404 const cl::MemOffsets &srcOrigin,
405 const cl::MemOffsets &dstOrigin,
406 const cl::Coordinate ®ion,
407 cl_uint numEventsInWaitList,
408 const cl_event *eventWaitList,
409 cl_event *event)
410 {
411 const Image &src = srcImage->cast<Image>();
412 const Image &dst = dstImage->cast<Image>();
413 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
414 rx::CLEventImpl::CreateFunc eventCreateFunc;
415 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
416 event != nullptr ? &eventCreateFunc : nullptr;
417 InitializeOutputEvent(event);
418
419 ANGLE_TRY(mImpl->enqueueCopyImage(src, dst, srcOrigin, dstOrigin, region, waitEvents,
420 eventCreateFuncPtr));
421
422 CheckCreateEvent(*this, CL_COMMAND_COPY_IMAGE, eventCreateFunc, event);
423 return angle::Result::Continue;
424 }
425
enqueueFillImage(cl_mem image,const void * fillColor,const cl::MemOffsets & origin,const cl::Coordinate & region,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)426 angle::Result CommandQueue::enqueueFillImage(cl_mem image,
427 const void *fillColor,
428 const cl::MemOffsets &origin,
429 const cl::Coordinate ®ion,
430 cl_uint numEventsInWaitList,
431 const cl_event *eventWaitList,
432 cl_event *event)
433 {
434 const Image &img = image->cast<Image>();
435 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
436 rx::CLEventImpl::CreateFunc eventCreateFunc;
437 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
438 event != nullptr ? &eventCreateFunc : nullptr;
439 InitializeOutputEvent(event);
440
441 ANGLE_TRY(
442 mImpl->enqueueFillImage(img, fillColor, origin, region, waitEvents, eventCreateFuncPtr));
443
444 CheckCreateEvent(*this, CL_COMMAND_FILL_IMAGE, eventCreateFunc, event);
445 return angle::Result::Continue;
446 }
447
enqueueCopyImageToBuffer(cl_mem srcImage,cl_mem dstBuffer,const cl::MemOffsets & srcOrigin,const cl::Coordinate & region,size_t dstOffset,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)448 angle::Result CommandQueue::enqueueCopyImageToBuffer(cl_mem srcImage,
449 cl_mem dstBuffer,
450 const cl::MemOffsets &srcOrigin,
451 const cl::Coordinate ®ion,
452 size_t dstOffset,
453 cl_uint numEventsInWaitList,
454 const cl_event *eventWaitList,
455 cl_event *event)
456 {
457 const Image &src = srcImage->cast<Image>();
458 const Buffer &dst = dstBuffer->cast<Buffer>();
459 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
460 rx::CLEventImpl::CreateFunc eventCreateFunc;
461 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
462 event != nullptr ? &eventCreateFunc : nullptr;
463 InitializeOutputEvent(event);
464
465 ANGLE_TRY(mImpl->enqueueCopyImageToBuffer(src, dst, srcOrigin, region, dstOffset, waitEvents,
466 eventCreateFuncPtr));
467
468 CheckCreateEvent(*this, CL_COMMAND_COPY_IMAGE_TO_BUFFER, eventCreateFunc, event);
469 return angle::Result::Continue;
470 }
471
enqueueCopyBufferToImage(cl_mem srcBuffer,cl_mem dstImage,size_t srcOffset,const cl::MemOffsets & dstOrigin,const cl::Coordinate & region,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)472 angle::Result CommandQueue::enqueueCopyBufferToImage(cl_mem srcBuffer,
473 cl_mem dstImage,
474 size_t srcOffset,
475 const cl::MemOffsets &dstOrigin,
476 const cl::Coordinate ®ion,
477 cl_uint numEventsInWaitList,
478 const cl_event *eventWaitList,
479 cl_event *event)
480 {
481 const Buffer &src = srcBuffer->cast<Buffer>();
482 const Image &dst = dstImage->cast<Image>();
483 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
484 rx::CLEventImpl::CreateFunc eventCreateFunc;
485 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
486 event != nullptr ? &eventCreateFunc : nullptr;
487 InitializeOutputEvent(event);
488
489 ANGLE_TRY(mImpl->enqueueCopyBufferToImage(src, dst, srcOffset, dstOrigin, region, waitEvents,
490 eventCreateFuncPtr));
491
492 CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER_TO_IMAGE, eventCreateFunc, event);
493 return angle::Result::Continue;
494 }
495
enqueueMapImage(cl_mem image,cl_bool blockingMap,MapFlags mapFlags,const cl::MemOffsets & origin,const cl::Coordinate & region,size_t * imageRowPitch,size_t * imageSlicePitch,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event,void * & mapPtr)496 angle::Result CommandQueue::enqueueMapImage(cl_mem image,
497 cl_bool blockingMap,
498 MapFlags mapFlags,
499 const cl::MemOffsets &origin,
500 const cl::Coordinate ®ion,
501 size_t *imageRowPitch,
502 size_t *imageSlicePitch,
503 cl_uint numEventsInWaitList,
504 const cl_event *eventWaitList,
505 cl_event *event,
506 void *&mapPtr)
507 {
508 const Image &img = image->cast<Image>();
509 const bool blocking = blockingMap != CL_FALSE;
510 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
511 rx::CLEventImpl::CreateFunc eventCreateFunc;
512 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
513 event != nullptr ? &eventCreateFunc : nullptr;
514 InitializeOutputEvent(event);
515
516 ANGLE_TRY(mImpl->enqueueMapImage(img, blocking, mapFlags, origin, region, imageRowPitch,
517 imageSlicePitch, waitEvents, eventCreateFuncPtr, mapPtr));
518
519 CheckCreateEvent(*this, CL_COMMAND_MAP_IMAGE, eventCreateFunc, event);
520 return angle::Result::Continue;
521 }
522
enqueueUnmapMemObject(cl_mem memobj,void * mappedPtr,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)523 angle::Result CommandQueue::enqueueUnmapMemObject(cl_mem memobj,
524 void *mappedPtr,
525 cl_uint numEventsInWaitList,
526 const cl_event *eventWaitList,
527 cl_event *event)
528 {
529 const Memory &memory = memobj->cast<Memory>();
530 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
531 rx::CLEventImpl::CreateFunc eventCreateFunc;
532 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
533 event != nullptr ? &eventCreateFunc : nullptr;
534 InitializeOutputEvent(event);
535
536 ANGLE_TRY(mImpl->enqueueUnmapMemObject(memory, mappedPtr, waitEvents, eventCreateFuncPtr));
537
538 CheckCreateEvent(*this, CL_COMMAND_UNMAP_MEM_OBJECT, eventCreateFunc, event);
539 return angle::Result::Continue;
540 }
541
enqueueMigrateMemObjects(cl_uint numMemObjects,const cl_mem * memObjects,MemMigrationFlags flags,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)542 angle::Result CommandQueue::enqueueMigrateMemObjects(cl_uint numMemObjects,
543 const cl_mem *memObjects,
544 MemMigrationFlags flags,
545 cl_uint numEventsInWaitList,
546 const cl_event *eventWaitList,
547 cl_event *event)
548 {
549 MemoryPtrs memories;
550 memories.reserve(numMemObjects);
551 while (numMemObjects-- != 0u)
552 {
553 memories.emplace_back(&(*memObjects++)->cast<Memory>());
554 }
555 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
556 rx::CLEventImpl::CreateFunc eventCreateFunc;
557 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
558 event != nullptr ? &eventCreateFunc : nullptr;
559 InitializeOutputEvent(event);
560
561 ANGLE_TRY(mImpl->enqueueMigrateMemObjects(memories, flags, waitEvents, eventCreateFuncPtr));
562
563 CheckCreateEvent(*this, CL_COMMAND_MIGRATE_MEM_OBJECTS, eventCreateFunc, event);
564 return angle::Result::Continue;
565 }
566
enqueueNDRangeKernel(cl_kernel kernel,const NDRange & ndrange,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)567 angle::Result CommandQueue::enqueueNDRangeKernel(cl_kernel kernel,
568 const NDRange &ndrange,
569 cl_uint numEventsInWaitList,
570 const cl_event *eventWaitList,
571 cl_event *event)
572 {
573 const Kernel &krnl = kernel->cast<Kernel>();
574 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
575 rx::CLEventImpl::CreateFunc eventCreateFunc;
576 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
577 event != nullptr ? &eventCreateFunc : nullptr;
578 InitializeOutputEvent(event);
579
580 ANGLE_TRY(mImpl->enqueueNDRangeKernel(krnl, ndrange, waitEvents, eventCreateFuncPtr));
581
582 CheckCreateEvent(*this, CL_COMMAND_NDRANGE_KERNEL, eventCreateFunc, event);
583 return angle::Result::Continue;
584 }
585
enqueueTask(cl_kernel kernel,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)586 angle::Result CommandQueue::enqueueTask(cl_kernel kernel,
587 cl_uint numEventsInWaitList,
588 const cl_event *eventWaitList,
589 cl_event *event)
590 {
591 const Kernel &krnl = kernel->cast<Kernel>();
592 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
593 rx::CLEventImpl::CreateFunc eventCreateFunc;
594 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
595 event != nullptr ? &eventCreateFunc : nullptr;
596 InitializeOutputEvent(event);
597
598 ANGLE_TRY(mImpl->enqueueTask(krnl, waitEvents, eventCreateFuncPtr));
599
600 CheckCreateEvent(*this, CL_COMMAND_TASK, eventCreateFunc, event);
601 return angle::Result::Continue;
602 }
603
enqueueNativeKernel(UserFunc userFunc,void * args,size_t cbArgs,cl_uint numMemObjects,const cl_mem * memList,const void ** argsMemLoc,cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)604 angle::Result CommandQueue::enqueueNativeKernel(UserFunc userFunc,
605 void *args,
606 size_t cbArgs,
607 cl_uint numMemObjects,
608 const cl_mem *memList,
609 const void **argsMemLoc,
610 cl_uint numEventsInWaitList,
611 const cl_event *eventWaitList,
612 cl_event *event)
613 {
614 std::vector<unsigned char> funcArgs;
615 BufferPtrs buffers;
616 std::vector<size_t> offsets;
617 if (numMemObjects != 0u)
618 {
619 // If argument memory block contains memory objects, make a copy.
620 funcArgs.resize(cbArgs);
621 std::memcpy(funcArgs.data(), args, cbArgs);
622 buffers.reserve(numMemObjects);
623 offsets.reserve(numMemObjects);
624
625 while (numMemObjects-- != 0u)
626 {
627 buffers.emplace_back(&(*memList++)->cast<Buffer>());
628
629 // Calc memory offset of cl_mem object in args.
630 offsets.emplace_back(static_cast<const char *>(*argsMemLoc++) -
631 static_cast<const char *>(args));
632
633 // Fetch location of cl_mem object in copied function argument memory block.
634 void *loc = &funcArgs[offsets.back()];
635
636 // Cast cl_mem object to cl::Buffer pointer in place.
637 *reinterpret_cast<Buffer **>(loc) = &(*reinterpret_cast<cl_mem *>(loc))->cast<Buffer>();
638 }
639
640 // Use copied argument memory block.
641 args = funcArgs.data();
642 }
643
644 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
645 rx::CLEventImpl::CreateFunc eventCreateFunc;
646 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
647 event != nullptr ? &eventCreateFunc : nullptr;
648 InitializeOutputEvent(event);
649
650 ANGLE_TRY(mImpl->enqueueNativeKernel(userFunc, args, cbArgs, buffers, offsets, waitEvents,
651 eventCreateFuncPtr));
652
653 CheckCreateEvent(*this, CL_COMMAND_NATIVE_KERNEL, eventCreateFunc, event);
654 return angle::Result::Continue;
655 }
656
enqueueMarkerWithWaitList(cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)657 angle::Result CommandQueue::enqueueMarkerWithWaitList(cl_uint numEventsInWaitList,
658 const cl_event *eventWaitList,
659 cl_event *event)
660 {
661 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
662 rx::CLEventImpl::CreateFunc eventCreateFunc;
663 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
664 event != nullptr ? &eventCreateFunc : nullptr;
665 InitializeOutputEvent(event);
666
667 ANGLE_TRY(mImpl->enqueueMarkerWithWaitList(waitEvents, eventCreateFuncPtr));
668
669 CheckCreateEvent(*this, CL_COMMAND_MARKER, eventCreateFunc, event);
670 return angle::Result::Continue;
671 }
672
enqueueMarker(cl_event * event)673 angle::Result CommandQueue::enqueueMarker(cl_event *event)
674 {
675 rx::CLEventImpl::CreateFunc eventCreateFunc;
676 InitializeOutputEvent(event);
677
678 ANGLE_TRY(mImpl->enqueueMarker(eventCreateFunc));
679
680 CheckCreateEvent(*this, CL_COMMAND_MARKER, eventCreateFunc, event);
681 return angle::Result::Continue;
682 }
683
enqueueWaitForEvents(cl_uint numEvents,const cl_event * eventList)684 angle::Result CommandQueue::enqueueWaitForEvents(cl_uint numEvents, const cl_event *eventList)
685 {
686 return mImpl->enqueueWaitForEvents(Event::Cast(numEvents, eventList));
687 }
688
enqueueBarrierWithWaitList(cl_uint numEventsInWaitList,const cl_event * eventWaitList,cl_event * event)689 angle::Result CommandQueue::enqueueBarrierWithWaitList(cl_uint numEventsInWaitList,
690 const cl_event *eventWaitList,
691 cl_event *event)
692 {
693 const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
694 rx::CLEventImpl::CreateFunc eventCreateFunc;
695 rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
696 event != nullptr ? &eventCreateFunc : nullptr;
697 InitializeOutputEvent(event);
698
699 ANGLE_TRY(mImpl->enqueueBarrierWithWaitList(waitEvents, eventCreateFuncPtr));
700
701 CheckCreateEvent(*this, CL_COMMAND_BARRIER, eventCreateFunc, event);
702 return angle::Result::Continue;
703 }
704
enqueueBarrier()705 angle::Result CommandQueue::enqueueBarrier()
706 {
707 return mImpl->enqueueBarrier();
708 }
709
flush()710 angle::Result CommandQueue::flush()
711 {
712 return mImpl->flush();
713 }
714
finish()715 angle::Result CommandQueue::finish()
716 {
717 return mImpl->finish();
718 }
719
~CommandQueue()720 CommandQueue::~CommandQueue()
721 {
722 auto queue = mDevice->mDefaultCommandQueue.synchronize();
723 if (*queue == this)
724 {
725 *queue = nullptr;
726 }
727 }
728
getDeviceIndex() const729 size_t CommandQueue::getDeviceIndex() const
730 {
731 return std::find(mContext->getDevices().cbegin(), mContext->getDevices().cend(), mDevice) -
732 mContext->getDevices().cbegin();
733 }
734
CommandQueue(Context & context,Device & device,PropArray && propArray,CommandQueueProperties properties,cl_uint size)735 CommandQueue::CommandQueue(Context &context,
736 Device &device,
737 PropArray &&propArray,
738 CommandQueueProperties properties,
739 cl_uint size)
740 : mContext(&context),
741 mDevice(&device),
742 mPropArray(std::move(propArray)),
743 mProperties(properties),
744 mSize(size),
745 mImpl(nullptr)
746 {
747 ANGLE_CL_IMPL_TRY(context.getImpl().createCommandQueue(*this, &mImpl));
748 if (mProperties->intersects(CL_QUEUE_ON_DEVICE_DEFAULT))
749 {
750 *mDevice->mDefaultCommandQueue = this;
751 }
752 }
753
CommandQueue(Context & context,Device & device,CommandQueueProperties properties)754 CommandQueue::CommandQueue(Context &context, Device &device, CommandQueueProperties properties)
755 : mContext(&context), mDevice(&device), mProperties(properties), mImpl(nullptr)
756 {
757 ANGLE_CL_IMPL_TRY(context.getImpl().createCommandQueue(*this, &mImpl));
758 }
759
760 } // namespace cl
761