Commit 41b817f3 by John Plate Committed by Angle LUCI CQ

CL: Add buffer enqueue commands

Add buffer enqueue commands to front end and pass-through back end. Bug: angleproject:6015 Change-Id: I936530d31903e395550e4540339ebec2e6702e65 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2928425 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent daf18594
......@@ -50,6 +50,9 @@ class BitField
return (isSet(bits1) ? 1 : 0) + (isSet(bits2) ? 1 : 0) + (isSet(bits3) ? 1 : 0) <= 1;
}
BitField mask(cl_bitfield bits) const { return BitField(mBits & bits); }
BitField mask(const BitField &other) const { return BitField(mBits & other.mBits); }
void set(cl_bitfield bits) { mBits |= bits; }
void set(const BitField &other) { mBits |= other.mBits; }
void clear(cl_bitfield bits) { mBits &= ~bits; }
......
......@@ -23,6 +23,7 @@ class Buffer final : public Memory
const void *createInfo,
cl_int &errorCode);
bool isRegionValid(size_t offset, size_t size) const;
bool isRegionValid(const cl_buffer_region &region) const;
static bool IsValid(const _cl_mem *buffer);
......@@ -47,6 +48,11 @@ class Buffer final : public Memory
friend class Object;
};
inline bool Buffer::isRegionValid(size_t offset, size_t size) const
{
return offset < mSize && offset + size <= mSize;
}
inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
{
return region.origin < mSize && region.origin + region.size <= mSize;
......
......@@ -7,8 +7,10 @@
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLEvent.h"
#include <cstring>
......@@ -106,6 +108,237 @@ cl_int CommandQueue::setProperty(CommandQueueProperties properties,
return result;
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_READ_BUFFER, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_WRITE_BUFFER, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event =
Object::Create<Event>(errorCode, *this, CL_COMMAND_READ_BUFFER_RECT, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event =
Object::Create<Event>(errorCode, *this, CL_COMMAND_WRITE_BUFFER_RECT, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_COPY_BUFFER, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event =
Object::Create<Event>(errorCode, *this, CL_COMMAND_COPY_BUFFER_RECT, eventCreateFunc);
}
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);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_FILL_BUFFER, eventCreateFunc);
}
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 region = mImpl->enqueueMapBuffer(buf, blocking, mapFlags, offset, size, waitEvents,
eventCreateFuncPtr, errorCode);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_MAP_BUFFER, eventCreateFunc);
}
return region;
}
CommandQueue::~CommandQueue()
{
if (mDevice->mDefaultCommandQueue == this)
......
......@@ -31,6 +31,93 @@ class CommandQueue final : public _cl_command_queue, public Object
cl_bool enable,
cl_command_queue_properties *oldProperties);
cl_int 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);
cl_int 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);
cl_int 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);
cl_int 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);
cl_int 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);
cl_int 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);
cl_int 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);
void *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);
public:
using PropArray = std::vector<cl_queue_properties>;
......@@ -38,10 +125,14 @@ class CommandQueue final : public _cl_command_queue, public Object
~CommandQueue() override;
Context &getContext();
const Context &getContext() const;
const Device &getDevice() const;
CommandQueueProperties getProperties() const;
bool isOnHost() const;
bool isOnDevice() const;
bool hasSize() const;
cl_uint getSize() const;
......@@ -71,6 +162,11 @@ class CommandQueue final : public _cl_command_queue, public Object
friend class Object;
};
inline Context &CommandQueue::getContext()
{
return *mContext;
}
inline const Context &CommandQueue::getContext() const
{
return *mContext;
......@@ -86,6 +182,16 @@ inline CommandQueueProperties CommandQueue::getProperties() const
return mProperties;
}
inline bool CommandQueue::isOnHost() const
{
return mProperties.isNotSet(CL_QUEUE_ON_DEVICE);
}
inline bool CommandQueue::isOnDevice() const
{
return mProperties.isSet(CL_QUEUE_ON_DEVICE);
}
inline bool CommandQueue::hasSize() const
{
return mSize != kNoSize;
......
......@@ -292,13 +292,7 @@ cl_event Context::createUserEvent(cl_int &errorCode)
cl_int Context::waitForEvents(cl_uint numEvents, const cl_event *eventList)
{
EventPtrs events;
events.reserve(numEvents);
while (numEvents-- != 0u)
{
events.emplace_back(&(*eventList++)->cast<Event>());
}
return mImpl->waitForEvents(events);
return mImpl->waitForEvents(Event::Cast(numEvents, eventList));
}
Context::~Context() = default;
......
......@@ -71,7 +71,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
case DeviceInfo::MaxPipeArgs:
case DeviceInfo::PipeMaxActiveReservations:
case DeviceInfo::PipeMaxPacketSize:
case DeviceInfo::MemBaseAddrAlign:
case DeviceInfo::MinDataTypeAlignSize:
case DeviceInfo::GlobalMemCacheType:
case DeviceInfo::GlobalMemCachelineSize:
......@@ -221,6 +220,10 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copyValue = &mInfo.mImageBaseAddressAlignment;
copySize = sizeof(mInfo.mImageBaseAddressAlignment);
break;
case DeviceInfo::MemBaseAddrAlign:
copyValue = &mInfo.mMemBaseAddrAlign;
copySize = sizeof(mInfo.mMemBaseAddrAlign);
break;
case DeviceInfo::QueueOnDeviceMaxSize:
copyValue = &mInfo.mQueueOnDeviceMaxSize;
copySize = sizeof(mInfo.mQueueOnDeviceMaxSize);
......
......@@ -122,10 +122,31 @@ void Event::callback(cl_int commandStatus)
}
}
EventPtrs Event::Cast(cl_uint numEvents, const cl_event *eventList)
{
EventPtrs events;
events.reserve(numEvents);
while (numEvents-- != 0u)
{
events.emplace_back(&(*eventList++)->cast<Event>());
}
return events;
}
Event::Event(Context &context, cl_int &errorCode)
: mContext(&context),
mImpl(context.getImpl().createUserEvent(*this, errorCode)),
mCommandType(CL_COMMAND_USER)
mCommandType(CL_COMMAND_USER),
mImpl(context.getImpl().createUserEvent(*this, errorCode))
{}
Event::Event(CommandQueue &queue,
cl_command_type commandType,
const rx::CLEventImpl::CreateFunc &createFunc,
cl_int &errorCode)
: mContext(&queue.getContext()),
mCommandQueue(&queue),
mCommandType(commandType),
mImpl(createFunc(*this))
{}
} // namespace cl
......@@ -42,15 +42,22 @@ class Event final : public _cl_event, public Object
void callback(cl_int commandStatus);
static EventPtrs Cast(cl_uint numEvents, const cl_event *eventList);
private:
using CallbackData = std::pair<EventCB, void *>;
Event(Context &context, cl_int &errorCode);
Event(CommandQueue &queue,
cl_command_type commandType,
const rx::CLEventImpl::CreateFunc &createFunc,
cl_int &errorCode);
const ContextPtr mContext;
const CommandQueuePtr mCommandQueue;
const rx::CLEventImpl::Ptr mImpl;
const cl_command_type mCommandType;
const rx::CLEventImpl::Ptr mImpl;
bool mStatusWasChanged = false;
......
......@@ -103,6 +103,30 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu
Memory::~Memory() = default;
MemFlags Memory::getEffectiveFlags() const
{
MemFlags flags = mFlags;
if (mParent)
{
const MemFlags parent = mParent->getFlags();
const MemFlags access(CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
const MemFlags hostAccess(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY |
CL_MEM_HOST_NO_ACCESS);
const MemFlags hostPtrFlags(CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
CL_MEM_COPY_HOST_PTR);
if (flags.isNotSet(access))
{
flags.set(parent.mask(access));
}
if (flags.isNotSet(hostAccess))
{
flags.set(parent.mask(hostAccess));
}
flags.set(parent.mask(hostPtrFlags));
}
return flags;
}
Memory::Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
......
......@@ -39,6 +39,8 @@ class Memory : public _cl_mem, public Object
template <typename T = rx::CLMemoryImpl>
T &getImpl() const;
MemFlags getEffectiveFlags() const;
protected:
Memory(const Buffer &buffer,
Context &context,
......
......@@ -8,7 +8,7 @@
#ifndef LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#define LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#include "libANGLE/renderer/CLtypes.h"
#include "libANGLE/renderer/CLEventImpl.h"
namespace rx
{
......@@ -23,6 +23,85 @@ class CLCommandQueueImpl : angle::NonCopyable
virtual cl_int setProperty(cl::CommandQueueProperties properties, cl_bool enable) = 0;
virtual cl_int enqueueReadBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueWriteBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int 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) = 0;
virtual cl_int 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) = 0;
virtual cl_int 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) = 0;
virtual cl_int 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) = 0;
virtual cl_int enqueueFillBuffer(const cl::Buffer &buffer,
const void *pattern,
size_t patternSize,
size_t offset,
size_t size,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual void *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) = 0;
protected:
const cl::CommandQueue &mCommandQueue;
};
......
......@@ -52,6 +52,7 @@ class CLDeviceImpl : angle::NonCopyable
size_t mImageMaxArraySize = 0u;
cl_uint mImagePitchAlignment = 0u;
cl_uint mImageBaseAddressAlignment = 0u;
cl_uint mMemBaseAddrAlign = 0u;
cl_uint mQueueOnDeviceMaxSize = 0u;
std::string mBuiltInKernels;
NameVersionVector mBuiltInKernelsWithVersion;
......
......@@ -16,7 +16,8 @@ namespace rx
class CLEventImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLEventImpl>;
using Ptr = std::unique_ptr<CLEventImpl>;
using CreateFunc = std::function<Ptr(const cl::Event &)>;
CLEventImpl(const cl::Event &event);
virtual ~CLEventImpl();
......
......@@ -7,6 +7,11 @@
#include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLEventCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h"
namespace rx
{
......@@ -28,4 +33,252 @@ cl_int CLCommandQueueCL::setProperty(cl::CommandQueueProperties properties, cl_b
nullptr);
}
cl_int CLCommandQueueCL::enqueueReadBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const cl_bool block = blocking ? CL_TRUE : CL_FALSE;
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode =
mNative->getDispatch().clEnqueueReadBuffer(mNative, nativeBuffer, block, offset, size, ptr,
numEvents, nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueWriteBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const cl_bool block = blocking ? CL_TRUE : CL_FALSE;
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode =
mNative->getDispatch().clEnqueueWriteBuffer(mNative, nativeBuffer, block, offset, size, ptr,
numEvents, nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::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)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const cl_bool block = blocking ? CL_TRUE : CL_FALSE;
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode = mNative->getDispatch().clEnqueueReadBufferRect(
mNative, nativeBuffer, block, bufferOrigin, hostOrigin, region, bufferRowPitch,
bufferSlicePitch, hostRowPitch, hostSlicePitch, ptr, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::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)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const cl_bool block = blocking ? CL_TRUE : CL_FALSE;
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode = mNative->getDispatch().clEnqueueWriteBufferRect(
mNative, nativeBuffer, block, bufferOrigin, hostOrigin, region, bufferRowPitch,
bufferSlicePitch, hostRowPitch, hostSlicePitch, ptr, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::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)
{
const cl_mem nativeSrc = srcBuffer.getImpl<CLMemoryCL>().getNative();
const cl_mem nativeDst = dstBuffer.getImpl<CLMemoryCL>().getNative();
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode = mNative->getDispatch().clEnqueueCopyBuffer(
mNative, nativeSrc, nativeDst, srcOffset, dstOffset, size, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::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)
{
const cl_mem nativeSrc = srcBuffer.getImpl<CLMemoryCL>().getNative();
const cl_mem nativeDst = dstBuffer.getImpl<CLMemoryCL>().getNative();
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode = mNative->getDispatch().clEnqueueCopyBufferRect(
mNative, nativeSrc, nativeDst, srcOrigin, dstOrigin, region, srcRowPitch, srcSlicePitch,
dstRowPitch, dstSlicePitch, numEvents, nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueFillBuffer(const cl::Buffer &buffer,
const void *pattern,
size_t patternSize,
size_t offset,
size_t size,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
const cl_int errorCode = mNative->getDispatch().clEnqueueFillBuffer(
mNative, nativeBuffer, pattern, patternSize, offset, size, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
void *CLCommandQueueCL::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)
{
const cl_mem nativeBuffer = buffer.getImpl<CLMemoryCL>().getNative();
const cl_bool block = blocking ? CL_TRUE : CL_FALSE;
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(waitEvents);
const cl_uint numEvents = static_cast<cl_uint>(nativeEvents.size());
const cl_event *const nativeEventsPtr = nativeEvents.empty() ? nullptr : nativeEvents.data();
cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
void *const region = mNative->getDispatch().clEnqueueMapBuffer(
mNative, nativeBuffer, block, mapFlags.get(), offset, size, numEvents, nativeEventsPtr,
nativeEventPtr, &errorCode);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [=](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return region;
}
} // namespace rx
......@@ -22,6 +22,85 @@ class CLCommandQueueCL : public CLCommandQueueImpl
cl_int setProperty(cl::CommandQueueProperties properties, cl_bool enable) override;
cl_int enqueueReadBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueWriteBuffer(const cl::Buffer &buffer,
bool blocking,
size_t offset,
size_t size,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int 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) override;
cl_int 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) override;
cl_int 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) override;
cl_int 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) override;
cl_int enqueueFillBuffer(const cl::Buffer &buffer,
const void *pattern,
size_t patternSize,
size_t offset,
size_t size,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
void *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) override;
private:
const cl_command_queue mNative;
};
......
......@@ -280,12 +280,7 @@ CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &er
cl_int CLContextCL::waitForEvents(const cl::EventPtrs &events)
{
std::vector<cl_event> nativeEvents;
nativeEvents.reserve(events.size());
for (const cl::EventPtr &event : events)
{
nativeEvents.emplace_back(event->getImpl<CLEventCL>().getNative());
}
const std::vector<cl_event> nativeEvents = CLEventCL::Cast(events);
return mNative->getDispatch().clWaitForEvents(static_cast<cl_uint>(nativeEvents.size()),
nativeEvents.data());
}
......
......@@ -89,7 +89,8 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.mImage2D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.mImage3D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.mImage3D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.mImage3D_MaxDepth))
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.mImage3D_MaxDepth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.mMemBaseAddrAlign))
{
return Info{};
}
......
......@@ -41,6 +41,17 @@ cl_int CLEventCL::setCallback(cl::Event &event, cl_int commandExecCallbackType)
&event);
}
std::vector<cl_event> CLEventCL::Cast(const cl::EventPtrs &events)
{
std::vector<cl_event> nativeEvents;
nativeEvents.reserve(events.size());
for (const cl::EventPtr &event : events)
{
nativeEvents.emplace_back(event->getImpl<CLEventCL>().getNative());
}
return nativeEvents;
}
void CLEventCL::Callback(cl_event event, cl_int commandStatus, void *userData)
{
static_cast<cl::Event *>(userData)->callback(commandStatus);
......
......@@ -29,6 +29,8 @@ class CLEventCL : public CLEventImpl
cl_int setCallback(cl::Event &event, cl_int commandExecCallbackType) override;
static std::vector<cl_event> Cast(const cl::EventPtrs &events);
private:
static void CL_CALLBACK Callback(cl_event event, cl_int commandStatus, void *userData);
......
......@@ -19,6 +19,8 @@ class CLMemoryCL : public CLMemoryImpl
CLMemoryCL(const cl::Memory &memory, cl_mem native);
~CLMemoryCL() override;
cl_mem getNative();
size_t getSize(cl_int &errorCode) const override;
CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
......@@ -29,6 +31,11 @@ class CLMemoryCL : public CLMemoryImpl
const cl_mem mNative;
};
inline cl_mem CLMemoryCL::getNative()
{
return mNative;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLMEMORYCL_H_
......@@ -11,7 +11,7 @@
#include "libANGLE/cl_utils.h"
#define ANGLE_VALIDATE_VERSION(major, minor) \
#define ANGLE_VALIDATE_VERSION(version, major, minor) \
do \
{ \
if (version < CL_MAKE_VERSION(major##u, minor##u, 0u)) \
......@@ -106,8 +106,8 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform)
// CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY,
// and CL_MEM_HOST_NO_ACCESS are mutually exclusive.
allowedFlags.set(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS);
if (flags.areMutuallyExclusive(CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY,
CL_MEM_HOST_NO_ACCESS))
if (!flags.areMutuallyExclusive(CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY,
CL_MEM_HOST_NO_ACCESS))
{
return false;
}
......@@ -123,6 +123,25 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform)
return true;
}
bool ValidateMapFlags(MapFlags flags, const Platform &platform)
{
MemFlags allowedFlags(CL_MAP_READ | CL_MAP_WRITE);
if (platform.isVersionOrNewer(1u, 2u))
{
// CL_MAP_READ or CL_MAP_WRITE and CL_MAP_WRITE_INVALIDATE_REGION are mutually exclusive.
allowedFlags.set(CL_MAP_WRITE_INVALIDATE_REGION);
if (!flags.areMutuallyExclusive(CL_MAP_WRITE_INVALIDATE_REGION, CL_MAP_READ | CL_MAP_WRITE))
{
return false;
}
}
if (flags.hasOtherBitsThan(allowedFlags))
{
return false;
}
return true;
}
bool ValidateMemoryProperties(const cl_mem_properties *properties)
{
if (properties != nullptr)
......@@ -137,13 +156,13 @@ bool ValidateMemoryProperties(const cl_mem_properties *properties)
return true;
}
bool ValidateImageFormat(const cl_image_format *image_format, const Platform &platform)
bool ValidateImageFormat(const cl_image_format *imageFormat, const Platform &platform)
{
if (image_format == nullptr)
if (imageFormat == nullptr)
{
return false;
}
switch (image_format->image_channel_order)
switch (imageFormat->image_channel_order)
{
case CL_R:
case CL_A:
......@@ -181,7 +200,7 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
default:
return false;
}
switch (image_format->image_channel_data_type)
switch (imageFormat->image_channel_data_type)
{
case CL_SNORM_INT8:
case CL_SNORM_INT16:
......@@ -200,15 +219,15 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555:
case CL_UNORM_INT_101010:
if (image_format->image_channel_order != CL_RGB &&
image_format->image_channel_order != CL_RGBx)
if (imageFormat->image_channel_order != CL_RGB &&
imageFormat->image_channel_order != CL_RGBx)
{
return false;
}
break;
case CL_UNORM_INT_101010_2:
if (!platform.isVersionOrNewer(2u, 1u) || image_format->image_channel_order != CL_RGBA)
if (!platform.isVersionOrNewer(2u, 1u) || imageFormat->image_channel_order != CL_RGBA)
{
return false;
}
......@@ -220,6 +239,186 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
return true;
}
cl_int ValidateCommandQueueAndEventWaitList(cl_command_queue commandQueue,
cl_uint numEvents,
const cl_event *events)
{
// CL_INVALID_COMMAND_QUEUE if command_queue is not a valid host command-queue.
if (!CommandQueue::IsValid(commandQueue))
{
return CL_INVALID_COMMAND_QUEUE;
}
const CommandQueue &queue = commandQueue->cast<CommandQueue>();
if (!queue.isOnHost())
{
return CL_INVALID_COMMAND_QUEUE;
}
// CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and num_events_in_wait_list > 0,
// or event_wait_list is not NULL and num_events_in_wait_list is 0, ...
if ((events == nullptr) != (numEvents == 0u))
{
return CL_INVALID_EVENT_WAIT_LIST;
}
while (numEvents-- != 0u)
{
// or if event objects in event_wait_list are not valid events.
if (!Event::IsValid(*events))
{
return CL_INVALID_EVENT_WAIT_LIST;
}
// CL_INVALID_CONTEXT if the context associated with command_queue
// and events in event_wait_list are not the same.
if (&queue.getContext() != &(*events++)->cast<Event>().getContext())
{
return CL_INVALID_CONTEXT;
}
}
return CL_SUCCESS;
}
cl_int ValidateEnqueueBuffer(const CommandQueue &queue,
cl_mem buffer,
bool hostRead,
bool hostWrite)
{
// CL_INVALID_MEM_OBJECT if buffer is not a valid buffer object.
if (!Buffer::IsValid(buffer))
{
return CL_INVALID_MEM_OBJECT;
}
const Buffer &buf = buffer->cast<Buffer>();
// CL_INVALID_CONTEXT if the context associated with command_queue and buffer are not the same.
if (&queue.getContext() != &buf.getContext())
{
return CL_INVALID_CONTEXT;
}
// CL_MISALIGNED_SUB_BUFFER_OFFSET if buffer is a sub-buffer object and offset specified
// when the sub-buffer object is created is not aligned to CL_DEVICE_MEM_BASE_ADDR_ALIGN
// value for device associated with queue.
if (buf.isSubBuffer() &&
(buf.getOffset() % queue.getDevice().getInfo().mMemBaseAddrAlign) != 0u)
{
return CL_MISALIGNED_SUB_BUFFER_OFFSET;
}
// CL_INVALID_OPERATION if a read function is called on buffer which
// has been created with CL_MEM_HOST_WRITE_ONLY or CL_MEM_HOST_NO_ACCESS.
if (hostRead && buf.getEffectiveFlags().isSet(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS))
{
return CL_INVALID_OPERATION;
}
// CL_INVALID_OPERATION if a write function is called on buffer which
// has been created with CL_MEM_HOST_READ_ONLY or CL_MEM_HOST_NO_ACCESS.
if (hostWrite && buf.getEffectiveFlags().isSet(CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS))
{
return CL_INVALID_OPERATION;
}
return CL_SUCCESS;
}
cl_int ValidateBufferRect(const Buffer &buffer,
const size_t *origin,
const size_t *region,
size_t rowPitch,
size_t slicePitch)
{
// CL_INVALID_VALUE if origin or region is NULL.
if (origin == nullptr || region == nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if any region array element is 0.
if (region[0] == 0u || region[1] == 0u || region[2] == 0u)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if row_pitch is not 0 and is less than region[0].
if (rowPitch == 0u)
{
rowPitch = region[0];
}
else if (rowPitch < region[0])
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if slice_pitch is not 0 and is less than
// region[1] x row_pitch and not a multiple of row_pitch.
if (slicePitch == 0u)
{
slicePitch = region[1] * rowPitch;
}
else if (slicePitch < region[1] * rowPitch || (slicePitch % rowPitch) != 0u)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if the region being read or written specified
// by (origin, region, row_pitch, slice_pitch) is out of bounds.
if (!buffer.isRegionValid(
origin[2] * slicePitch + origin[1] * rowPitch + origin[0],
(region[2] - 1u) * slicePitch + (region[1] - 1u) * rowPitch + region[0]))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
cl_int ValidateHostRect(const size_t *hostOrigin,
const size_t *region,
size_t hostRowPitch,
size_t hostSlicePitch,
const void *ptr)
{
// CL_INVALID_VALUE if host_origin or region is NULL.
if (hostOrigin == nullptr || region == nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if any region array element is 0.
if (region[0] == 0u || region[1] == 0u || region[2] == 0u)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if host_row_pitch is not 0 and is less than region[0].
if (hostRowPitch == 0u)
{
hostRowPitch = region[0];
}
else if (hostRowPitch < region[0])
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if host_slice_pitch is not 0 and is less than
// region[1] x host_row_pitch and not a multiple of host_row_pitch.
if (hostSlicePitch != 0u &&
(hostSlicePitch < region[1] * hostRowPitch || (hostSlicePitch % hostRowPitch) != 0u))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if ptr is NULL.
if (ptr == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
} // namespace
// CL 1.0
......@@ -255,15 +454,16 @@ cl_int ValidateGetPlatformInfo(cl_platform_id platform,
switch (param_name)
{
case PlatformInfo::HostTimerResolution:
ANGLE_VALIDATE_VERSION(2, 1);
ANGLE_VALIDATE_VERSION(version, 2, 1);
break;
case PlatformInfo::NumericVersion:
case PlatformInfo::ExtensionsWithVersion:
ANGLE_VALIDATE_VERSION(3, 0);
ANGLE_VALIDATE_VERSION(version, 3, 0);
break;
case PlatformInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -327,7 +527,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::NativeVectorWidthHalf:
case DeviceInfo::HostUnifiedMemory:
case DeviceInfo::OpenCL_C_Version:
ANGLE_VALIDATE_VERSION(1, 1);
ANGLE_VALIDATE_VERSION(version, 1, 1);
break;
case DeviceInfo::ImageMaxBufferSize:
......@@ -343,7 +543,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PartitionAffinityDomain:
case DeviceInfo::PartitionType:
case DeviceInfo::ReferenceCount:
ANGLE_VALIDATE_VERSION(1, 2);
ANGLE_VALIDATE_VERSION(version, 1, 2);
break;
case DeviceInfo::MaxReadWriteImageArgs:
......@@ -363,13 +563,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PreferredPlatformAtomicAlignment:
case DeviceInfo::PreferredGlobalAtomicAlignment:
case DeviceInfo::PreferredLocalAtomicAlignment:
ANGLE_VALIDATE_VERSION(2, 0);
ANGLE_VALIDATE_VERSION(version, 2, 0);
break;
case DeviceInfo::IL_Version:
case DeviceInfo::MaxNumSubGroups:
case DeviceInfo::SubGroupIndependentForwardProgress:
ANGLE_VALIDATE_VERSION(2, 1);
ANGLE_VALIDATE_VERSION(version, 2, 1);
break;
case DeviceInfo::ILsWithVersion:
......@@ -387,12 +587,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PipeSupport:
case DeviceInfo::PreferredWorkGroupSizeMultiple:
case DeviceInfo::LatestConformanceVersionPassed:
ANGLE_VALIDATE_VERSION(3, 0);
ANGLE_VALIDATE_VERSION(version, 3, 0);
break;
case DeviceInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -523,7 +724,7 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
// or if command_queue is not a valid command-queue for param_name.
if (param_name == CommandQueueInfo::Size && queue.getProperties().isNotSet(CL_QUEUE_ON_DEVICE))
if (param_name == CommandQueueInfo::Size && queue.isOnDevice())
{
return CL_INVALID_COMMAND_QUEUE;
}
......@@ -533,17 +734,18 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
switch (param_name)
{
case CommandQueueInfo::Size:
ANGLE_VALIDATE_VERSION(2, 0);
ANGLE_VALIDATE_VERSION(version, 2, 0);
break;
case CommandQueueInfo::DeviceDefault:
ANGLE_VALIDATE_VERSION(2, 1);
ANGLE_VALIDATE_VERSION(version, 2, 1);
break;
case CommandQueueInfo::PropertiesArray:
ANGLE_VALIDATE_VERSION(3, 0);
ANGLE_VALIDATE_VERSION(version, 3, 0);
break;
case CommandQueueInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -631,17 +833,18 @@ cl_int ValidateGetMemObjectInfo(cl_mem memobj,
{
case MemInfo::AssociatedMemObject:
case MemInfo::Offset:
ANGLE_VALIDATE_VERSION(1, 1);
ANGLE_VALIDATE_VERSION(version, 1, 1);
break;
case MemInfo::UsesSVM_Pointer:
ANGLE_VALIDATE_VERSION(2, 0);
ANGLE_VALIDATE_VERSION(version, 2, 0);
break;
case MemInfo::Properties:
ANGLE_VALIDATE_VERSION(3, 0);
ANGLE_VALIDATE_VERSION(version, 3, 0);
break;
case MemInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -668,11 +871,12 @@ cl_int ValidateGetImageInfo(cl_mem image,
case ImageInfo::Buffer:
case ImageInfo::NumMipLevels:
case ImageInfo::NumSamples:
ANGLE_VALIDATE_VERSION(1, 2);
ANGLE_VALIDATE_VERSION(version, 1, 2);
break;
case ImageInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -708,11 +912,12 @@ cl_int ValidateGetSamplerInfo(cl_sampler sampler,
switch (param_name)
{
case SamplerInfo::Properties:
ANGLE_VALIDATE_VERSION(3, 0);
ANGLE_VALIDATE_VERSION(version, 3, 0);
break;
case SamplerInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -825,18 +1030,19 @@ cl_int ValidateGetProgramInfo(cl_program program,
{
case ProgramInfo::NumKernels:
case ProgramInfo::KernelNames:
ANGLE_VALIDATE_VERSION(1, 2);
ANGLE_VALIDATE_VERSION(version, 1, 2);
break;
case ProgramInfo::IL:
ANGLE_VALIDATE_VERSION(2, 1);
ANGLE_VALIDATE_VERSION(version, 2, 1);
break;
case ProgramInfo::ScopeGlobalCtorsPresent:
case ProgramInfo::ScopeGlobalDtorsPresent:
ANGLE_VALIDATE_VERSION(2, 2);
ANGLE_VALIDATE_VERSION(version, 2, 2);
break;
case ProgramInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -922,11 +1128,12 @@ cl_int ValidateGetKernelInfo(cl_kernel kernel,
switch (param_name)
{
case KernelInfo::Attributes:
ANGLE_VALIDATE_VERSION(1, 2);
ANGLE_VALIDATE_VERSION(version, 1, 2);
break;
case KernelInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -978,7 +1185,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel,
switch (param_name)
{
case KernelWorkGroupInfo::GlobalWorkSize:
ANGLE_VALIDATE_VERSION(1, 2);
ANGLE_VALIDATE_VERSION(version, 1, 2);
// CL_INVALID_VALUE if param_name is CL_KERNEL_GLOBAL_WORK_SIZE and
// device is not a custom device and kernel is not a built-in kernel.
if (!dev->supportsBuiltInKernel(krnl.getInfo().mFunctionName))
......@@ -989,6 +1196,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel,
case KernelWorkGroupInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -1044,11 +1252,12 @@ cl_int ValidateGetEventInfo(cl_event event,
switch (param_name)
{
case EventInfo::Context:
ANGLE_VALIDATE_VERSION(1, 1);
ANGLE_VALIDATE_VERSION(version, 1, 1);
break;
case EventInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
......@@ -1096,6 +1305,26 @@ cl_int ValidateEnqueueReadBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateEnqueueBuffer(command_queue->cast<CommandQueue>(), buffer, true, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if the region being read or written specified
// by (offset, size) is out of bounds or if ptr is a NULL value.
if (!buffer->cast<Buffer>().isRegionValid(offset, size) || ptr == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -1109,6 +1338,26 @@ cl_int ValidateEnqueueWriteBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateEnqueueBuffer(command_queue->cast<CommandQueue>(), buffer, false, true);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if the region being read or written specified
// by (offset, size) is out of bounds or if ptr is a NULL value.
if (!buffer->cast<Buffer>().isRegionValid(offset, size) || ptr == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -1122,6 +1371,54 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
errorCode = ValidateEnqueueBuffer(queue, src_buffer, false, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &src = src_buffer->cast<Buffer>();
errorCode = ValidateEnqueueBuffer(queue, dst_buffer, false, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &dst = dst_buffer->cast<Buffer>();
// CL_INVALID_VALUE if src_offset, dst_offset, size, src_offset + size or dst_offset + size
// require accessing elements outside the src_buffer and dst_buffer buffer objects respectively.
if (!src.isRegionValid(src_offset, size) || !dst.isRegionValid(dst_offset, size))
{
return CL_INVALID_VALUE;
}
// CL_MEM_COPY_OVERLAP if src_buffer and dst_buffer are the same buffer or sub-buffer object
// and the source and destination regions overlap or if src_buffer and dst_buffer are
// different sub-buffers of the same associated buffer object and they overlap.
if ((src.isSubBuffer() ? src.getParent().get() : &src) ==
(dst.isSubBuffer() ? dst.getParent().get() : &dst))
{
// Only sub-buffers have offsets larger than zero
src_offset += src.getOffset();
dst_offset += dst.getOffset();
// The regions overlap if src_offset <= dst_offset <= src_offset + size - 1
// or if dst_offset <= src_offset <= dst_offset + size - 1.
if ((src_offset <= dst_offset && dst_offset <= src_offset + size - 1u) ||
(dst_offset <= src_offset && src_offset <= dst_offset + size - 1u))
{
return CL_MEM_COPY_OVERLAP;
}
}
return CL_SUCCESS;
}
......@@ -1204,6 +1501,34 @@ cl_int ValidateEnqueueMapBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
// CL_INVALID_OPERATION if buffer has been created with CL_MEM_HOST_WRITE_ONLY or
// CL_MEM_HOST_NO_ACCESS and CL_MAP_READ is set in map_flags
// or if buffer has been created with CL_MEM_HOST_READ_ONLY or CL_MEM_HOST_NO_ACCESS
// and CL_MAP_WRITE or CL_MAP_WRITE_INVALIDATE_REGION is set in map_flags.
errorCode =
ValidateEnqueueBuffer(queue, buffer, map_flags.isSet(CL_MAP_READ),
map_flags.isSet(CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if region being mapped given by (offset, size) is out of bounds
// or if size is 0 or if values specified in map_flags are not valid.
if (!buffer->cast<Buffer>().isRegionValid(offset, size) || size == 0u ||
!ValidateMapFlags(map_flags, queue.getContext().getPlatform()))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -1559,6 +1884,37 @@ cl_int ValidateEnqueueReadBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{
return CL_INVALID_COMMAND_QUEUE;
}
errorCode = ValidateEnqueueBuffer(queue, buffer, true, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateBufferRect(buffer->cast<Buffer>(), buffer_origin, region, buffer_row_pitch,
buffer_slice_pitch);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateHostRect(host_origin, region, host_row_pitch, host_slice_pitch, ptr);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
return CL_SUCCESS;
}
......@@ -1577,6 +1933,37 @@ cl_int ValidateEnqueueWriteBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{
return CL_INVALID_COMMAND_QUEUE;
}
errorCode = ValidateEnqueueBuffer(queue, buffer, false, true);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateBufferRect(buffer->cast<Buffer>(), buffer_origin, region, buffer_row_pitch,
buffer_slice_pitch);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateHostRect(host_origin, region, host_row_pitch, host_slice_pitch, ptr);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
return CL_SUCCESS;
}
......@@ -1594,6 +1981,51 @@ cl_int ValidateEnqueueCopyBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{
return CL_INVALID_COMMAND_QUEUE;
}
errorCode = ValidateEnqueueBuffer(queue, src_buffer, false, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &src = src_buffer->cast<Buffer>();
errorCode = ValidateEnqueueBuffer(queue, dst_buffer, false, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &dst = dst_buffer->cast<Buffer>();
errorCode = ValidateBufferRect(src, src_origin, region, src_row_pitch, src_slice_pitch);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
errorCode = ValidateBufferRect(dst, dst_origin, region, dst_row_pitch, dst_slice_pitch);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if src_buffer and dst_buffer are the same buffer object and src_slice_pitch
// is not equal to dst_slice_pitch or src_row_pitch is not equal to dst_row_pitch.
if (&src == &dst && (src_slice_pitch != dst_slice_pitch || src_row_pitch != dst_row_pitch))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -1737,31 +2169,50 @@ cl_int ValidateCreateImage(cl_context context,
default:
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// image_row_pitch must be 0 if host_ptr is NULL and can be either 0
// or >= image_width * size of element in bytes if host_ptr is not NULL.
// If image_row_pitch is not 0, it must be a multiple of the image element size in bytes.
if (image_desc->image_row_pitch != 0u &&
(host_ptr == nullptr || image_desc->image_row_pitch < image_desc->image_width * elemSize ||
(image_desc->image_row_pitch % elemSize) != 0u))
if (image_desc->image_row_pitch != 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
// image_row_pitch must be 0 if host_ptr is NULL.
if (host_ptr == nullptr)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// image_row_pitch can be either 0
// or >= image_width * size of element in bytes if host_ptr is not NULL.
if (image_desc->image_row_pitch < image_desc->image_width * elemSize)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// If image_row_pitch is not 0, it must be a multiple of the image element size in bytes.
if ((image_desc->image_row_pitch % elemSize) != 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
}
// image_slice_pitch must be 0 if host_ptr is NULL. If host_ptr is not NULL, image_slice_pitch
// can be either 0 or >= image_row_pitch * image_height for a 2D image array or 3D image
// and can be either 0 or >= image_row_pitch for a 1D image array.
// If image_slice_pitch is not 0, it must be a multiple of the image_row_pitch.
if (image_desc->image_slice_pitch != 0u &&
(host_ptr == nullptr || image_desc->image_slice_pitch < sliceSize ||
(image_desc->image_slice_pitch % rowPitch) != 0u))
if (image_desc->image_slice_pitch != 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
// image_slice_pitch must be 0 if host_ptr is NULL.
if (host_ptr == nullptr)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// If host_ptr is not NULL, image_slice_pitch can be either 0
// or >= image_row_pitch * image_height for a 2D image array or 3D image
// and can be either 0 or >= image_row_pitch for a 1D image array.
if (image_desc->image_slice_pitch < sliceSize)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// If image_slice_pitch is not 0, it must be a multiple of the image_row_pitch.
if ((image_desc->image_slice_pitch % rowPitch) != 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
}
// num_mip_levels and num_samples must be 0.
if (image_desc->num_mip_levels != 0u || image_desc->num_samples != 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// buffer can be a buffer memory object if image_type is CL_MEM_OBJECT_IMAGE1D_BUFFER or
// CL_MEM_OBJECT_IMAGE2D. buffer can be an image object if image_type is CL_MEM_OBJECT_IMAGE2D.
// Otherwise it must be NULL.
......@@ -1953,6 +2404,45 @@ cl_int ValidateEnqueueFillBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
const cl_event *event)
{
cl_int errorCode = ValidateCommandQueueAndEventWaitList(command_queue, num_events_in_wait_list,
event_wait_list);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 2u))
{
return CL_INVALID_COMMAND_QUEUE;
}
errorCode = ValidateEnqueueBuffer(queue, buffer, false, false);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if offset or offset + size require accessing
// elements outside the buffer object respectively.
if (!buffer->cast<Buffer>().isRegionValid(offset, size))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if pattern is NULL or if pattern_size is 0 or
// if pattern_size is not one of { 1, 2, 4, 8, 16, 32, 64, 128 }.
if (pattern == nullptr || pattern_size == 0u || pattern_size > 128u ||
(pattern_size & (pattern_size - 1u)) != 0u)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if offset and size are not a multiple of pattern_size.
if ((offset % pattern_size) != 0u || (size % pattern_size) != 0u)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......
......@@ -714,8 +714,8 @@ cl_int EnqueueReadBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueReadBuffer);
return 0;
return command_queue->cast<CommandQueue>().enqueueReadBuffer(
buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
}
cl_int EnqueueReadBufferRect(cl_command_queue command_queue,
......@@ -733,8 +733,10 @@ cl_int EnqueueReadBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueReadBufferRect);
return 0;
return command_queue->cast<CommandQueue>().enqueueReadBufferRect(
buffer, blocking_read, buffer_origin, host_origin, region, buffer_row_pitch,
buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
event_wait_list, event);
}
cl_int EnqueueWriteBuffer(cl_command_queue command_queue,
......@@ -747,8 +749,8 @@ cl_int EnqueueWriteBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueWriteBuffer);
return 0;
return command_queue->cast<CommandQueue>().enqueueWriteBuffer(
buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
}
cl_int EnqueueWriteBufferRect(cl_command_queue command_queue,
......@@ -766,8 +768,10 @@ cl_int EnqueueWriteBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueWriteBufferRect);
return 0;
return command_queue->cast<CommandQueue>().enqueueWriteBufferRect(
buffer, blocking_write, buffer_origin, host_origin, region, buffer_row_pitch,
buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
event_wait_list, event);
}
cl_int EnqueueFillBuffer(cl_command_queue command_queue,
......@@ -780,8 +784,9 @@ cl_int EnqueueFillBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueFillBuffer);
return 0;
return command_queue->cast<CommandQueue>().enqueueFillBuffer(
buffer, pattern, pattern_size, offset, size, num_events_in_wait_list, event_wait_list,
event);
}
cl_int EnqueueCopyBuffer(cl_command_queue command_queue,
......@@ -794,8 +799,9 @@ cl_int EnqueueCopyBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueCopyBuffer);
return 0;
return command_queue->cast<CommandQueue>().enqueueCopyBuffer(
src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list,
event_wait_list, event);
}
cl_int EnqueueCopyBufferRect(cl_command_queue command_queue,
......@@ -812,8 +818,9 @@ cl_int EnqueueCopyBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list,
cl_event *event)
{
WARN_NOT_SUPPORTED(EnqueueCopyBufferRect);
return 0;
return command_queue->cast<CommandQueue>().enqueueCopyBufferRect(
src_buffer, dst_buffer, src_origin, dst_origin, region, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, num_events_in_wait_list, event_wait_list, event);
}
cl_int EnqueueReadImage(cl_command_queue command_queue,
......@@ -914,8 +921,9 @@ void *EnqueueMapBuffer(cl_command_queue command_queue,
cl_event *event,
cl_int &errorCode)
{
WARN_NOT_SUPPORTED(EnqueueMapBuffer);
return 0;
return command_queue->cast<CommandQueue>().enqueueMapBuffer(
buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list,
event, errorCode);
}
void *EnqueueMapImage(cl_command_queue command_queue,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment