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