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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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 ®ion,
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