| // |
| // Copyright 2021 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // CLCommandQueue.cpp: Implements the cl::CommandQueue class. |
| |
| #include "libANGLE/CLCommandQueue.h" |
| |
| #include "libANGLE/CLBuffer.h" |
| #include "libANGLE/CLContext.h" |
| #include "libANGLE/CLDevice.h" |
| #include "libANGLE/CLEvent.h" |
| #include "libANGLE/CLImage.h" |
| #include "libANGLE/CLKernel.h" |
| #include "libANGLE/CLMemory.h" |
| |
| #include <cstring> |
| |
| namespace cl |
| { |
| |
| namespace |
| { |
| |
| void CheckCreateEvent(CommandQueue &queue, |
| cl_command_type commandType, |
| const rx::CLEventImpl::CreateFunc &createFunc, |
| cl_event *event, |
| cl_int &errorCode) |
| { |
| if (errorCode == CL_SUCCESS && event != nullptr) |
| { |
| ASSERT(createFunc); |
| *event = Object::Create<Event>(errorCode, queue, commandType, createFunc); |
| } |
| } |
| |
| } // namespace |
| |
| cl_int CommandQueue::getInfo(CommandQueueInfo name, |
| size_t valueSize, |
| void *value, |
| size_t *valueSizeRet) const |
| { |
| cl_command_queue_properties properties = 0u; |
| cl_uint valUInt = 0u; |
| void *valPointer = nullptr; |
| const void *copyValue = nullptr; |
| size_t copySize = 0u; |
| |
| switch (name) |
| { |
| case CommandQueueInfo::Context: |
| valPointer = mContext->getNative(); |
| copyValue = &valPointer; |
| copySize = sizeof(valPointer); |
| break; |
| case CommandQueueInfo::Device: |
| valPointer = mDevice->getNative(); |
| copyValue = &valPointer; |
| copySize = sizeof(valPointer); |
| break; |
| case CommandQueueInfo::ReferenceCount: |
| valUInt = getRefCount(); |
| copyValue = &valUInt; |
| copySize = sizeof(valUInt); |
| break; |
| case CommandQueueInfo::Properties: |
| properties = mProperties->get(); |
| copyValue = &properties; |
| copySize = sizeof(properties); |
| break; |
| case CommandQueueInfo::PropertiesArray: |
| copyValue = mPropArray.data(); |
| copySize = mPropArray.size() * sizeof(decltype(mPropArray)::value_type); |
| break; |
| case CommandQueueInfo::Size: |
| copyValue = &mSize; |
| copySize = sizeof(mSize); |
| break; |
| case CommandQueueInfo::DeviceDefault: |
| valPointer = CommandQueue::CastNative(*mDevice->mDefaultCommandQueue); |
| copyValue = &valPointer; |
| copySize = sizeof(valPointer); |
| break; |
| default: |
| return CL_INVALID_VALUE; |
| } |
| |
| if (value != nullptr) |
| { |
| // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type |
| // as specified in the Command Queue Parameter table, and param_value is not a NULL value. |
| if (valueSize < copySize) |
| { |
| return CL_INVALID_VALUE; |
| } |
| if (copyValue != nullptr) |
| { |
| std::memcpy(value, copyValue, copySize); |
| } |
| } |
| if (valueSizeRet != nullptr) |
| { |
| *valueSizeRet = copySize; |
| } |
| return CL_SUCCESS; |
| } |
| |
| cl_int CommandQueue::setProperty(CommandQueueProperties properties, |
| cl_bool enable, |
| cl_command_queue_properties *oldProperties) |
| { |
| auto props = mProperties.synchronize(); |
| if (oldProperties != nullptr) |
| { |
| *oldProperties = props->get(); |
| } |
| |
| ANGLE_CL_TRY(mImpl->setProperty(properties, enable)); |
| |
| if (enable == CL_FALSE) |
| { |
| props->clear(properties); |
| } |
| else |
| { |
| props->set(properties); |
| } |
| return CL_SUCCESS; |
| } |
| |
| cl_int CommandQueue::enqueueReadBuffer(cl_mem buffer, |
| cl_bool blockingRead, |
| size_t offset, |
| size_t size, |
| void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const bool blocking = blockingRead != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueReadBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_READ_BUFFER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueWriteBuffer(cl_mem buffer, |
| cl_bool blockingWrite, |
| size_t offset, |
| size_t size, |
| const void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const bool blocking = blockingWrite != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueWriteBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_WRITE_BUFFER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueReadBufferRect(cl_mem buffer, |
| cl_bool blockingRead, |
| const size_t *bufferOrigin, |
| const size_t *hostOrigin, |
| const size_t *region, |
| size_t bufferRowPitch, |
| size_t bufferSlicePitch, |
| size_t hostRowPitch, |
| size_t hostSlicePitch, |
| void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const bool blocking = blockingRead != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueReadBufferRect( |
| buf, blocking, bufferOrigin, hostOrigin, region, bufferRowPitch, bufferSlicePitch, |
| hostRowPitch, hostSlicePitch, ptr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_READ_BUFFER_RECT, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueWriteBufferRect(cl_mem buffer, |
| cl_bool blockingWrite, |
| const size_t *bufferOrigin, |
| const size_t *hostOrigin, |
| const size_t *region, |
| size_t bufferRowPitch, |
| size_t bufferSlicePitch, |
| size_t hostRowPitch, |
| size_t hostSlicePitch, |
| const void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const bool blocking = blockingWrite != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueWriteBufferRect( |
| buf, blocking, bufferOrigin, hostOrigin, region, bufferRowPitch, bufferSlicePitch, |
| hostRowPitch, hostSlicePitch, ptr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_WRITE_BUFFER_RECT, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueCopyBuffer(cl_mem srcBuffer, |
| cl_mem dstBuffer, |
| size_t srcOffset, |
| size_t dstOffset, |
| size_t size, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &src = srcBuffer->cast<Buffer>(); |
| const Buffer &dst = dstBuffer->cast<Buffer>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueCopyBuffer(src, dst, srcOffset, dstOffset, size, waitEvents, |
| eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueCopyBufferRect(cl_mem srcBuffer, |
| cl_mem dstBuffer, |
| const size_t *srcOrigin, |
| const size_t *dstOrigin, |
| const size_t *region, |
| size_t srcRowPitch, |
| size_t srcSlicePitch, |
| size_t dstRowPitch, |
| size_t dstSlicePitch, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &src = srcBuffer->cast<Buffer>(); |
| const Buffer &dst = dstBuffer->cast<Buffer>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueCopyBufferRect(src, dst, srcOrigin, dstOrigin, region, |
| srcRowPitch, srcSlicePitch, dstRowPitch, |
| dstSlicePitch, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER_RECT, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueFillBuffer(cl_mem buffer, |
| const void *pattern, |
| size_t patternSize, |
| size_t offset, |
| size_t size, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueFillBuffer(buf, pattern, patternSize, offset, size, waitEvents, |
| eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_FILL_BUFFER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| void *CommandQueue::enqueueMapBuffer(cl_mem buffer, |
| cl_bool blockingMap, |
| MapFlags mapFlags, |
| size_t offset, |
| size_t size, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event, |
| cl_int &errorCode) |
| { |
| const Buffer &buf = buffer->cast<Buffer>(); |
| const bool blocking = blockingMap != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| void *const map = mImpl->enqueueMapBuffer(buf, blocking, mapFlags, offset, size, waitEvents, |
| eventCreateFuncPtr, errorCode); |
| |
| CheckCreateEvent(*this, CL_COMMAND_MAP_BUFFER, eventCreateFunc, event, errorCode); |
| return map; |
| } |
| |
| cl_int CommandQueue::enqueueReadImage(cl_mem image, |
| cl_bool blockingRead, |
| const size_t *origin, |
| const size_t *region, |
| size_t rowPitch, |
| size_t slicePitch, |
| void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Image &img = image->cast<Image>(); |
| const bool blocking = blockingRead != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueReadImage(img, blocking, origin, region, rowPitch, slicePitch, |
| ptr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_READ_IMAGE, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueWriteImage(cl_mem image, |
| cl_bool blockingWrite, |
| const size_t *origin, |
| const size_t *region, |
| size_t inputRowPitch, |
| size_t inputSlicePitch, |
| const void *ptr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Image &img = image->cast<Image>(); |
| const bool blocking = blockingWrite != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueWriteImage(img, blocking, origin, region, inputRowPitch, inputSlicePitch, ptr, |
| waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_WRITE_IMAGE, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueCopyImage(cl_mem srcImage, |
| cl_mem dstImage, |
| const size_t *srcOrigin, |
| const size_t *dstOrigin, |
| const size_t *region, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Image &src = srcImage->cast<Image>(); |
| const Image &dst = dstImage->cast<Image>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueCopyImage(src, dst, srcOrigin, dstOrigin, region, waitEvents, |
| eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_COPY_IMAGE, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueFillImage(cl_mem image, |
| const void *fillColor, |
| const size_t *origin, |
| const size_t *region, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Image &img = image->cast<Image>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueFillImage(img, fillColor, origin, region, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_FILL_IMAGE, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueCopyImageToBuffer(cl_mem srcImage, |
| cl_mem dstBuffer, |
| const size_t *srcOrigin, |
| const size_t *region, |
| size_t dstOffset, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Image &src = srcImage->cast<Image>(); |
| const Buffer &dst = dstBuffer->cast<Buffer>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueCopyImageToBuffer(src, dst, srcOrigin, region, dstOffset, |
| waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_COPY_IMAGE_TO_BUFFER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueCopyBufferToImage(cl_mem srcBuffer, |
| cl_mem dstImage, |
| size_t srcOffset, |
| const size_t *dstOrigin, |
| const size_t *region, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Buffer &src = srcBuffer->cast<Buffer>(); |
| const Image &dst = dstImage->cast<Image>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueCopyBufferToImage(src, dst, srcOffset, dstOrigin, region, |
| waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_COPY_BUFFER_TO_IMAGE, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| void *CommandQueue::enqueueMapImage(cl_mem image, |
| cl_bool blockingMap, |
| MapFlags mapFlags, |
| const size_t *origin, |
| const size_t *region, |
| size_t *imageRowPitch, |
| size_t *imageSlicePitch, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event, |
| cl_int &errorCode) |
| { |
| const Image &img = image->cast<Image>(); |
| const bool blocking = blockingMap != CL_FALSE; |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| void *const map = |
| mImpl->enqueueMapImage(img, blocking, mapFlags, origin, region, imageRowPitch, |
| imageSlicePitch, waitEvents, eventCreateFuncPtr, errorCode); |
| |
| CheckCreateEvent(*this, CL_COMMAND_MAP_IMAGE, eventCreateFunc, event, errorCode); |
| return map; |
| } |
| |
| cl_int CommandQueue::enqueueUnmapMemObject(cl_mem memobj, |
| void *mappedPtr, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Memory &memory = memobj->cast<Memory>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueUnmapMemObject(memory, mappedPtr, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_UNMAP_MEM_OBJECT, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueMigrateMemObjects(cl_uint numMemObjects, |
| const cl_mem *memObjects, |
| MemMigrationFlags flags, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| MemoryPtrs memories; |
| memories.reserve(numMemObjects); |
| while (numMemObjects-- != 0u) |
| { |
| memories.emplace_back(&(*memObjects++)->cast<Memory>()); |
| } |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = |
| mImpl->enqueueMigrateMemObjects(memories, flags, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_MIGRATE_MEM_OBJECTS, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueNDRangeKernel(cl_kernel kernel, |
| cl_uint workDim, |
| const size_t *globalWorkOffset, |
| const size_t *globalWorkSize, |
| const size_t *localWorkSize, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Kernel &krnl = kernel->cast<Kernel>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueNDRangeKernel(krnl, workDim, globalWorkOffset, globalWorkSize, |
| localWorkSize, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_NDRANGE_KERNEL, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueTask(cl_kernel kernel, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const Kernel &krnl = kernel->cast<Kernel>(); |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueTask(krnl, waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_TASK, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueNativeKernel(UserFunc userFunc, |
| void *args, |
| size_t cbArgs, |
| cl_uint numMemObjects, |
| const cl_mem *memList, |
| const void **argsMemLoc, |
| cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| std::vector<unsigned char> funcArgs; |
| BufferPtrs buffers; |
| std::vector<size_t> offsets; |
| if (numMemObjects != 0u) |
| { |
| // If argument memory block contains memory objects, make a copy. |
| funcArgs.resize(cbArgs); |
| std::memcpy(funcArgs.data(), args, cbArgs); |
| buffers.reserve(numMemObjects); |
| offsets.reserve(numMemObjects); |
| |
| while (numMemObjects-- != 0u) |
| { |
| buffers.emplace_back(&(*memList++)->cast<Buffer>()); |
| |
| // Calc memory offset of cl_mem object in args. |
| offsets.emplace_back(static_cast<const char *>(*argsMemLoc++) - |
| static_cast<const char *>(args)); |
| |
| // Fetch location of cl_mem object in copied function argument memory block. |
| void *loc = &funcArgs[offsets.back()]; |
| |
| // Cast cl_mem object to cl::Buffer pointer in place. |
| *reinterpret_cast<Buffer **>(loc) = &(*reinterpret_cast<cl_mem *>(loc))->cast<Buffer>(); |
| } |
| |
| // Use copied argument memory block. |
| args = funcArgs.data(); |
| } |
| |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueNativeKernel(userFunc, args, cbArgs, buffers, offsets, |
| waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_NATIVE_KERNEL, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueMarkerWithWaitList(cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueMarkerWithWaitList(waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_MARKER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueMarker(cl_event *event) |
| { |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| |
| cl_int errorCode = mImpl->enqueueMarker(eventCreateFunc); |
| |
| CheckCreateEvent(*this, CL_COMMAND_MARKER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueWaitForEvents(cl_uint numEvents, const cl_event *eventList) |
| { |
| return mImpl->enqueueWaitForEvents(Event::Cast(numEvents, eventList)); |
| } |
| |
| cl_int CommandQueue::enqueueBarrierWithWaitList(cl_uint numEventsInWaitList, |
| const cl_event *eventWaitList, |
| cl_event *event) |
| { |
| const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList); |
| rx::CLEventImpl::CreateFunc eventCreateFunc; |
| rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = |
| event != nullptr ? &eventCreateFunc : nullptr; |
| |
| cl_int errorCode = mImpl->enqueueBarrierWithWaitList(waitEvents, eventCreateFuncPtr); |
| |
| CheckCreateEvent(*this, CL_COMMAND_BARRIER, eventCreateFunc, event, errorCode); |
| return errorCode; |
| } |
| |
| cl_int CommandQueue::enqueueBarrier() |
| { |
| return mImpl->enqueueBarrier(); |
| } |
| |
| cl_int CommandQueue::flush() |
| { |
| return mImpl->flush(); |
| } |
| |
| cl_int CommandQueue::finish() |
| { |
| return mImpl->finish(); |
| } |
| |
| CommandQueue::~CommandQueue() |
| { |
| auto queue = mDevice->mDefaultCommandQueue.synchronize(); |
| if (*queue == this) |
| { |
| *queue = nullptr; |
| } |
| } |
| |
| size_t CommandQueue::getDeviceIndex() const |
| { |
| return std::find(mContext->getDevices().cbegin(), mContext->getDevices().cend(), mDevice) - |
| mContext->getDevices().cbegin(); |
| } |
| |
| CommandQueue::CommandQueue(Context &context, |
| Device &device, |
| PropArray &&propArray, |
| CommandQueueProperties properties, |
| cl_uint size, |
| cl_int &errorCode) |
| : mContext(&context), |
| mDevice(&device), |
| mPropArray(std::move(propArray)), |
| mProperties(properties), |
| mSize(size), |
| mImpl(context.getImpl().createCommandQueue(*this, errorCode)) |
| { |
| if (mProperties->isSet(CL_QUEUE_ON_DEVICE_DEFAULT)) |
| { |
| *mDevice->mDefaultCommandQueue = this; |
| } |
| } |
| |
| CommandQueue::CommandQueue(Context &context, |
| Device &device, |
| CommandQueueProperties properties, |
| cl_int &errorCode) |
| : mContext(&context), |
| mDevice(&device), |
| mProperties(properties), |
| mImpl(context.getImpl().createCommandQueue(*this, errorCode)) |
| {} |
| |
| } // namespace cl |