• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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