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