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