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 ...@@ -50,6 +50,9 @@ class BitField
return (isSet(bits1) ? 1 : 0) + (isSet(bits2) ? 1 : 0) + (isSet(bits3) ? 1 : 0) <= 1; 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(cl_bitfield bits) { mBits |= bits; }
void set(const BitField &other) { mBits |= other.mBits; } void set(const BitField &other) { mBits |= other.mBits; }
void clear(cl_bitfield bits) { mBits &= ~bits; } void clear(cl_bitfield bits) { mBits &= ~bits; }
......
...@@ -23,6 +23,7 @@ class Buffer final : public Memory ...@@ -23,6 +23,7 @@ class Buffer final : public Memory
const void *createInfo, const void *createInfo,
cl_int &errorCode); cl_int &errorCode);
bool isRegionValid(size_t offset, size_t size) const;
bool isRegionValid(const cl_buffer_region &region) const; bool isRegionValid(const cl_buffer_region &region) const;
static bool IsValid(const _cl_mem *buffer); static bool IsValid(const _cl_mem *buffer);
...@@ -47,6 +48,11 @@ class Buffer final : public Memory ...@@ -47,6 +48,11 @@ class Buffer final : public Memory
friend class Object; 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 inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
{ {
return region.origin < mSize && region.origin + region.size <= mSize; return region.origin < mSize && region.origin + region.size <= mSize;
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLEvent.h"
#include <cstring> #include <cstring>
...@@ -106,6 +108,237 @@ cl_int CommandQueue::setProperty(CommandQueueProperties properties, ...@@ -106,6 +108,237 @@ cl_int CommandQueue::setProperty(CommandQueueProperties properties,
return result; 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() CommandQueue::~CommandQueue()
{ {
if (mDevice->mDefaultCommandQueue == this) if (mDevice->mDefaultCommandQueue == this)
......
...@@ -31,6 +31,93 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -31,6 +31,93 @@ class CommandQueue final : public _cl_command_queue, public Object
cl_bool enable, cl_bool enable,
cl_command_queue_properties *oldProperties); 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: public:
using PropArray = std::vector<cl_queue_properties>; using PropArray = std::vector<cl_queue_properties>;
...@@ -38,10 +125,14 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -38,10 +125,14 @@ class CommandQueue final : public _cl_command_queue, public Object
~CommandQueue() override; ~CommandQueue() override;
Context &getContext();
const Context &getContext() const; const Context &getContext() const;
const Device &getDevice() const; const Device &getDevice() const;
CommandQueueProperties getProperties() const; CommandQueueProperties getProperties() const;
bool isOnHost() const;
bool isOnDevice() const;
bool hasSize() const; bool hasSize() const;
cl_uint getSize() const; cl_uint getSize() const;
...@@ -71,6 +162,11 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -71,6 +162,11 @@ class CommandQueue final : public _cl_command_queue, public Object
friend class Object; friend class Object;
}; };
inline Context &CommandQueue::getContext()
{
return *mContext;
}
inline const Context &CommandQueue::getContext() const inline const Context &CommandQueue::getContext() const
{ {
return *mContext; return *mContext;
...@@ -86,6 +182,16 @@ inline CommandQueueProperties CommandQueue::getProperties() const ...@@ -86,6 +182,16 @@ inline CommandQueueProperties CommandQueue::getProperties() const
return mProperties; 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 inline bool CommandQueue::hasSize() const
{ {
return mSize != kNoSize; return mSize != kNoSize;
......
...@@ -292,13 +292,7 @@ cl_event Context::createUserEvent(cl_int &errorCode) ...@@ -292,13 +292,7 @@ cl_event Context::createUserEvent(cl_int &errorCode)
cl_int Context::waitForEvents(cl_uint numEvents, const cl_event *eventList) cl_int Context::waitForEvents(cl_uint numEvents, const cl_event *eventList)
{ {
EventPtrs events; return mImpl->waitForEvents(Event::Cast(numEvents, eventList));
events.reserve(numEvents);
while (numEvents-- != 0u)
{
events.emplace_back(&(*eventList++)->cast<Event>());
}
return mImpl->waitForEvents(events);
} }
Context::~Context() = default; Context::~Context() = default;
......
...@@ -71,7 +71,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -71,7 +71,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
case DeviceInfo::MaxPipeArgs: case DeviceInfo::MaxPipeArgs:
case DeviceInfo::PipeMaxActiveReservations: case DeviceInfo::PipeMaxActiveReservations:
case DeviceInfo::PipeMaxPacketSize: case DeviceInfo::PipeMaxPacketSize:
case DeviceInfo::MemBaseAddrAlign:
case DeviceInfo::MinDataTypeAlignSize: case DeviceInfo::MinDataTypeAlignSize:
case DeviceInfo::GlobalMemCacheType: case DeviceInfo::GlobalMemCacheType:
case DeviceInfo::GlobalMemCachelineSize: case DeviceInfo::GlobalMemCachelineSize:
...@@ -221,6 +220,10 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -221,6 +220,10 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copyValue = &mInfo.mImageBaseAddressAlignment; copyValue = &mInfo.mImageBaseAddressAlignment;
copySize = sizeof(mInfo.mImageBaseAddressAlignment); copySize = sizeof(mInfo.mImageBaseAddressAlignment);
break; break;
case DeviceInfo::MemBaseAddrAlign:
copyValue = &mInfo.mMemBaseAddrAlign;
copySize = sizeof(mInfo.mMemBaseAddrAlign);
break;
case DeviceInfo::QueueOnDeviceMaxSize: case DeviceInfo::QueueOnDeviceMaxSize:
copyValue = &mInfo.mQueueOnDeviceMaxSize; copyValue = &mInfo.mQueueOnDeviceMaxSize;
copySize = sizeof(mInfo.mQueueOnDeviceMaxSize); copySize = sizeof(mInfo.mQueueOnDeviceMaxSize);
......
...@@ -122,10 +122,31 @@ void Event::callback(cl_int commandStatus) ...@@ -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) Event::Event(Context &context, cl_int &errorCode)
: mContext(&context), : 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 } // namespace cl
...@@ -42,15 +42,22 @@ class Event final : public _cl_event, public Object ...@@ -42,15 +42,22 @@ class Event final : public _cl_event, public Object
void callback(cl_int commandStatus); void callback(cl_int commandStatus);
static EventPtrs Cast(cl_uint numEvents, const cl_event *eventList);
private: private:
using CallbackData = std::pair<EventCB, void *>; using CallbackData = std::pair<EventCB, void *>;
Event(Context &context, cl_int &errorCode); 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 ContextPtr mContext;
const CommandQueuePtr mCommandQueue; const CommandQueuePtr mCommandQueue;
const rx::CLEventImpl::Ptr mImpl;
const cl_command_type mCommandType; const cl_command_type mCommandType;
const rx::CLEventImpl::Ptr mImpl;
bool mStatusWasChanged = false; bool mStatusWasChanged = false;
......
...@@ -103,6 +103,30 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu ...@@ -103,6 +103,30 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu
Memory::~Memory() = default; 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, Memory::Memory(const Buffer &buffer,
Context &context, Context &context,
PropArray &&properties, PropArray &&properties,
......
...@@ -39,6 +39,8 @@ class Memory : public _cl_mem, public Object ...@@ -39,6 +39,8 @@ class Memory : public _cl_mem, public Object
template <typename T = rx::CLMemoryImpl> template <typename T = rx::CLMemoryImpl>
T &getImpl() const; T &getImpl() const;
MemFlags getEffectiveFlags() const;
protected: protected:
Memory(const Buffer &buffer, Memory(const Buffer &buffer,
Context &context, Context &context,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#ifndef LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_ #ifndef LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#define LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_ #define LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#include "libANGLE/renderer/CLtypes.h" #include "libANGLE/renderer/CLEventImpl.h"
namespace rx namespace rx
{ {
...@@ -23,6 +23,85 @@ class CLCommandQueueImpl : angle::NonCopyable ...@@ -23,6 +23,85 @@ class CLCommandQueueImpl : angle::NonCopyable
virtual cl_int setProperty(cl::CommandQueueProperties properties, cl_bool enable) = 0; 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: protected:
const cl::CommandQueue &mCommandQueue; const cl::CommandQueue &mCommandQueue;
}; };
......
...@@ -52,6 +52,7 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -52,6 +52,7 @@ class CLDeviceImpl : angle::NonCopyable
size_t mImageMaxArraySize = 0u; size_t mImageMaxArraySize = 0u;
cl_uint mImagePitchAlignment = 0u; cl_uint mImagePitchAlignment = 0u;
cl_uint mImageBaseAddressAlignment = 0u; cl_uint mImageBaseAddressAlignment = 0u;
cl_uint mMemBaseAddrAlign = 0u;
cl_uint mQueueOnDeviceMaxSize = 0u; cl_uint mQueueOnDeviceMaxSize = 0u;
std::string mBuiltInKernels; std::string mBuiltInKernels;
NameVersionVector mBuiltInKernelsWithVersion; NameVersionVector mBuiltInKernelsWithVersion;
......
...@@ -16,7 +16,8 @@ namespace rx ...@@ -16,7 +16,8 @@ namespace rx
class CLEventImpl : angle::NonCopyable class CLEventImpl : angle::NonCopyable
{ {
public: 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); CLEventImpl(const cl::Event &event);
virtual ~CLEventImpl(); virtual ~CLEventImpl();
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
#include "libANGLE/renderer/cl/CLCommandQueueCL.h" #include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLEventCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h"
namespace rx namespace rx
{ {
...@@ -28,4 +33,252 @@ cl_int CLCommandQueueCL::setProperty(cl::CommandQueueProperties properties, cl_b ...@@ -28,4 +33,252 @@ cl_int CLCommandQueueCL::setProperty(cl::CommandQueueProperties properties, cl_b
nullptr); 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 } // namespace rx
...@@ -22,6 +22,85 @@ class CLCommandQueueCL : public CLCommandQueueImpl ...@@ -22,6 +22,85 @@ class CLCommandQueueCL : public CLCommandQueueImpl
cl_int setProperty(cl::CommandQueueProperties properties, cl_bool enable) override; 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: private:
const cl_command_queue mNative; const cl_command_queue mNative;
}; };
......
...@@ -280,12 +280,7 @@ CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &er ...@@ -280,12 +280,7 @@ CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &er
cl_int CLContextCL::waitForEvents(const cl::EventPtrs &events) cl_int CLContextCL::waitForEvents(const cl::EventPtrs &events)
{ {
std::vector<cl_event> nativeEvents; const std::vector<cl_event> nativeEvents = CLEventCL::Cast(events);
nativeEvents.reserve(events.size());
for (const cl::EventPtr &event : events)
{
nativeEvents.emplace_back(event->getImpl<CLEventCL>().getNative());
}
return mNative->getDispatch().clWaitForEvents(static_cast<cl_uint>(nativeEvents.size()), return mNative->getDispatch().clWaitForEvents(static_cast<cl_uint>(nativeEvents.size()),
nativeEvents.data()); nativeEvents.data());
} }
......
...@@ -89,7 +89,8 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const ...@@ -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::Image2D_MaxHeight, info.mImage2D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.mImage3D_MaxWidth) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.mImage3D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.mImage3D_MaxHeight) || !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{}; return Info{};
} }
......
...@@ -41,6 +41,17 @@ cl_int CLEventCL::setCallback(cl::Event &event, cl_int commandExecCallbackType) ...@@ -41,6 +41,17 @@ cl_int CLEventCL::setCallback(cl::Event &event, cl_int commandExecCallbackType)
&event); &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) void CLEventCL::Callback(cl_event event, cl_int commandStatus, void *userData)
{ {
static_cast<cl::Event *>(userData)->callback(commandStatus); static_cast<cl::Event *>(userData)->callback(commandStatus);
......
...@@ -29,6 +29,8 @@ class CLEventCL : public CLEventImpl ...@@ -29,6 +29,8 @@ class CLEventCL : public CLEventImpl
cl_int setCallback(cl::Event &event, cl_int commandExecCallbackType) override; cl_int setCallback(cl::Event &event, cl_int commandExecCallbackType) override;
static std::vector<cl_event> Cast(const cl::EventPtrs &events);
private: private:
static void CL_CALLBACK Callback(cl_event event, cl_int commandStatus, void *userData); static void CL_CALLBACK Callback(cl_event event, cl_int commandStatus, void *userData);
......
...@@ -19,6 +19,8 @@ class CLMemoryCL : public CLMemoryImpl ...@@ -19,6 +19,8 @@ class CLMemoryCL : public CLMemoryImpl
CLMemoryCL(const cl::Memory &memory, cl_mem native); CLMemoryCL(const cl::Memory &memory, cl_mem native);
~CLMemoryCL() override; ~CLMemoryCL() override;
cl_mem getNative();
size_t getSize(cl_int &errorCode) const override; size_t getSize(cl_int &errorCode) const override;
CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer, CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
...@@ -29,6 +31,11 @@ class CLMemoryCL : public CLMemoryImpl ...@@ -29,6 +31,11 @@ class CLMemoryCL : public CLMemoryImpl
const cl_mem mNative; const cl_mem mNative;
}; };
inline cl_mem CLMemoryCL::getNative()
{
return mNative;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLMEMORYCL_H_ #endif // LIBANGLE_RENDERER_CL_CLMEMORYCL_H_
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "libANGLE/cl_utils.h" #include "libANGLE/cl_utils.h"
#define ANGLE_VALIDATE_VERSION(major, minor) \ #define ANGLE_VALIDATE_VERSION(version, major, minor) \
do \ do \
{ \ { \
if (version < CL_MAKE_VERSION(major##u, minor##u, 0u)) \ if (version < CL_MAKE_VERSION(major##u, minor##u, 0u)) \
...@@ -106,8 +106,8 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform) ...@@ -106,8 +106,8 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform)
// CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY, // CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY,
// and CL_MEM_HOST_NO_ACCESS are mutually exclusive. // 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); 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, if (!flags.areMutuallyExclusive(CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY,
CL_MEM_HOST_NO_ACCESS)) CL_MEM_HOST_NO_ACCESS))
{ {
return false; return false;
} }
...@@ -123,6 +123,25 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform) ...@@ -123,6 +123,25 @@ bool ValidateMemoryFlags(MemFlags flags, const Platform &platform)
return true; 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) bool ValidateMemoryProperties(const cl_mem_properties *properties)
{ {
if (properties != nullptr) if (properties != nullptr)
...@@ -137,13 +156,13 @@ bool ValidateMemoryProperties(const cl_mem_properties *properties) ...@@ -137,13 +156,13 @@ bool ValidateMemoryProperties(const cl_mem_properties *properties)
return true; 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; return false;
} }
switch (image_format->image_channel_order) switch (imageFormat->image_channel_order)
{ {
case CL_R: case CL_R:
case CL_A: case CL_A:
...@@ -181,7 +200,7 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl ...@@ -181,7 +200,7 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
default: default:
return false; return false;
} }
switch (image_format->image_channel_data_type) switch (imageFormat->image_channel_data_type)
{ {
case CL_SNORM_INT8: case CL_SNORM_INT8:
case CL_SNORM_INT16: case CL_SNORM_INT16:
...@@ -200,15 +219,15 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl ...@@ -200,15 +219,15 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
case CL_UNORM_SHORT_565: case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555: case CL_UNORM_SHORT_555:
case CL_UNORM_INT_101010: case CL_UNORM_INT_101010:
if (image_format->image_channel_order != CL_RGB && if (imageFormat->image_channel_order != CL_RGB &&
image_format->image_channel_order != CL_RGBx) imageFormat->image_channel_order != CL_RGBx)
{ {
return false; return false;
} }
break; break;
case CL_UNORM_INT_101010_2: 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; return false;
} }
...@@ -220,6 +239,186 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl ...@@ -220,6 +239,186 @@ bool ValidateImageFormat(const cl_image_format *image_format, const Platform &pl
return true; 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 } // namespace
// CL 1.0 // CL 1.0
...@@ -255,15 +454,16 @@ cl_int ValidateGetPlatformInfo(cl_platform_id platform, ...@@ -255,15 +454,16 @@ cl_int ValidateGetPlatformInfo(cl_platform_id platform,
switch (param_name) switch (param_name)
{ {
case PlatformInfo::HostTimerResolution: case PlatformInfo::HostTimerResolution:
ANGLE_VALIDATE_VERSION(2, 1); ANGLE_VALIDATE_VERSION(version, 2, 1);
break; break;
case PlatformInfo::NumericVersion: case PlatformInfo::NumericVersion:
case PlatformInfo::ExtensionsWithVersion: case PlatformInfo::ExtensionsWithVersion:
ANGLE_VALIDATE_VERSION(3, 0); ANGLE_VALIDATE_VERSION(version, 3, 0);
break; break;
case PlatformInfo::InvalidEnum: case PlatformInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -327,7 +527,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device, ...@@ -327,7 +527,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::NativeVectorWidthHalf: case DeviceInfo::NativeVectorWidthHalf:
case DeviceInfo::HostUnifiedMemory: case DeviceInfo::HostUnifiedMemory:
case DeviceInfo::OpenCL_C_Version: case DeviceInfo::OpenCL_C_Version:
ANGLE_VALIDATE_VERSION(1, 1); ANGLE_VALIDATE_VERSION(version, 1, 1);
break; break;
case DeviceInfo::ImageMaxBufferSize: case DeviceInfo::ImageMaxBufferSize:
...@@ -343,7 +543,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device, ...@@ -343,7 +543,7 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PartitionAffinityDomain: case DeviceInfo::PartitionAffinityDomain:
case DeviceInfo::PartitionType: case DeviceInfo::PartitionType:
case DeviceInfo::ReferenceCount: case DeviceInfo::ReferenceCount:
ANGLE_VALIDATE_VERSION(1, 2); ANGLE_VALIDATE_VERSION(version, 1, 2);
break; break;
case DeviceInfo::MaxReadWriteImageArgs: case DeviceInfo::MaxReadWriteImageArgs:
...@@ -363,13 +563,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device, ...@@ -363,13 +563,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PreferredPlatformAtomicAlignment: case DeviceInfo::PreferredPlatformAtomicAlignment:
case DeviceInfo::PreferredGlobalAtomicAlignment: case DeviceInfo::PreferredGlobalAtomicAlignment:
case DeviceInfo::PreferredLocalAtomicAlignment: case DeviceInfo::PreferredLocalAtomicAlignment:
ANGLE_VALIDATE_VERSION(2, 0); ANGLE_VALIDATE_VERSION(version, 2, 0);
break; break;
case DeviceInfo::IL_Version: case DeviceInfo::IL_Version:
case DeviceInfo::MaxNumSubGroups: case DeviceInfo::MaxNumSubGroups:
case DeviceInfo::SubGroupIndependentForwardProgress: case DeviceInfo::SubGroupIndependentForwardProgress:
ANGLE_VALIDATE_VERSION(2, 1); ANGLE_VALIDATE_VERSION(version, 2, 1);
break; break;
case DeviceInfo::ILsWithVersion: case DeviceInfo::ILsWithVersion:
...@@ -387,12 +587,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device, ...@@ -387,12 +587,13 @@ cl_int ValidateGetDeviceInfo(cl_device_id device,
case DeviceInfo::PipeSupport: case DeviceInfo::PipeSupport:
case DeviceInfo::PreferredWorkGroupSizeMultiple: case DeviceInfo::PreferredWorkGroupSizeMultiple:
case DeviceInfo::LatestConformanceVersionPassed: case DeviceInfo::LatestConformanceVersionPassed:
ANGLE_VALIDATE_VERSION(3, 0); ANGLE_VALIDATE_VERSION(version, 3, 0);
break; break;
case DeviceInfo::InvalidEnum: case DeviceInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -523,7 +724,7 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue, ...@@ -523,7 +724,7 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
} }
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
// or if command_queue is not a valid command-queue for param_name. // 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; return CL_INVALID_COMMAND_QUEUE;
} }
...@@ -533,17 +734,18 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue, ...@@ -533,17 +734,18 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
switch (param_name) switch (param_name)
{ {
case CommandQueueInfo::Size: case CommandQueueInfo::Size:
ANGLE_VALIDATE_VERSION(2, 0); ANGLE_VALIDATE_VERSION(version, 2, 0);
break; break;
case CommandQueueInfo::DeviceDefault: case CommandQueueInfo::DeviceDefault:
ANGLE_VALIDATE_VERSION(2, 1); ANGLE_VALIDATE_VERSION(version, 2, 1);
break; break;
case CommandQueueInfo::PropertiesArray: case CommandQueueInfo::PropertiesArray:
ANGLE_VALIDATE_VERSION(3, 0); ANGLE_VALIDATE_VERSION(version, 3, 0);
break; break;
case CommandQueueInfo::InvalidEnum: case CommandQueueInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -631,17 +833,18 @@ cl_int ValidateGetMemObjectInfo(cl_mem memobj, ...@@ -631,17 +833,18 @@ cl_int ValidateGetMemObjectInfo(cl_mem memobj,
{ {
case MemInfo::AssociatedMemObject: case MemInfo::AssociatedMemObject:
case MemInfo::Offset: case MemInfo::Offset:
ANGLE_VALIDATE_VERSION(1, 1); ANGLE_VALIDATE_VERSION(version, 1, 1);
break; break;
case MemInfo::UsesSVM_Pointer: case MemInfo::UsesSVM_Pointer:
ANGLE_VALIDATE_VERSION(2, 0); ANGLE_VALIDATE_VERSION(version, 2, 0);
break; break;
case MemInfo::Properties: case MemInfo::Properties:
ANGLE_VALIDATE_VERSION(3, 0); ANGLE_VALIDATE_VERSION(version, 3, 0);
break; break;
case MemInfo::InvalidEnum: case MemInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -668,11 +871,12 @@ cl_int ValidateGetImageInfo(cl_mem image, ...@@ -668,11 +871,12 @@ cl_int ValidateGetImageInfo(cl_mem image,
case ImageInfo::Buffer: case ImageInfo::Buffer:
case ImageInfo::NumMipLevels: case ImageInfo::NumMipLevels:
case ImageInfo::NumSamples: case ImageInfo::NumSamples:
ANGLE_VALIDATE_VERSION(1, 2); ANGLE_VALIDATE_VERSION(version, 1, 2);
break; break;
case ImageInfo::InvalidEnum: case ImageInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -708,11 +912,12 @@ cl_int ValidateGetSamplerInfo(cl_sampler sampler, ...@@ -708,11 +912,12 @@ cl_int ValidateGetSamplerInfo(cl_sampler sampler,
switch (param_name) switch (param_name)
{ {
case SamplerInfo::Properties: case SamplerInfo::Properties:
ANGLE_VALIDATE_VERSION(3, 0); ANGLE_VALIDATE_VERSION(version, 3, 0);
break; break;
case SamplerInfo::InvalidEnum: case SamplerInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -825,18 +1030,19 @@ cl_int ValidateGetProgramInfo(cl_program program, ...@@ -825,18 +1030,19 @@ cl_int ValidateGetProgramInfo(cl_program program,
{ {
case ProgramInfo::NumKernels: case ProgramInfo::NumKernels:
case ProgramInfo::KernelNames: case ProgramInfo::KernelNames:
ANGLE_VALIDATE_VERSION(1, 2); ANGLE_VALIDATE_VERSION(version, 1, 2);
break; break;
case ProgramInfo::IL: case ProgramInfo::IL:
ANGLE_VALIDATE_VERSION(2, 1); ANGLE_VALIDATE_VERSION(version, 2, 1);
break; break;
case ProgramInfo::ScopeGlobalCtorsPresent: case ProgramInfo::ScopeGlobalCtorsPresent:
case ProgramInfo::ScopeGlobalDtorsPresent: case ProgramInfo::ScopeGlobalDtorsPresent:
ANGLE_VALIDATE_VERSION(2, 2); ANGLE_VALIDATE_VERSION(version, 2, 2);
break; break;
case ProgramInfo::InvalidEnum: case ProgramInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -922,11 +1128,12 @@ cl_int ValidateGetKernelInfo(cl_kernel kernel, ...@@ -922,11 +1128,12 @@ cl_int ValidateGetKernelInfo(cl_kernel kernel,
switch (param_name) switch (param_name)
{ {
case KernelInfo::Attributes: case KernelInfo::Attributes:
ANGLE_VALIDATE_VERSION(1, 2); ANGLE_VALIDATE_VERSION(version, 1, 2);
break; break;
case KernelInfo::InvalidEnum: case KernelInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -978,7 +1185,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel, ...@@ -978,7 +1185,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel,
switch (param_name) switch (param_name)
{ {
case KernelWorkGroupInfo::GlobalWorkSize: 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 // 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. // device is not a custom device and kernel is not a built-in kernel.
if (!dev->supportsBuiltInKernel(krnl.getInfo().mFunctionName)) if (!dev->supportsBuiltInKernel(krnl.getInfo().mFunctionName))
...@@ -989,6 +1196,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel, ...@@ -989,6 +1196,7 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel,
case KernelWorkGroupInfo::InvalidEnum: case KernelWorkGroupInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -1044,11 +1252,12 @@ cl_int ValidateGetEventInfo(cl_event event, ...@@ -1044,11 +1252,12 @@ cl_int ValidateGetEventInfo(cl_event event,
switch (param_name) switch (param_name)
{ {
case EventInfo::Context: case EventInfo::Context:
ANGLE_VALIDATE_VERSION(1, 1); ANGLE_VALIDATE_VERSION(version, 1, 1);
break; break;
case EventInfo::InvalidEnum: case EventInfo::InvalidEnum:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
default: default:
// All remaining possible values for param_name are valid for all versions.
break; break;
} }
...@@ -1096,6 +1305,26 @@ cl_int ValidateEnqueueReadBuffer(cl_command_queue command_queue, ...@@ -1096,6 +1305,26 @@ cl_int ValidateEnqueueReadBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1109,6 +1338,26 @@ cl_int ValidateEnqueueWriteBuffer(cl_command_queue command_queue, ...@@ -1109,6 +1338,26 @@ cl_int ValidateEnqueueWriteBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1122,6 +1371,54 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue, ...@@ -1122,6 +1371,54 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1204,6 +1501,34 @@ cl_int ValidateEnqueueMapBuffer(cl_command_queue command_queue, ...@@ -1204,6 +1501,34 @@ cl_int ValidateEnqueueMapBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1559,6 +1884,37 @@ cl_int ValidateEnqueueReadBufferRect(cl_command_queue command_queue, ...@@ -1559,6 +1884,37 @@ cl_int ValidateEnqueueReadBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1577,6 +1933,37 @@ cl_int ValidateEnqueueWriteBufferRect(cl_command_queue command_queue, ...@@ -1577,6 +1933,37 @@ cl_int ValidateEnqueueWriteBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1594,6 +1981,51 @@ cl_int ValidateEnqueueCopyBufferRect(cl_command_queue command_queue, ...@@ -1594,6 +1981,51 @@ cl_int ValidateEnqueueCopyBufferRect(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
...@@ -1737,31 +2169,50 @@ cl_int ValidateCreateImage(cl_context context, ...@@ -1737,31 +2169,50 @@ cl_int ValidateCreateImage(cl_context context,
default: default:
return CL_INVALID_IMAGE_DESCRIPTOR; return CL_INVALID_IMAGE_DESCRIPTOR;
} }
// image_row_pitch must be 0 if host_ptr is NULL and can be either 0 if (image_desc->image_row_pitch != 0u)
// 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))
{ {
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 if (image_desc->image_slice_pitch != 0u)
// 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))
{ {
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. // num_mip_levels and num_samples must be 0.
if (image_desc->num_mip_levels != 0u || image_desc->num_samples != 0u) if (image_desc->num_mip_levels != 0u || image_desc->num_samples != 0u)
{ {
return CL_INVALID_IMAGE_DESCRIPTOR; return CL_INVALID_IMAGE_DESCRIPTOR;
} }
// buffer can be a buffer memory object if image_type is CL_MEM_OBJECT_IMAGE1D_BUFFER or // 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. // CL_MEM_OBJECT_IMAGE2D. buffer can be an image object if image_type is CL_MEM_OBJECT_IMAGE2D.
// Otherwise it must be NULL. // Otherwise it must be NULL.
...@@ -1953,6 +2404,45 @@ cl_int ValidateEnqueueFillBuffer(cl_command_queue command_queue, ...@@ -1953,6 +2404,45 @@ cl_int ValidateEnqueueFillBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
const cl_event *event) 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; return CL_SUCCESS;
} }
......
...@@ -714,8 +714,8 @@ cl_int EnqueueReadBuffer(cl_command_queue command_queue, ...@@ -714,8 +714,8 @@ cl_int EnqueueReadBuffer(cl_command_queue command_queue,
const cl_event *event_wait_list, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueReadBuffer); return command_queue->cast<CommandQueue>().enqueueReadBuffer(
return 0; buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
} }
cl_int EnqueueReadBufferRect(cl_command_queue command_queue, cl_int EnqueueReadBufferRect(cl_command_queue command_queue,
...@@ -733,8 +733,10 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueReadBufferRect); return command_queue->cast<CommandQueue>().enqueueReadBufferRect(
return 0; 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, cl_int EnqueueWriteBuffer(cl_command_queue command_queue,
...@@ -747,8 +749,8 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueWriteBuffer); return command_queue->cast<CommandQueue>().enqueueWriteBuffer(
return 0; buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
} }
cl_int EnqueueWriteBufferRect(cl_command_queue command_queue, cl_int EnqueueWriteBufferRect(cl_command_queue command_queue,
...@@ -766,8 +768,10 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueWriteBufferRect); return command_queue->cast<CommandQueue>().enqueueWriteBufferRect(
return 0; 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, cl_int EnqueueFillBuffer(cl_command_queue command_queue,
...@@ -780,8 +784,9 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueFillBuffer); return command_queue->cast<CommandQueue>().enqueueFillBuffer(
return 0; buffer, pattern, pattern_size, offset, size, num_events_in_wait_list, event_wait_list,
event);
} }
cl_int EnqueueCopyBuffer(cl_command_queue command_queue, cl_int EnqueueCopyBuffer(cl_command_queue command_queue,
...@@ -794,8 +799,9 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueCopyBuffer); return command_queue->cast<CommandQueue>().enqueueCopyBuffer(
return 0; 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, cl_int EnqueueCopyBufferRect(cl_command_queue command_queue,
...@@ -812,8 +818,9 @@ 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, const cl_event *event_wait_list,
cl_event *event) cl_event *event)
{ {
WARN_NOT_SUPPORTED(EnqueueCopyBufferRect); return command_queue->cast<CommandQueue>().enqueueCopyBufferRect(
return 0; 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, cl_int EnqueueReadImage(cl_command_queue command_queue,
...@@ -914,8 +921,9 @@ void *EnqueueMapBuffer(cl_command_queue command_queue, ...@@ -914,8 +921,9 @@ void *EnqueueMapBuffer(cl_command_queue command_queue,
cl_event *event, cl_event *event,
cl_int &errorCode) cl_int &errorCode)
{ {
WARN_NOT_SUPPORTED(EnqueueMapBuffer); return command_queue->cast<CommandQueue>().enqueueMapBuffer(
return 0; buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list,
event, errorCode);
} }
void *EnqueueMapImage(cl_command_queue command_queue, 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