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 // CLCommandQueueCL.cpp: Implements the class methods for CLCommandQueueCL.
7 
8 #include "libANGLE/renderer/cl/CLCommandQueueCL.h"
9 
10 #include "libANGLE/renderer/cl/CLContextCL.h"
11 #include "libANGLE/renderer/cl/CLEventCL.h"
12 #include "libANGLE/renderer/cl/CLKernelCL.h"
13 #include "libANGLE/renderer/cl/CLMemoryCL.h"
14 
15 #include "libANGLE/CLBuffer.h"
16 #include "libANGLE/CLCommandQueue.h"
17 #include "libANGLE/CLContext.h"
18 #include "libANGLE/CLImage.h"
19 #include "libANGLE/CLKernel.h"
20 #include "libANGLE/CLMemory.h"
21 
22 namespace rx
23 {
24 
25 namespace
26 {
27 
CheckCreateEvent(cl_int errorCode,cl_event nativeEvent,CLEventImpl::CreateFunc * createFunc)28 void CheckCreateEvent(cl_int errorCode, cl_event nativeEvent, CLEventImpl::CreateFunc *createFunc)
29 {
30     if (errorCode == CL_SUCCESS && createFunc != nullptr)
31     {
32         *createFunc = [nativeEvent](const cl::Event &event) {
33             return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
34         };
35     }
36 }
37 
38 }  // namespace
39 
CLCommandQueueCL(const cl::CommandQueue & commandQueue,cl_command_queue native)40 CLCommandQueueCL::CLCommandQueueCL(const cl::CommandQueue &commandQueue, cl_command_queue native)
41     : CLCommandQueueImpl(commandQueue), mNative(native)
42 {
43     if (commandQueue.getProperties().isSet(CL_QUEUE_ON_DEVICE))
44     {
45         commandQueue.getContext().getImpl<CLContextCL>().mData->mDeviceQueues.emplace(
46             commandQueue.getNative());
47     }
48 }
49 
~CLCommandQueueCL()50 CLCommandQueueCL::~CLCommandQueueCL()
51 {
52     if (mCommandQueue.getProperties().isSet(CL_QUEUE_ON_DEVICE))
53     {
54         const size_t numRemoved =
55             mCommandQueue.getContext().getImpl<CLContextCL>().mData->mDeviceQueues.erase(
56                 mCommandQueue.getNative());
57         ASSERT(numRemoved == 1u);
58     }
59 
60     if (mNative->getDispatch().clReleaseCommandQueue(mNative) != CL_SUCCESS)
61     {
62         ERR() << "Error while releasing CL command-queue";
63     }
64 }
65 
setProperty(cl::CommandQueueProperties properties,cl_bool enable)66 cl_int CLCommandQueueCL::setProperty(cl::CommandQueueProperties properties, cl_bool enable)
67 {
68     return mNative->getDispatch().clSetCommandQueueProperty(mNative, properties.get(), enable,
69                                                             nullptr);
70 }
71 
enqueueReadBuffer(const cl::Buffer & buffer,bool blocking,size_t offset,size_t size,void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)72 cl_int CLCommandQueueCL::enqueueReadBuffer(const cl::Buffer &buffer,
73                                            bool blocking,
74                                            size_t offset,
75                                            size_t size,
76                                            void *ptr,
77                                            const cl::EventPtrs &waitEvents,
78                                            CLEventImpl::CreateFunc *eventCreateFunc)
79 {
80     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
81     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
82     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
83     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
84     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
85     cl_event nativeEvent                     = nullptr;
86     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
87 
88     const cl_int errorCode =
89         mNative->getDispatch().clEnqueueReadBuffer(mNative, nativeBuffer, block, offset, size, ptr,
90                                                    numEvents, nativeEventsPtr, nativeEventPtr);
91 
92     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
93     return errorCode;
94 }
95 
enqueueWriteBuffer(const cl::Buffer & buffer,bool blocking,size_t offset,size_t size,const void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)96 cl_int CLCommandQueueCL::enqueueWriteBuffer(const cl::Buffer &buffer,
97                                             bool blocking,
98                                             size_t offset,
99                                             size_t size,
100                                             const void *ptr,
101                                             const cl::EventPtrs &waitEvents,
102                                             CLEventImpl::CreateFunc *eventCreateFunc)
103 {
104     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
105     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
106     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
107     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
108     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
109     cl_event nativeEvent                     = nullptr;
110     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
111 
112     const cl_int errorCode =
113         mNative->getDispatch().clEnqueueWriteBuffer(mNative, nativeBuffer, block, offset, size, ptr,
114                                                     numEvents, nativeEventsPtr, nativeEventPtr);
115 
116     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
117     return errorCode;
118 }
119 
enqueueReadBufferRect(const cl::Buffer & buffer,bool blocking,const size_t bufferOrigin[3],const size_t hostOrigin[3],const size_t region[3],size_t bufferRowPitch,size_t bufferSlicePitch,size_t hostRowPitch,size_t hostSlicePitch,void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)120 cl_int CLCommandQueueCL::enqueueReadBufferRect(const cl::Buffer &buffer,
121                                                bool blocking,
122                                                const size_t bufferOrigin[3],
123                                                const size_t hostOrigin[3],
124                                                const size_t region[3],
125                                                size_t bufferRowPitch,
126                                                size_t bufferSlicePitch,
127                                                size_t hostRowPitch,
128                                                size_t hostSlicePitch,
129                                                void *ptr,
130                                                const cl::EventPtrs &waitEvents,
131                                                CLEventImpl::CreateFunc *eventCreateFunc)
132 {
133     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
134     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
135     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
136     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
137     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
138     cl_event nativeEvent                     = nullptr;
139     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
140 
141     const cl_int errorCode = mNative->getDispatch().clEnqueueReadBufferRect(
142         mNative, nativeBuffer, block, bufferOrigin, hostOrigin, region, bufferRowPitch,
143         bufferSlicePitch, hostRowPitch, hostSlicePitch, ptr, numEvents, nativeEventsPtr,
144         nativeEventPtr);
145 
146     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
147     return errorCode;
148 }
149 
enqueueWriteBufferRect(const cl::Buffer & buffer,bool blocking,const size_t bufferOrigin[3],const size_t hostOrigin[3],const size_t region[3],size_t bufferRowPitch,size_t bufferSlicePitch,size_t hostRowPitch,size_t hostSlicePitch,const void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)150 cl_int CLCommandQueueCL::enqueueWriteBufferRect(const cl::Buffer &buffer,
151                                                 bool blocking,
152                                                 const size_t bufferOrigin[3],
153                                                 const size_t hostOrigin[3],
154                                                 const size_t region[3],
155                                                 size_t bufferRowPitch,
156                                                 size_t bufferSlicePitch,
157                                                 size_t hostRowPitch,
158                                                 size_t hostSlicePitch,
159                                                 const void *ptr,
160                                                 const cl::EventPtrs &waitEvents,
161                                                 CLEventImpl::CreateFunc *eventCreateFunc)
162 {
163     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
164     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
165     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
166     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
167     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
168     cl_event nativeEvent                     = nullptr;
169     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
170 
171     const cl_int errorCode = mNative->getDispatch().clEnqueueWriteBufferRect(
172         mNative, nativeBuffer, block, bufferOrigin, hostOrigin, region, bufferRowPitch,
173         bufferSlicePitch, hostRowPitch, hostSlicePitch, ptr, numEvents, nativeEventsPtr,
174         nativeEventPtr);
175 
176     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
177     return errorCode;
178 }
179 
enqueueCopyBuffer(const cl::Buffer & srcBuffer,const cl::Buffer & dstBuffer,size_t srcOffset,size_t dstOffset,size_t size,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)180 cl_int CLCommandQueueCL::enqueueCopyBuffer(const cl::Buffer &srcBuffer,
181                                            const cl::Buffer &dstBuffer,
182                                            size_t srcOffset,
183                                            size_t dstOffset,
184                                            size_t size,
185                                            const cl::EventPtrs &waitEvents,
186                                            CLEventImpl::CreateFunc *eventCreateFunc)
187 {
188     const cl_mem nativeSrc                   = srcBuffer.getImpl<CLMemoryCL>().getNative();
189     const cl_mem nativeDst                   = dstBuffer.getImpl<CLMemoryCL>().getNative();
190     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
191     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
192     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
193     cl_event nativeEvent                     = nullptr;
194     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
195 
196     const cl_int errorCode = mNative->getDispatch().clEnqueueCopyBuffer(
197         mNative, nativeSrc, nativeDst, srcOffset, dstOffset, size, numEvents, nativeEventsPtr,
198         nativeEventPtr);
199 
200     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
201     return errorCode;
202 }
203 
enqueueCopyBufferRect(const cl::Buffer & srcBuffer,const cl::Buffer & dstBuffer,const size_t srcOrigin[3],const size_t dstOrigin[3],const size_t region[3],size_t srcRowPitch,size_t srcSlicePitch,size_t dstRowPitch,size_t dstSlicePitch,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)204 cl_int CLCommandQueueCL::enqueueCopyBufferRect(const cl::Buffer &srcBuffer,
205                                                const cl::Buffer &dstBuffer,
206                                                const size_t srcOrigin[3],
207                                                const size_t dstOrigin[3],
208                                                const size_t region[3],
209                                                size_t srcRowPitch,
210                                                size_t srcSlicePitch,
211                                                size_t dstRowPitch,
212                                                size_t dstSlicePitch,
213                                                const cl::EventPtrs &waitEvents,
214                                                CLEventImpl::CreateFunc *eventCreateFunc)
215 {
216     const cl_mem nativeSrc                   = srcBuffer.getImpl<CLMemoryCL>().getNative();
217     const cl_mem nativeDst                   = dstBuffer.getImpl<CLMemoryCL>().getNative();
218     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
219     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
220     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
221     cl_event nativeEvent                     = nullptr;
222     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
223 
224     const cl_int errorCode = mNative->getDispatch().clEnqueueCopyBufferRect(
225         mNative, nativeSrc, nativeDst, srcOrigin, dstOrigin, region, srcRowPitch, srcSlicePitch,
226         dstRowPitch, dstSlicePitch, numEvents, nativeEventsPtr, nativeEventPtr);
227 
228     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
229     return errorCode;
230 }
231 
enqueueFillBuffer(const cl::Buffer & buffer,const void * pattern,size_t patternSize,size_t offset,size_t size,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)232 cl_int CLCommandQueueCL::enqueueFillBuffer(const cl::Buffer &buffer,
233                                            const void *pattern,
234                                            size_t patternSize,
235                                            size_t offset,
236                                            size_t size,
237                                            const cl::EventPtrs &waitEvents,
238                                            CLEventImpl::CreateFunc *eventCreateFunc)
239 {
240     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
241     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
242     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
243     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
244     cl_event nativeEvent                     = nullptr;
245     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
246 
247     const cl_int errorCode = mNative->getDispatch().clEnqueueFillBuffer(
248         mNative, nativeBuffer, pattern, patternSize, offset, size, numEvents, nativeEventsPtr,
249         nativeEventPtr);
250 
251     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
252     return errorCode;
253 }
254 
enqueueMapBuffer(const cl::Buffer & buffer,bool blocking,cl::MapFlags mapFlags,size_t offset,size_t size,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc,cl_int & errorCode)255 void *CLCommandQueueCL::enqueueMapBuffer(const cl::Buffer &buffer,
256                                          bool blocking,
257                                          cl::MapFlags mapFlags,
258                                          size_t offset,
259                                          size_t size,
260                                          const cl::EventPtrs &waitEvents,
261                                          CLEventImpl::CreateFunc *eventCreateFunc,
262                                          cl_int &errorCode)
263 {
264     const cl_mem nativeBuffer                = buffer.getImpl<CLMemoryCL>().getNative();
265     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
266     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
267     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
268     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
269     cl_event nativeEvent                     = nullptr;
270     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
271 
272     void *const map = mNative->getDispatch().clEnqueueMapBuffer(
273         mNative, nativeBuffer, block, mapFlags.get(), offset, size, numEvents, nativeEventsPtr,
274         nativeEventPtr, &errorCode);
275 
276     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
277     return map;
278 }
279 
enqueueReadImage(const cl::Image & image,bool blocking,const size_t origin[3],const size_t region[3],size_t rowPitch,size_t slicePitch,void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)280 cl_int CLCommandQueueCL::enqueueReadImage(const cl::Image &image,
281                                           bool blocking,
282                                           const size_t origin[3],
283                                           const size_t region[3],
284                                           size_t rowPitch,
285                                           size_t slicePitch,
286                                           void *ptr,
287                                           const cl::EventPtrs &waitEvents,
288                                           CLEventImpl::CreateFunc *eventCreateFunc)
289 {
290     const cl_mem nativeImage                 = image.getImpl<CLMemoryCL>().getNative();
291     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
292     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
293     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
294     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
295     cl_event nativeEvent                     = nullptr;
296     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
297 
298     const cl_int errorCode = mNative->getDispatch().clEnqueueReadImage(
299         mNative, nativeImage, block, origin, region, rowPitch, slicePitch, ptr, numEvents,
300         nativeEventsPtr, nativeEventPtr);
301 
302     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
303     return errorCode;
304 }
305 
enqueueWriteImage(const cl::Image & image,bool blocking,const size_t origin[3],const size_t region[3],size_t inputRowPitch,size_t inputSlicePitch,const void * ptr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)306 cl_int CLCommandQueueCL::enqueueWriteImage(const cl::Image &image,
307                                            bool blocking,
308                                            const size_t origin[3],
309                                            const size_t region[3],
310                                            size_t inputRowPitch,
311                                            size_t inputSlicePitch,
312                                            const void *ptr,
313                                            const cl::EventPtrs &waitEvents,
314                                            CLEventImpl::CreateFunc *eventCreateFunc)
315 {
316     const cl_mem nativeImage                 = image.getImpl<CLMemoryCL>().getNative();
317     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
318     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
319     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
320     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
321     cl_event nativeEvent                     = nullptr;
322     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
323 
324     const cl_int errorCode = mNative->getDispatch().clEnqueueWriteImage(
325         mNative, nativeImage, block, origin, region, inputRowPitch, inputSlicePitch, ptr, numEvents,
326         nativeEventsPtr, nativeEventPtr);
327 
328     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
329     return errorCode;
330 }
331 
enqueueCopyImage(const cl::Image & srcImage,const cl::Image & dstImage,const size_t srcOrigin[3],const size_t dstOrigin[3],const size_t region[3],const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)332 cl_int CLCommandQueueCL::enqueueCopyImage(const cl::Image &srcImage,
333                                           const cl::Image &dstImage,
334                                           const size_t srcOrigin[3],
335                                           const size_t dstOrigin[3],
336                                           const size_t region[3],
337                                           const cl::EventPtrs &waitEvents,
338                                           CLEventImpl::CreateFunc *eventCreateFunc)
339 {
340     const cl_mem nativeSrc                   = srcImage.getImpl<CLMemoryCL>().getNative();
341     const cl_mem nativeDst                   = dstImage.getImpl<CLMemoryCL>().getNative();
342     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
343     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
344     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
345     cl_event nativeEvent                     = nullptr;
346     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
347 
348     const cl_int errorCode = mNative->getDispatch().clEnqueueCopyImage(
349         mNative, nativeSrc, nativeDst, srcOrigin, dstOrigin, region, numEvents, nativeEventsPtr,
350         nativeEventPtr);
351 
352     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
353     return errorCode;
354 }
355 
enqueueFillImage(const cl::Image & image,const void * fillColor,const size_t origin[3],const size_t region[3],const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)356 cl_int CLCommandQueueCL::enqueueFillImage(const cl::Image &image,
357                                           const void *fillColor,
358                                           const size_t origin[3],
359                                           const size_t region[3],
360                                           const cl::EventPtrs &waitEvents,
361                                           CLEventImpl::CreateFunc *eventCreateFunc)
362 {
363     const cl_mem nativeImage                 = image.getImpl<CLMemoryCL>().getNative();
364     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
365     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
366     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
367     cl_event nativeEvent                     = nullptr;
368     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
369 
370     const cl_int errorCode =
371         mNative->getDispatch().clEnqueueFillImage(mNative, nativeImage, fillColor, origin, region,
372                                                   numEvents, nativeEventsPtr, nativeEventPtr);
373 
374     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
375     return errorCode;
376 }
377 
enqueueCopyImageToBuffer(const cl::Image & srcImage,const cl::Buffer & dstBuffer,const size_t srcOrigin[3],const size_t region[3],size_t dstOffset,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)378 cl_int CLCommandQueueCL::enqueueCopyImageToBuffer(const cl::Image &srcImage,
379                                                   const cl::Buffer &dstBuffer,
380                                                   const size_t srcOrigin[3],
381                                                   const size_t region[3],
382                                                   size_t dstOffset,
383                                                   const cl::EventPtrs &waitEvents,
384                                                   CLEventImpl::CreateFunc *eventCreateFunc)
385 {
386     const cl_mem nativeSrc                   = srcImage.getImpl<CLMemoryCL>().getNative();
387     const cl_mem nativeDst                   = dstBuffer.getImpl<CLMemoryCL>().getNative();
388     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
389     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
390     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
391     cl_event nativeEvent                     = nullptr;
392     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
393 
394     const cl_int errorCode = mNative->getDispatch().clEnqueueCopyImageToBuffer(
395         mNative, nativeSrc, nativeDst, srcOrigin, region, dstOffset, numEvents, nativeEventsPtr,
396         nativeEventPtr);
397 
398     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
399     return errorCode;
400 }
401 
enqueueCopyBufferToImage(const cl::Buffer & srcBuffer,const cl::Image & dstImage,size_t srcOffset,const size_t dstOrigin[3],const size_t region[3],const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)402 cl_int CLCommandQueueCL::enqueueCopyBufferToImage(const cl::Buffer &srcBuffer,
403                                                   const cl::Image &dstImage,
404                                                   size_t srcOffset,
405                                                   const size_t dstOrigin[3],
406                                                   const size_t region[3],
407                                                   const cl::EventPtrs &waitEvents,
408                                                   CLEventImpl::CreateFunc *eventCreateFunc)
409 {
410     const cl_mem nativeSrc                   = srcBuffer.getImpl<CLMemoryCL>().getNative();
411     const cl_mem nativeDst                   = dstImage.getImpl<CLMemoryCL>().getNative();
412     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
413     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
414     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
415     cl_event nativeEvent                     = nullptr;
416     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
417 
418     const cl_int errorCode = mNative->getDispatch().clEnqueueCopyBufferToImage(
419         mNative, nativeSrc, nativeDst, srcOffset, dstOrigin, region, numEvents, nativeEventsPtr,
420         nativeEventPtr);
421 
422     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
423     return errorCode;
424 }
425 
enqueueMapImage(const cl::Image & image,bool blocking,cl::MapFlags mapFlags,const size_t origin[3],const size_t region[3],size_t * imageRowPitch,size_t * imageSlicePitch,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc,cl_int & errorCode)426 void *CLCommandQueueCL::enqueueMapImage(const cl::Image &image,
427                                         bool blocking,
428                                         cl::MapFlags mapFlags,
429                                         const size_t origin[3],
430                                         const size_t region[3],
431                                         size_t *imageRowPitch,
432                                         size_t *imageSlicePitch,
433                                         const cl::EventPtrs &waitEvents,
434                                         CLEventImpl::CreateFunc *eventCreateFunc,
435                                         cl_int &errorCode)
436 {
437     const cl_mem nativeImage                 = image.getImpl<CLMemoryCL>().getNative();
438     const cl_bool block                      = blocking ? CL_TRUE : CL_FALSE;
439     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
440     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
441     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
442     cl_event nativeEvent                     = nullptr;
443     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
444 
445     void *const map = mNative->getDispatch().clEnqueueMapImage(
446         mNative, nativeImage, block, mapFlags.get(), origin, region, imageRowPitch, imageSlicePitch,
447         numEvents, nativeEventsPtr, nativeEventPtr, &errorCode);
448 
449     // TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/6066
450     if (imageSlicePitch != nullptr && (image.getType() == cl::MemObjectType::Image1D ||
451                                        image.getType() == cl::MemObjectType::Image1D_Buffer ||
452                                        image.getType() == cl::MemObjectType::Image2D))
453     {
454         *imageSlicePitch = 0u;
455     }
456 
457     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
458     return map;
459 }
460 
enqueueUnmapMemObject(const cl::Memory & memory,void * mappedPtr,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)461 cl_int CLCommandQueueCL::enqueueUnmapMemObject(const cl::Memory &memory,
462                                                void *mappedPtr,
463                                                const cl::EventPtrs &waitEvents,
464                                                CLEventImpl::CreateFunc *eventCreateFunc)
465 {
466     const cl_mem nativeMemory                = memory.getImpl<CLMemoryCL>().getNative();
467     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
468     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
469     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
470     cl_event nativeEvent                     = nullptr;
471     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
472 
473     const cl_int errorCode = mNative->getDispatch().clEnqueueUnmapMemObject(
474         mNative, nativeMemory, mappedPtr, numEvents, nativeEventsPtr, nativeEventPtr);
475 
476     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
477     return errorCode;
478 }
479 
enqueueMigrateMemObjects(const cl::MemoryPtrs & memObjects,cl::MemMigrationFlags flags,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)480 cl_int CLCommandQueueCL::enqueueMigrateMemObjects(const cl::MemoryPtrs &memObjects,
481                                                   cl::MemMigrationFlags flags,
482                                                   const cl::EventPtrs &waitEvents,
483                                                   CLEventImpl::CreateFunc *eventCreateFunc)
484 {
485     std::vector<cl_mem> nativeMemories;
486     nativeMemories.reserve(memObjects.size());
487     for (const cl::MemoryPtr &memory : memObjects)
488     {
489         nativeMemories.emplace_back(memory->getImpl<CLMemoryCL>().getNative());
490     }
491     const cl_uint numMemories                = static_cast<cl_uint>(nativeMemories.size());
492     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
493     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
494     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
495     cl_event nativeEvent                     = nullptr;
496     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
497 
498     const cl_int errorCode = mNative->getDispatch().clEnqueueMigrateMemObjects(
499         mNative, numMemories, nativeMemories.data(), flags.get(), numEvents, nativeEventsPtr,
500         nativeEventPtr);
501 
502     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
503     return errorCode;
504 }
505 
enqueueNDRangeKernel(const cl::Kernel & kernel,cl_uint workDim,const size_t * globalWorkOffset,const size_t * globalWorkSize,const size_t * localWorkSize,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)506 cl_int CLCommandQueueCL::enqueueNDRangeKernel(const cl::Kernel &kernel,
507                                               cl_uint workDim,
508                                               const size_t *globalWorkOffset,
509                                               const size_t *globalWorkSize,
510                                               const size_t *localWorkSize,
511                                               const cl::EventPtrs &waitEvents,
512                                               CLEventImpl::CreateFunc *eventCreateFunc)
513 {
514     const cl_kernel nativeKernel             = kernel.getImpl<CLKernelCL>().getNative();
515     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
516     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
517     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
518     cl_event nativeEvent                     = nullptr;
519     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
520 
521     const cl_int errorCode = mNative->getDispatch().clEnqueueNDRangeKernel(
522         mNative, nativeKernel, workDim, globalWorkOffset, globalWorkSize, localWorkSize, numEvents,
523         nativeEventsPtr, nativeEventPtr);
524 
525     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
526     return errorCode;
527 }
528 
enqueueTask(const cl::Kernel & kernel,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)529 cl_int CLCommandQueueCL::enqueueTask(const cl::Kernel &kernel,
530                                      const cl::EventPtrs &waitEvents,
531                                      CLEventImpl::CreateFunc *eventCreateFunc)
532 {
533     const cl_kernel nativeKernel             = kernel.getImpl<CLKernelCL>().getNative();
534     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
535     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
536     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
537     cl_event nativeEvent                     = nullptr;
538     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
539 
540     const cl_int errorCode = mNative->getDispatch().clEnqueueTask(mNative, nativeKernel, numEvents,
541                                                                   nativeEventsPtr, nativeEventPtr);
542 
543     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
544     return errorCode;
545 }
546 
enqueueNativeKernel(cl::UserFunc userFunc,void * args,size_t cbArgs,const cl::BufferPtrs & buffers,const std::vector<size_t> bufferPtrOffsets,const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)547 cl_int CLCommandQueueCL::enqueueNativeKernel(cl::UserFunc userFunc,
548                                              void *args,
549                                              size_t cbArgs,
550                                              const cl::BufferPtrs &buffers,
551                                              const std::vector<size_t> bufferPtrOffsets,
552                                              const cl::EventPtrs &waitEvents,
553                                              CLEventImpl::CreateFunc *eventCreateFunc)
554 {
555     std::vector<unsigned char> funcArgs;
556     std::vector<const void *> locs;
557     if (!bufferPtrOffsets.empty())
558     {
559         // If argument memory block contains buffers, make a copy.
560         funcArgs.resize(cbArgs);
561         std::memcpy(funcArgs.data(), args, cbArgs);
562 
563         locs.reserve(bufferPtrOffsets.size());
564         for (size_t offset : bufferPtrOffsets)
565         {
566             // Fetch location of buffer in copied function argument memory block.
567             void *const loc = &funcArgs[offset];
568             locs.emplace_back(loc);
569 
570             // Cast cl::Buffer to native cl_mem object in place.
571             cl::Buffer *const buffer         = *reinterpret_cast<cl::Buffer **>(loc);
572             *reinterpret_cast<cl_mem *>(loc) = buffer->getImpl<CLMemoryCL>().getNative();
573         }
574 
575         // Use copied argument memory block.
576         args = funcArgs.data();
577     }
578 
579     std::vector<cl_mem> nativeBuffers;
580     nativeBuffers.reserve(buffers.size());
581     for (const cl::BufferPtr &buffer : buffers)
582     {
583         nativeBuffers.emplace_back(buffer->getImpl<CLMemoryCL>().getNative());
584     }
585     const cl_uint numBuffers             = static_cast<cl_uint>(nativeBuffers.size());
586     const cl_mem *const nativeBuffersPtr = nativeBuffers.empty() ? nullptr : nativeBuffers.data();
587     const void **const locsPtr           = locs.empty() ? nullptr : locs.data();
588 
589     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
590     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
591     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
592     cl_event nativeEvent                     = nullptr;
593     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
594 
595     const cl_int errorCode = mNative->getDispatch().clEnqueueNativeKernel(
596         mNative, userFunc, args, cbArgs, numBuffers, nativeBuffersPtr, locsPtr, numEvents,
597         nativeEventsPtr, nativeEventPtr);
598 
599     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
600     return errorCode;
601 }
602 
enqueueMarkerWithWaitList(const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)603 cl_int CLCommandQueueCL::enqueueMarkerWithWaitList(const cl::EventPtrs &waitEvents,
604                                                    CLEventImpl::CreateFunc *eventCreateFunc)
605 {
606     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
607     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
608     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
609     cl_event nativeEvent                     = nullptr;
610     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
611 
612     const cl_int errorCode = mNative->getDispatch().clEnqueueMarkerWithWaitList(
613         mNative, numEvents, nativeEventsPtr, nativeEventPtr);
614 
615     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
616     return errorCode;
617 }
618 
enqueueMarker(CLEventImpl::CreateFunc & eventCreateFunc)619 cl_int CLCommandQueueCL::enqueueMarker(CLEventImpl::CreateFunc &eventCreateFunc)
620 {
621     cl_event nativeEvent = nullptr;
622 
623     const cl_int errorCode = mNative->getDispatch().clEnqueueMarker(mNative, &nativeEvent);
624 
625     if (errorCode == CL_SUCCESS)
626     {
627         eventCreateFunc = [nativeEvent](const cl::Event &event) {
628             return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
629         };
630     }
631     return errorCode;
632 }
633 
enqueueWaitForEvents(const cl::EventPtrs & events)634 cl_int CLCommandQueueCL::enqueueWaitForEvents(const cl::EventPtrs &events)
635 {
636     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(events);
637     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
638 
639     return mNative->getDispatch().clEnqueueWaitForEvents(mNative, numEvents, nativeEvents.data());
640 }
641 
enqueueBarrierWithWaitList(const cl::EventPtrs & waitEvents,CLEventImpl::CreateFunc * eventCreateFunc)642 cl_int CLCommandQueueCL::enqueueBarrierWithWaitList(const cl::EventPtrs &waitEvents,
643                                                     CLEventImpl::CreateFunc *eventCreateFunc)
644 {
645     const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
646     const cl_uint numEvents                  = static_cast<cl_uint>(nativeEvents.size());
647     const cl_event *const nativeEventsPtr    = nativeEvents.empty() ? nullptr : nativeEvents.data();
648     cl_event nativeEvent                     = nullptr;
649     cl_event *const nativeEventPtr           = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
650 
651     const cl_int errorCode = mNative->getDispatch().clEnqueueBarrierWithWaitList(
652         mNative, numEvents, nativeEventsPtr, nativeEventPtr);
653 
654     CheckCreateEvent(errorCode, nativeEvent, eventCreateFunc);
655     return errorCode;
656 }
657 
enqueueBarrier()658 cl_int CLCommandQueueCL::enqueueBarrier()
659 {
660     return mNative->getDispatch().clEnqueueBarrier(mNative);
661 }
662 
flush()663 cl_int CLCommandQueueCL::flush()
664 {
665     return mNative->getDispatch().clFlush(mNative);
666 }
667 
finish()668 cl_int CLCommandQueueCL::finish()
669 {
670     return mNative->getDispatch().clFinish(mNative);
671 }
672 
673 }  // namespace rx
674