Commit 2e772e04 by John Plate Committed by Angle LUCI CQ

CL: Add image enqueue commands

Add image enqueue commands to front end and pass-through back end. Bug: angleproject:6015 Change-Id: I133e84020975679fafd29432c965cd19f086d2b4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2940837Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: John Plate <jplate@google.com>
parent c670917c
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLEvent.h" #include "libANGLE/CLEvent.h"
#include "libANGLE/CLImage.h"
#include <cstring> #include <cstring>
...@@ -126,6 +127,7 @@ cl_int CommandQueue::enqueueReadBuffer(cl_mem buffer, ...@@ -126,6 +127,7 @@ cl_int CommandQueue::enqueueReadBuffer(cl_mem buffer,
cl_int errorCode = cl_int errorCode =
mImpl->enqueueReadBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr); mImpl->enqueueReadBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr) if (errorCode == CL_SUCCESS && event != nullptr)
{ {
ASSERT(eventCreateFunc); ASSERT(eventCreateFunc);
...@@ -152,6 +154,7 @@ cl_int CommandQueue::enqueueWriteBuffer(cl_mem buffer, ...@@ -152,6 +154,7 @@ cl_int CommandQueue::enqueueWriteBuffer(cl_mem buffer,
cl_int errorCode = cl_int errorCode =
mImpl->enqueueWriteBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr); mImpl->enqueueWriteBuffer(buf, blocking, offset, size, ptr, waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr) if (errorCode == CL_SUCCESS && event != nullptr)
{ {
ASSERT(eventCreateFunc); ASSERT(eventCreateFunc);
...@@ -246,6 +249,7 @@ cl_int CommandQueue::enqueueCopyBuffer(cl_mem srcBuffer, ...@@ -246,6 +249,7 @@ cl_int CommandQueue::enqueueCopyBuffer(cl_mem srcBuffer,
cl_int errorCode = mImpl->enqueueCopyBuffer(src, dst, srcOffset, dstOffset, size, waitEvents, cl_int errorCode = mImpl->enqueueCopyBuffer(src, dst, srcOffset, dstOffset, size, waitEvents,
eventCreateFuncPtr); eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr) if (errorCode == CL_SUCCESS && event != nullptr)
{ {
ASSERT(eventCreateFunc); ASSERT(eventCreateFunc);
...@@ -304,6 +308,7 @@ cl_int CommandQueue::enqueueFillBuffer(cl_mem buffer, ...@@ -304,6 +308,7 @@ cl_int CommandQueue::enqueueFillBuffer(cl_mem buffer,
cl_int errorCode = mImpl->enqueueFillBuffer(buf, pattern, patternSize, offset, size, waitEvents, cl_int errorCode = mImpl->enqueueFillBuffer(buf, pattern, patternSize, offset, size, waitEvents,
eventCreateFuncPtr); eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr) if (errorCode == CL_SUCCESS && event != nullptr)
{ {
ASSERT(eventCreateFunc); ASSERT(eventCreateFunc);
...@@ -329,14 +334,213 @@ void *CommandQueue::enqueueMapBuffer(cl_mem buffer, ...@@ -329,14 +334,213 @@ void *CommandQueue::enqueueMapBuffer(cl_mem buffer,
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr = rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr; event != nullptr ? &eventCreateFunc : nullptr;
void *const region = mImpl->enqueueMapBuffer(buf, blocking, mapFlags, offset, size, waitEvents, void *const map = mImpl->enqueueMapBuffer(buf, blocking, mapFlags, offset, size, waitEvents,
eventCreateFuncPtr, errorCode); eventCreateFuncPtr, errorCode);
if (errorCode == CL_SUCCESS && event != nullptr) if (errorCode == CL_SUCCESS && event != nullptr)
{ {
ASSERT(eventCreateFunc); ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_MAP_BUFFER, eventCreateFunc); *event = Object::Create<Event>(errorCode, *this, CL_COMMAND_MAP_BUFFER, eventCreateFunc);
} }
return region; return map;
}
cl_int CommandQueue::enqueueReadImage(cl_mem image,
cl_bool blockingRead,
const size_t *origin,
const size_t *region,
size_t rowPitch,
size_t slicePitch,
void *ptr,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Image &img = image->cast<Image>();
const bool blocking = blockingRead != CL_FALSE;
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode = mImpl->enqueueReadImage(img, blocking, origin, region, rowPitch, slicePitch,
ptr, waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_READ_IMAGE, eventCreateFunc);
}
return errorCode;
}
cl_int CommandQueue::enqueueWriteImage(cl_mem image,
cl_bool blockingWrite,
const size_t *origin,
const size_t *region,
size_t inputRowPitch,
size_t inputSlicePitch,
const void *ptr,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Image &img = image->cast<Image>();
const bool blocking = blockingWrite != CL_FALSE;
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode =
mImpl->enqueueWriteImage(img, blocking, origin, region, inputRowPitch, inputSlicePitch, ptr,
waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_WRITE_IMAGE, eventCreateFunc);
}
return errorCode;
}
cl_int CommandQueue::enqueueCopyImage(cl_mem srcImage,
cl_mem dstImage,
const size_t *srcOrigin,
const size_t *dstOrigin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Image &src = srcImage->cast<Image>();
const Image &dst = dstImage->cast<Image>();
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode = mImpl->enqueueCopyImage(src, dst, srcOrigin, dstOrigin, region, waitEvents,
eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_COPY_IMAGE, eventCreateFunc);
}
return errorCode;
}
cl_int CommandQueue::enqueueFillImage(cl_mem image,
const void *fillColor,
const size_t *origin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Image &img = image->cast<Image>();
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode =
mImpl->enqueueFillImage(img, fillColor, origin, region, waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_FILL_IMAGE, eventCreateFunc);
}
return errorCode;
}
cl_int CommandQueue::enqueueCopyImageToBuffer(cl_mem srcImage,
cl_mem dstBuffer,
const size_t *srcOrigin,
const size_t *region,
size_t dstOffset,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Image &src = srcImage->cast<Image>();
const Buffer &dst = dstBuffer->cast<Buffer>();
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode = mImpl->enqueueCopyImageToBuffer(src, dst, srcOrigin, region, dstOffset,
waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_COPY_IMAGE_TO_BUFFER,
eventCreateFunc);
}
return errorCode;
}
cl_int CommandQueue::enqueueCopyBufferToImage(cl_mem srcBuffer,
cl_mem dstImage,
size_t srcOffset,
const size_t *dstOrigin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event)
{
const Buffer &src = srcBuffer->cast<Buffer>();
const Image &dst = dstImage->cast<Image>();
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
cl_int errorCode = mImpl->enqueueCopyBufferToImage(src, dst, srcOffset, dstOrigin, region,
waitEvents, eventCreateFuncPtr);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_COPY_BUFFER_TO_IMAGE,
eventCreateFunc);
}
return errorCode;
}
void *CommandQueue::enqueueMapImage(cl_mem image,
cl_bool blockingMap,
MapFlags mapFlags,
const size_t *origin,
const size_t *region,
size_t *imageRowPitch,
size_t *imageSlicePitch,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event,
cl_int &errorCode)
{
const Image &img = image->cast<Image>();
const bool blocking = blockingMap != CL_FALSE;
const EventPtrs waitEvents = Event::Cast(numEventsInWaitList, eventWaitList);
rx::CLEventImpl::CreateFunc eventCreateFunc;
rx::CLEventImpl::CreateFunc *const eventCreateFuncPtr =
event != nullptr ? &eventCreateFunc : nullptr;
void *const map =
mImpl->enqueueMapImage(img, blocking, mapFlags, origin, region, imageRowPitch,
imageSlicePitch, waitEvents, eventCreateFuncPtr, errorCode);
if (errorCode == CL_SUCCESS && event != nullptr)
{
ASSERT(eventCreateFunc);
*event = Object::Create<Event>(errorCode, *this, CL_COMMAND_MAP_IMAGE, eventCreateFunc);
}
return map;
} }
CommandQueue::~CommandQueue() CommandQueue::~CommandQueue()
......
...@@ -118,6 +118,75 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -118,6 +118,75 @@ class CommandQueue final : public _cl_command_queue, public Object
cl_event *event, cl_event *event,
cl_int &errorCode); cl_int &errorCode);
cl_int enqueueReadImage(cl_mem image,
cl_bool blockingRead,
const size_t *origin,
const size_t *region,
size_t rowPitch,
size_t slicePitch,
void *ptr,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
cl_int enqueueWriteImage(cl_mem image,
cl_bool blockingWrite,
const size_t *origin,
const size_t *region,
size_t inputRowPitch,
size_t inputSlicePitch,
const void *ptr,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
cl_int enqueueCopyImage(cl_mem srcImage,
cl_mem dstImage,
const size_t *srcOrigin,
const size_t *dstOrigin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
cl_int enqueueFillImage(cl_mem image,
const void *fillColor,
const size_t *origin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
cl_int enqueueCopyImageToBuffer(cl_mem srcImage,
cl_mem dstBuffer,
const size_t *srcOrigin,
const size_t *region,
size_t dstOffset,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
cl_int enqueueCopyBufferToImage(cl_mem srcBuffer,
cl_mem dstImage,
size_t srcOffset,
const size_t *dstOrigin,
const size_t *region,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event);
void *enqueueMapImage(cl_mem image,
cl_bool blockingMap,
MapFlags mapFlags,
const size_t *origin,
const size_t *region,
size_t *imageRowPitch,
size_t *imageSlicePitch,
cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event,
cl_int &errorCode);
public: public:
using PropArray = std::vector<cl_queue_properties>; using PropArray = std::vector<cl_queue_properties>;
......
...@@ -383,6 +383,62 @@ bool Device::supportsBuiltInKernel(const std::string &name) const ...@@ -383,6 +383,62 @@ bool Device::supportsBuiltInKernel(const std::string &name) const
return false; return false;
} }
bool Device::supportsNativeImageDimensions(const cl_image_desc &desc) const
{
switch (desc.image_type)
{
case CL_MEM_OBJECT_IMAGE1D:
return desc.image_width <= mInfo.mImage2D_MaxWidth;
case CL_MEM_OBJECT_IMAGE2D:
return desc.image_width <= mInfo.mImage2D_MaxWidth &&
desc.image_height <= mInfo.mImage2D_MaxHeight;
case CL_MEM_OBJECT_IMAGE3D:
return desc.image_width <= mInfo.mImage3D_MaxWidth &&
desc.image_height <= mInfo.mImage3D_MaxHeight &&
desc.image_depth <= mInfo.mImage3D_MaxDepth;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
return desc.image_width <= mInfo.mImage2D_MaxWidth &&
desc.image_array_size <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
return desc.image_width <= mInfo.mImage2D_MaxWidth &&
desc.image_height <= mInfo.mImage2D_MaxHeight &&
desc.image_array_size <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
return desc.image_width <= mInfo.mImageMaxBufferSize;
default:
ASSERT(false);
break;
}
return false;
}
bool Device::supportsImageDimensions(const ImageDescriptor &desc) const
{
switch (desc.type)
{
case CL_MEM_OBJECT_IMAGE1D:
return desc.width <= mInfo.mImage2D_MaxWidth;
case CL_MEM_OBJECT_IMAGE2D:
return desc.width <= mInfo.mImage2D_MaxWidth && desc.height <= mInfo.mImage2D_MaxHeight;
case CL_MEM_OBJECT_IMAGE3D:
return desc.width <= mInfo.mImage3D_MaxWidth &&
desc.height <= mInfo.mImage3D_MaxHeight && desc.depth <= mInfo.mImage3D_MaxDepth;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
return desc.width <= mInfo.mImage2D_MaxWidth &&
desc.arraySize <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
return desc.width <= mInfo.mImage2D_MaxWidth &&
desc.height <= mInfo.mImage2D_MaxHeight &&
desc.arraySize <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
return desc.width <= mInfo.mImageMaxBufferSize;
default:
ASSERT(false);
break;
}
return false;
}
Device::Device(Platform &platform, Device::Device(Platform &platform,
Device *parent, Device *parent,
DeviceType type, DeviceType type,
......
...@@ -43,6 +43,8 @@ class Device final : public _cl_device_id, public Object ...@@ -43,6 +43,8 @@ class Device final : public _cl_device_id, public Object
T &getImpl() const; T &getImpl() const;
bool supportsBuiltInKernel(const std::string &name) const; bool supportsBuiltInKernel(const std::string &name) const;
bool supportsNativeImageDimensions(const cl_image_desc &desc) const;
bool supportsImageDimensions(const ImageDescriptor &desc) const;
static bool IsValidType(DeviceType type); static bool IsValidType(DeviceType type);
......
...@@ -116,6 +116,30 @@ bool Image::IsValid(const _cl_mem *image) ...@@ -116,6 +116,30 @@ bool Image::IsValid(const _cl_mem *image)
Image::~Image() = default; Image::~Image() = default;
bool Image::isRegionValid(const size_t origin[3], const size_t region[3]) const
{
switch (getType())
{
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
return origin[0] + region[0] <= mDesc.width;
case CL_MEM_OBJECT_IMAGE2D:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.height;
case CL_MEM_OBJECT_IMAGE3D:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.height &&
origin[2] + region[2] <= mDesc.depth;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.arraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.height &&
origin[2] + region[2] <= mDesc.arraySize;
default:
ASSERT(false);
break;
}
return false;
}
Image::Image(Context &context, Image::Image(Context &context,
PropArray &&properties, PropArray &&properties,
MemFlags flags, MemFlags flags,
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "libANGLE/CLMemory.h" #include "libANGLE/CLMemory.h"
#include "libANGLE/cl_utils.h"
namespace cl namespace cl
{ {
...@@ -30,6 +32,12 @@ class Image final : public Memory ...@@ -30,6 +32,12 @@ class Image final : public Memory
const cl_image_format &getFormat() const; const cl_image_format &getFormat() const;
const ImageDescriptor &getDescriptor() const; const ImageDescriptor &getDescriptor() const;
bool isRegionValid(const size_t origin[3], const size_t region[3]) const;
size_t getElementSize() const;
size_t getRowSize() const;
size_t getSliceSize() const;
private: private:
Image(Context &context, Image(Context &context,
PropArray &&properties, PropArray &&properties,
...@@ -61,6 +69,21 @@ inline const ImageDescriptor &Image::getDescriptor() const ...@@ -61,6 +69,21 @@ inline const ImageDescriptor &Image::getDescriptor() const
return mDesc; return mDesc;
} }
inline size_t Image::getElementSize() const
{
return GetElementSize(mFormat);
}
inline size_t Image::getRowSize() const
{
return GetElementSize(mFormat) * mDesc.width;
}
inline size_t Image::getSliceSize() const
{
return GetElementSize(mFormat) * mDesc.width * mDesc.height;
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLIMAGE_H_ #endif // LIBANGLE_CLIMAGE_H_
...@@ -35,6 +35,7 @@ class Memory : public _cl_mem, public Object ...@@ -35,6 +35,7 @@ class Memory : public _cl_mem, public Object
void *getHostPtr() const; void *getHostPtr() const;
const MemoryPtr &getParent() const; const MemoryPtr &getParent() const;
size_t getOffset() const; size_t getOffset() const;
size_t getSize() const;
template <typename T = rx::CLMemoryImpl> template <typename T = rx::CLMemoryImpl>
T &getImpl() const; T &getImpl() const;
...@@ -112,6 +113,11 @@ inline size_t Memory::getOffset() const ...@@ -112,6 +113,11 @@ inline size_t Memory::getOffset() const
return mOffset; return mOffset;
} }
inline size_t Memory::getSize() const
{
return mSize;
}
template <typename T> template <typename T>
inline T &Memory::getImpl() const inline T &Memory::getImpl() const
{ {
......
...@@ -17,6 +17,15 @@ size_t GetChannelCount(cl_channel_order channelOrder); ...@@ -17,6 +17,15 @@ size_t GetChannelCount(cl_channel_order channelOrder);
size_t GetElementSize(const cl_image_format &image_format); size_t GetElementSize(const cl_image_format &image_format);
inline bool OverlapRegions(size_t offset1, size_t offset2, size_t size)
{
// From https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html
// The regions overlap if src_offset <= dst_offset <= src_offset + size - 1
// or if dst_offset <= src_offset <= dst_offset + size - 1.
return (offset1 <= offset2 && offset2 <= offset1 + size - 1u) ||
(offset2 <= offset1 && offset1 <= offset2 + size - 1u);
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CL_UTILS_H_ #endif // LIBANGLE_CL_UTILS_H_
...@@ -102,6 +102,68 @@ class CLCommandQueueImpl : angle::NonCopyable ...@@ -102,6 +102,68 @@ class CLCommandQueueImpl : angle::NonCopyable
CLEventImpl::CreateFunc *eventCreateFunc, CLEventImpl::CreateFunc *eventCreateFunc,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
virtual cl_int enqueueReadImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t rowPitch,
size_t slicePitch,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueWriteImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t inputRowPitch,
size_t inputSlicePitch,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueCopyImage(const cl::Image &srcImage,
const cl::Image &dstImage,
const size_t srcOrigin[3],
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueFillImage(const cl::Image &image,
const void *fillColor,
const size_t origin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueCopyImageToBuffer(const cl::Image &srcImage,
const cl::Buffer &dstBuffer,
const size_t srcOrigin[3],
const size_t region[3],
size_t dstOffset,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual cl_int enqueueCopyBufferToImage(const cl::Buffer &srcBuffer,
const cl::Image &dstImage,
size_t srcOffset,
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) = 0;
virtual void *enqueueMapImage(const cl::Image &image,
bool blocking,
cl::MapFlags mapFlags,
const size_t origin[3],
const size_t region[3],
size_t *imageRowPitch,
size_t *imageSlicePitch,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc,
cl_int &errorCode) = 0;
protected: protected:
const cl::CommandQueue &mCommandQueue; const cl::CommandQueue &mCommandQueue;
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/renderer/cl/CLMemoryCL.h" #include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h" #include "libANGLE/CLBuffer.h"
#include "libANGLE/CLImage.h"
namespace rx namespace rx
{ {
...@@ -55,7 +56,7 @@ cl_int CLCommandQueueCL::enqueueReadBuffer(const cl::Buffer &buffer, ...@@ -55,7 +56,7 @@ cl_int CLCommandQueueCL::enqueueReadBuffer(const cl::Buffer &buffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -84,7 +85,7 @@ cl_int CLCommandQueueCL::enqueueWriteBuffer(const cl::Buffer &buffer, ...@@ -84,7 +85,7 @@ cl_int CLCommandQueueCL::enqueueWriteBuffer(const cl::Buffer &buffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -119,7 +120,7 @@ cl_int CLCommandQueueCL::enqueueReadBufferRect(const cl::Buffer &buffer, ...@@ -119,7 +120,7 @@ cl_int CLCommandQueueCL::enqueueReadBufferRect(const cl::Buffer &buffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -154,7 +155,7 @@ cl_int CLCommandQueueCL::enqueueWriteBufferRect(const cl::Buffer &buffer, ...@@ -154,7 +155,7 @@ cl_int CLCommandQueueCL::enqueueWriteBufferRect(const cl::Buffer &buffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -183,7 +184,7 @@ cl_int CLCommandQueueCL::enqueueCopyBuffer(const cl::Buffer &srcBuffer, ...@@ -183,7 +184,7 @@ cl_int CLCommandQueueCL::enqueueCopyBuffer(const cl::Buffer &srcBuffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -216,7 +217,7 @@ cl_int CLCommandQueueCL::enqueueCopyBufferRect(const cl::Buffer &srcBuffer, ...@@ -216,7 +217,7 @@ cl_int CLCommandQueueCL::enqueueCopyBufferRect(const cl::Buffer &srcBuffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -244,7 +245,7 @@ cl_int CLCommandQueueCL::enqueueFillBuffer(const cl::Buffer &buffer, ...@@ -244,7 +245,7 @@ cl_int CLCommandQueueCL::enqueueFillBuffer(const cl::Buffer &buffer,
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
...@@ -268,17 +269,225 @@ void *CLCommandQueueCL::enqueueMapBuffer(const cl::Buffer &buffer, ...@@ -268,17 +269,225 @@ void *CLCommandQueueCL::enqueueMapBuffer(const cl::Buffer &buffer,
cl_event nativeEvent = nullptr; cl_event nativeEvent = nullptr;
cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr; cl_event *const nativeEventPtr = eventCreateFunc != nullptr ? &nativeEvent : nullptr;
void *const region = mNative->getDispatch().clEnqueueMapBuffer( void *const map = mNative->getDispatch().clEnqueueMapBuffer(
mNative, nativeBuffer, block, mapFlags.get(), offset, size, numEvents, nativeEventsPtr, mNative, nativeBuffer, block, mapFlags.get(), offset, size, numEvents, nativeEventsPtr,
nativeEventPtr, &errorCode); nativeEventPtr, &errorCode);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr) if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{ {
*eventCreateFunc = [=](const cl::Event &event) { *eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent)); return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
}; };
} }
return region; return map;
}
cl_int CLCommandQueueCL::enqueueReadImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t rowPitch,
size_t slicePitch,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeImage = image.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().clEnqueueReadImage(
mNative, nativeImage, block, origin, region, rowPitch, slicePitch, ptr, numEvents,
nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueWriteImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t inputRowPitch,
size_t inputSlicePitch,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeImage = image.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().clEnqueueWriteImage(
mNative, nativeImage, block, origin, region, inputRowPitch, inputSlicePitch, ptr, numEvents,
nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueCopyImage(const cl::Image &srcImage,
const cl::Image &dstImage,
const size_t srcOrigin[3],
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeSrc = srcImage.getImpl<CLMemoryCL>().getNative();
const cl_mem nativeDst = dstImage.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().clEnqueueCopyImage(
mNative, nativeSrc, nativeDst, srcOrigin, dstOrigin, region, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueFillImage(const cl::Image &image,
const void *fillColor,
const size_t origin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeImage = image.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().clEnqueueFillImage(mNative, nativeImage, fillColor, origin, region,
numEvents, nativeEventsPtr, nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueCopyImageToBuffer(const cl::Image &srcImage,
const cl::Buffer &dstBuffer,
const size_t srcOrigin[3],
const size_t region[3],
size_t dstOffset,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeSrc = srcImage.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().clEnqueueCopyImageToBuffer(
mNative, nativeSrc, nativeDst, srcOrigin, region, dstOffset, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
cl_int CLCommandQueueCL::enqueueCopyBufferToImage(const cl::Buffer &srcBuffer,
const cl::Image &dstImage,
size_t srcOffset,
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc)
{
const cl_mem nativeSrc = srcBuffer.getImpl<CLMemoryCL>().getNative();
const cl_mem nativeDst = dstImage.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().clEnqueueCopyBufferToImage(
mNative, nativeSrc, nativeDst, srcOffset, dstOrigin, region, numEvents, nativeEventsPtr,
nativeEventPtr);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return errorCode;
}
void *CLCommandQueueCL::enqueueMapImage(const cl::Image &image,
bool blocking,
cl::MapFlags mapFlags,
const size_t origin[3],
const size_t region[3],
size_t *imageRowPitch,
size_t *imageSlicePitch,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc,
cl_int &errorCode)
{
const cl_mem nativeImage = image.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 map = mNative->getDispatch().clEnqueueMapImage(
mNative, nativeImage, block, mapFlags.get(), origin, region, imageRowPitch, imageSlicePitch,
numEvents, nativeEventsPtr, nativeEventPtr, &errorCode);
if (errorCode == CL_SUCCESS && eventCreateFunc != nullptr)
{
*eventCreateFunc = [nativeEvent](const cl::Event &event) {
return CLEventImpl::Ptr(new CLEventCL(event, nativeEvent));
};
}
return map;
} }
} // namespace rx } // namespace rx
...@@ -101,6 +101,68 @@ class CLCommandQueueCL : public CLCommandQueueImpl ...@@ -101,6 +101,68 @@ class CLCommandQueueCL : public CLCommandQueueImpl
CLEventImpl::CreateFunc *eventCreateFunc, CLEventImpl::CreateFunc *eventCreateFunc,
cl_int &errorCode) override; cl_int &errorCode) override;
cl_int enqueueReadImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t rowPitch,
size_t slicePitch,
void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueWriteImage(const cl::Image &image,
bool blocking,
const size_t origin[3],
const size_t region[3],
size_t inputRowPitch,
size_t inputSlicePitch,
const void *ptr,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueCopyImage(const cl::Image &srcImage,
const cl::Image &dstImage,
const size_t srcOrigin[3],
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueFillImage(const cl::Image &image,
const void *fillColor,
const size_t origin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueCopyImageToBuffer(const cl::Image &srcImage,
const cl::Buffer &dstBuffer,
const size_t srcOrigin[3],
const size_t region[3],
size_t dstOffset,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
cl_int enqueueCopyBufferToImage(const cl::Buffer &srcBuffer,
const cl::Image &dstImage,
size_t srcOffset,
const size_t dstOrigin[3],
const size_t region[3],
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc) override;
void *enqueueMapImage(const cl::Image &image,
bool blocking,
cl::MapFlags mapFlags,
const size_t origin[3],
const size_t region[3],
size_t *imageRowPitch,
size_t *imageSlicePitch,
const cl::EventPtrs &waitEvents,
CLEventImpl::CreateFunc *eventCreateFunc,
cl_int &errorCode) override;
private: private:
const cl_command_queue mNative; const cl_command_queue mNative;
}; };
......
...@@ -212,7 +212,7 @@ cl_int CLDeviceCL::createSubDevices(const cl_device_partition_property *properti ...@@ -212,7 +212,7 @@ cl_int CLDeviceCL::createSubDevices(const cl_device_partition_property *properti
{ {
for (cl_device_id nativeSubDevice : nativeSubDevices) for (cl_device_id nativeSubDevice : nativeSubDevices)
{ {
createFuncs.emplace_back([=](const cl::Device &device) { createFuncs.emplace_back([nativeSubDevice](const cl::Device &device) {
return Ptr(new CLDeviceCL(device, nativeSubDevice)); return Ptr(new CLDeviceCL(device, nativeSubDevice));
}); });
} }
......
...@@ -348,7 +348,7 @@ CLDeviceImpl::CreateDatas CLPlatformCL::createDevices() const ...@@ -348,7 +348,7 @@ CLDeviceImpl::CreateDatas CLPlatformCL::createDevices() const
} }
cl_device_id nativeDevice = nativeDevices[index]; cl_device_id nativeDevice = nativeDevices[index];
createDatas.emplace_back(types[index], [=](const cl::Device &device) { createDatas.emplace_back(types[index], [nativeDevice](const cl::Device &device) {
return CLDeviceCL::Ptr(new CLDeviceCL(device, nativeDevice)); return CLDeviceCL::Ptr(new CLDeviceCL(device, nativeDevice));
}); });
} }
...@@ -418,7 +418,7 @@ void CLPlatformCL::Initialize(CreateFuncs &createFuncs, bool isIcd) ...@@ -418,7 +418,7 @@ void CLPlatformCL::Initialize(CreateFuncs &createFuncs, bool isIcd)
for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next) for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next)
{ {
cl_platform_id nativePlatform = vendorIt->platform; cl_platform_id nativePlatform = vendorIt->platform;
createFuncs.emplace_back([=](const cl::Platform &platform) { createFuncs.emplace_back([nativePlatform](const cl::Platform &platform) {
return Ptr(new CLPlatformCL(platform, nativePlatform)); return Ptr(new CLPlatformCL(platform, nativePlatform));
}); });
} }
......
...@@ -70,7 +70,7 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels, ...@@ -70,7 +70,7 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels,
{ {
for (cl_kernel nativeKernel : nativeKernels) for (cl_kernel nativeKernel : nativeKernels)
{ {
createFuncs.emplace_back([=](const cl::Kernel &kernel) { createFuncs.emplace_back([nativeKernel](const cl::Kernel &kernel) {
return CLKernelImpl::Ptr(new CLKernelCL(kernel, nativeKernel)); return CLKernelImpl::Ptr(new CLKernelCL(kernel, nativeKernel));
}); });
} }
......
...@@ -20,6 +20,16 @@ ...@@ -20,6 +20,16 @@
} \ } \
} while (0) } while (0)
#define ANGLE_TRY(expression) \
do \
{ \
const cl_int errorCode = expression; \
if (errorCode != CL_SUCCESS) \
{ \
return errorCode; \
} \
} while (0)
namespace cl namespace cl
{ {
...@@ -240,6 +250,7 @@ bool ValidateImageFormat(const cl_image_format *imageFormat, const Platform &pla ...@@ -240,6 +250,7 @@ bool ValidateImageFormat(const cl_image_format *imageFormat, const Platform &pla
} }
cl_int ValidateCommandQueueAndEventWaitList(cl_command_queue commandQueue, cl_int ValidateCommandQueueAndEventWaitList(cl_command_queue commandQueue,
bool validateImageSupport,
cl_uint numEvents, cl_uint numEvents,
const cl_event *events) const cl_event *events)
{ {
...@@ -254,6 +265,15 @@ cl_int ValidateCommandQueueAndEventWaitList(cl_command_queue commandQueue, ...@@ -254,6 +265,15 @@ cl_int ValidateCommandQueueAndEventWaitList(cl_command_queue commandQueue,
return CL_INVALID_COMMAND_QUEUE; return CL_INVALID_COMMAND_QUEUE;
} }
if (validateImageSupport)
{
// CL_INVALID_OPERATION if the device associated with command_queue does not support images.
if (queue.getDevice().getInfo().mImageSupport == CL_FALSE)
{
return CL_INVALID_OPERATION;
}
}
// CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and num_events_in_wait_list > 0, // 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, ... // or event_wait_list is not NULL and num_events_in_wait_list is 0, ...
if ((events == nullptr) != (numEvents == 0u)) if ((events == nullptr) != (numEvents == 0u))
...@@ -419,6 +439,140 @@ cl_int ValidateHostRect(const size_t *hostOrigin, ...@@ -419,6 +439,140 @@ cl_int ValidateHostRect(const size_t *hostOrigin,
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_int ValidateEnqueueImage(const CommandQueue &queue, cl_mem image, bool hostRead, bool hostWrite)
{
// CL_INVALID_MEM_OBJECT if image is not a valid image object.
if (!Image::IsValid(image))
{
return CL_INVALID_MEM_OBJECT;
}
const Image &img = image->cast<Image>();
// CL_INVALID_CONTEXT if the context associated with command_queue and image are not the same.
if (&queue.getContext() != &img.getContext())
{
return CL_INVALID_CONTEXT;
}
// CL_INVALID_OPERATION if a read function is called on image which
// has been created with CL_MEM_HOST_WRITE_ONLY or CL_MEM_HOST_NO_ACCESS.
if (hostRead && img.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 image which
// has been created with CL_MEM_HOST_READ_ONLY or CL_MEM_HOST_NO_ACCESS.
if (hostWrite && img.getEffectiveFlags().isSet(CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS))
{
return CL_INVALID_OPERATION;
}
return CL_SUCCESS;
}
cl_int ValidateImageForDevice(const Image &image,
const Device &device,
const size_t *origin,
const size_t *region)
{
// CL_INVALID_VALUE if origin or region is NULL.
if (origin == nullptr || region == nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if values in origin and region do not follow rules
// described in the argument description for origin and region.
// The values in region cannot be 0.
if (region[0] == 0u || region[1] == 0u || region[2] == 0u)
{
return CL_INVALID_VALUE;
}
switch (image.getType())
{
// If image is a 1D image or 1D image buffer object,
// origin[1] and origin[2] must be 0 and region[1] and region[2] must be 1.
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
if (origin[1] != 0u || origin[2] != 0u || region[1] != 1u || region[2] != 1u)
{
return CL_INVALID_VALUE;
}
break;
// If image is a 2D image object or a 1D image array object,
// origin[2] must be 0 and region[2] must be 1.
case CL_MEM_OBJECT_IMAGE2D:
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
if (origin[2] != 0u || region[2] != 1u)
{
return CL_INVALID_VALUE;
}
break;
case CL_MEM_OBJECT_IMAGE3D:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
break;
default:
ASSERT(false);
return CL_INVALID_IMAGE_DESCRIPTOR;
}
// CL_INVALID_VALUE if the region being read or written
// specified by origin and region is out of bounds.
if (!image.isRegionValid(origin, region))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified or compute
// row and/or slice pitch) for image are not supported by device associated with queue.
if (!device.supportsImageDimensions(image.getDescriptor()))
{
return CL_INVALID_IMAGE_SIZE;
}
return CL_SUCCESS;
}
cl_int ValidateHostRegionForImage(const Image &image,
size_t rowPitch,
size_t slicePitch,
const void *ptr)
{
// CL_INVALID_VALUE if row_pitch is not 0 and is less than the element size in bytes x width.
if (rowPitch == 0u)
{
rowPitch = image.getRowSize();
}
else if (rowPitch < image.getRowSize())
{
return CL_INVALID_VALUE;
}
if (slicePitch != 0u)
{
// slice_pitch must be 0 if image is a 1D or 2D image.
if (image.getType() == CL_MEM_OBJECT_IMAGE1D ||
image.getType() == CL_MEM_OBJECT_IMAGE1D_BUFFER ||
image.getType() == CL_MEM_OBJECT_IMAGE2D)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if slice_pitch is not 0 and is less than row_pitch x height.
if (slicePitch < rowPitch * image.getDescriptor().height)
{
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
...@@ -610,11 +764,7 @@ cl_int ValidateCreateContext(const cl_context_properties *properties, ...@@ -610,11 +764,7 @@ cl_int ValidateCreateContext(const cl_context_properties *properties,
const void *user_data) const void *user_data)
{ {
const Platform *platform = nullptr; const Platform *platform = nullptr;
const cl_int errorCode = ValidateContextProperties(properties, platform); ANGLE_TRY(ValidateContextProperties(properties, platform));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if devices is NULL or if num_devices is equal to zero // CL_INVALID_VALUE if devices is NULL or if num_devices is equal to zero
// or if pfn_notify is NULL but user_data is not NULL. // or if pfn_notify is NULL but user_data is not NULL.
...@@ -645,11 +795,7 @@ cl_int ValidateCreateContextFromType(const cl_context_properties *properties, ...@@ -645,11 +795,7 @@ cl_int ValidateCreateContextFromType(const cl_context_properties *properties,
const void *user_data) const void *user_data)
{ {
const Platform *platform = nullptr; const Platform *platform = nullptr;
const cl_int errorCode = ValidateContextProperties(properties, platform); ANGLE_TRY(ValidateContextProperties(properties, platform));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_DEVICE_TYPE if device_type is not a valid value. // CL_INVALID_DEVICE_TYPE if device_type is not a valid value.
if (!Device::IsValidType(device_type)) if (!Device::IsValidType(device_type))
...@@ -1305,18 +1451,9 @@ cl_int ValidateEnqueueReadBuffer(cl_command_queue command_queue, ...@@ -1305,18 +1451,9 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS) ANGLE_TRY(ValidateEnqueueBuffer(command_queue->cast<CommandQueue>(), buffer, true, false));
{
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 // 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. // by (offset, size) is out of bounds or if ptr is a NULL value.
...@@ -1338,18 +1475,9 @@ cl_int ValidateEnqueueWriteBuffer(cl_command_queue command_queue, ...@@ -1338,18 +1475,9 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS) ANGLE_TRY(ValidateEnqueueBuffer(command_queue->cast<CommandQueue>(), buffer, false, true));
{
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 // 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. // by (offset, size) is out of bounds or if ptr is a NULL value.
...@@ -1371,26 +1499,14 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue, ...@@ -1371,26 +1499,14 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
errorCode = ValidateEnqueueBuffer(queue, src_buffer, false, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, src_buffer, false, false));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &src = src_buffer->cast<Buffer>(); const Buffer &src = src_buffer->cast<Buffer>();
errorCode = ValidateEnqueueBuffer(queue, dst_buffer, false, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, dst_buffer, false, false));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &dst = dst_buffer->cast<Buffer>(); const Buffer &dst = dst_buffer->cast<Buffer>();
// CL_INVALID_VALUE if src_offset, dst_offset, size, src_offset + size or dst_offset + size // CL_INVALID_VALUE if src_offset, dst_offset, size, src_offset + size or dst_offset + size
...@@ -1410,10 +1526,7 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue, ...@@ -1410,10 +1526,7 @@ cl_int ValidateEnqueueCopyBuffer(cl_command_queue command_queue,
src_offset += src.getOffset(); src_offset += src.getOffset();
dst_offset += dst.getOffset(); dst_offset += dst.getOffset();
// The regions overlap if src_offset <= dst_offset <= src_offset + size - 1 if (OverlapRegions(src_offset, dst_offset, size))
// 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_MEM_COPY_OVERLAP;
} }
...@@ -1434,6 +1547,16 @@ cl_int ValidateEnqueueReadImage(cl_command_queue command_queue, ...@@ -1434,6 +1547,16 @@ cl_int ValidateEnqueueReadImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
ANGLE_TRY(ValidateEnqueueImage(queue, image, true, false));
const Image &img = image->cast<Image>();
ANGLE_TRY(ValidateImageForDevice(img, queue.getDevice(), origin, region));
ANGLE_TRY(ValidateHostRegionForImage(img, row_pitch, slice_pitch, ptr));
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1449,6 +1572,16 @@ cl_int ValidateEnqueueWriteImage(cl_command_queue command_queue, ...@@ -1449,6 +1572,16 @@ cl_int ValidateEnqueueWriteImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
ANGLE_TRY(ValidateEnqueueImage(queue, image, false, true));
const Image &img = image->cast<Image>();
ANGLE_TRY(ValidateImageForDevice(img, queue.getDevice(), origin, region));
ANGLE_TRY(ValidateHostRegionForImage(img, input_row_pitch, input_slice_pitch, ptr));
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1462,6 +1595,56 @@ cl_int ValidateEnqueueCopyImage(cl_command_queue command_queue, ...@@ -1462,6 +1595,56 @@ cl_int ValidateEnqueueCopyImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
ANGLE_TRY(ValidateEnqueueImage(queue, src_image, false, false));
const Image &src = src_image->cast<Image>();
ANGLE_TRY(ValidateEnqueueImage(queue, dst_image, false, false));
const Image &dst = dst_image->cast<Image>();
// CL_IMAGE_FORMAT_MISMATCH if src_image and dst_image do not use the same image format.
if (src.getFormat().image_channel_order != dst.getFormat().image_channel_order ||
src.getFormat().image_channel_data_type != dst.getFormat().image_channel_data_type)
{
return CL_IMAGE_FORMAT_MISMATCH;
}
ANGLE_TRY(ValidateImageForDevice(src, queue.getDevice(), src_origin, region));
ANGLE_TRY(ValidateImageForDevice(dst, queue.getDevice(), dst_origin, region));
// CL_MEM_COPY_OVERLAP if src_image and dst_image are the same image object
// and the source and destination regions overlap.
if (&src == &dst)
{
const cl_mem_object_type type = src.getType();
// Check overlap in first dimension
if (OverlapRegions(src_origin[0], dst_origin[0], region[0]))
{
if (type == CL_MEM_OBJECT_IMAGE1D || type == CL_MEM_OBJECT_IMAGE1D_BUFFER)
{
return CL_MEM_COPY_OVERLAP;
}
// Check overlap in second dimension
if (OverlapRegions(src_origin[1], dst_origin[1], region[1]))
{
if (type == CL_MEM_OBJECT_IMAGE2D || type == CL_MEM_OBJECT_IMAGE1D_ARRAY)
{
return CL_MEM_COPY_OVERLAP;
}
// Check overlap in third dimension
if (OverlapRegions(src_origin[2], dst_origin[2], region[2]))
{
return CL_MEM_COPY_OVERLAP;
}
}
}
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1475,6 +1658,41 @@ cl_int ValidateEnqueueCopyImageToBuffer(cl_command_queue command_queue, ...@@ -1475,6 +1658,41 @@ cl_int ValidateEnqueueCopyImageToBuffer(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
ANGLE_TRY(ValidateEnqueueImage(queue, src_image, false, false));
const Image &src = src_image->cast<Image>();
ANGLE_TRY(ValidateEnqueueBuffer(queue, dst_buffer, false, false));
const Buffer &dst = dst_buffer->cast<Buffer>();
// CL_INVALID_MEM_OBJECT if src_image is a 1D image buffer object created from dst_buffer.
if (src.getType() == CL_MEM_OBJECT_IMAGE1D_BUFFER && src.getParent().get() == &dst)
{
return CL_INVALID_MEM_OBJECT;
}
ANGLE_TRY(ValidateImageForDevice(src, queue.getDevice(), src_origin, region));
// CL_INVALID_VALUE if the region specified by dst_offset and dst_offset + dst_cb
// refer to a region outside dst_buffer.
const cl_mem_object_type type = src.getType();
size_t dst_cb = src.getElementSize() * region[0];
if (type != CL_MEM_OBJECT_IMAGE1D && type != CL_MEM_OBJECT_IMAGE1D_BUFFER)
{
dst_cb *= region[1];
if (type != CL_MEM_OBJECT_IMAGE2D && type != CL_MEM_OBJECT_IMAGE1D_ARRAY)
{
dst_cb *= region[2];
}
}
if (!dst.isRegionValid(dst_offset, dst_cb))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1488,6 +1706,41 @@ cl_int ValidateEnqueueCopyBufferToImage(cl_command_queue command_queue, ...@@ -1488,6 +1706,41 @@ cl_int ValidateEnqueueCopyBufferToImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
ANGLE_TRY(ValidateEnqueueBuffer(queue, src_buffer, false, false));
const Buffer &src = src_buffer->cast<Buffer>();
ANGLE_TRY(ValidateEnqueueImage(queue, dst_image, false, false));
const Image &dst = dst_image->cast<Image>();
// CL_INVALID_MEM_OBJECT if dst_image is a 1D image buffer object created from src_buffer.
if (dst.getType() == CL_MEM_OBJECT_IMAGE1D_BUFFER && dst.getParent().get() == &src)
{
return CL_INVALID_MEM_OBJECT;
}
ANGLE_TRY(ValidateImageForDevice(dst, queue.getDevice(), dst_origin, region));
// CL_INVALID_VALUE if the region specified by src_offset and src_offset + src_cb
// refer to a region outside src_buffer.
const cl_mem_object_type type = dst.getType();
size_t src_cb = dst.getElementSize() * region[0];
if (type != CL_MEM_OBJECT_IMAGE1D && type != CL_MEM_OBJECT_IMAGE1D_BUFFER)
{
src_cb *= region[1];
if (type != CL_MEM_OBJECT_IMAGE2D && type != CL_MEM_OBJECT_IMAGE1D_ARRAY)
{
src_cb *= region[2];
}
}
if (!src.isRegionValid(src_offset, src_cb))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1501,25 +1754,17 @@ cl_int ValidateEnqueueMapBuffer(cl_command_queue command_queue, ...@@ -1501,25 +1754,17 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
// CL_INVALID_OPERATION if buffer has been created with CL_MEM_HOST_WRITE_ONLY or // 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 // 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 // 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. // and CL_MAP_WRITE or CL_MAP_WRITE_INVALIDATE_REGION is set in map_flags.
errorCode = ANGLE_TRY(
ValidateEnqueueBuffer(queue, buffer, map_flags.isSet(CL_MAP_READ), ValidateEnqueueBuffer(queue, buffer, map_flags.isSet(CL_MAP_READ),
map_flags.isSet(CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION)); 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 // 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. // or if size is 0 or if values specified in map_flags are not valid.
...@@ -1544,6 +1789,41 @@ cl_int ValidateEnqueueMapImage(cl_command_queue command_queue, ...@@ -1544,6 +1789,41 @@ cl_int ValidateEnqueueMapImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
// CL_INVALID_OPERATION if image 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 image 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.
ANGLE_TRY(ValidateEnqueueImage(queue, image, map_flags.isSet(CL_MAP_READ),
map_flags.isSet(CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION)));
const Image &img = image->cast<Image>();
ANGLE_TRY(ValidateImageForDevice(img, queue.getDevice(), origin, region));
// CL_INVALID_VALUE if values specified in map_flags are not valid.
if (!ValidateMapFlags(map_flags, queue.getContext().getPlatform()))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if image_row_pitch is NULL.
if (image_row_pitch == nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if image is a 3D image, 1D or 2D image array object
// and image_slice_pitch is NULL.
if ((img.getType() == CL_MEM_OBJECT_IMAGE3D || img.getType() == CL_MEM_OBJECT_IMAGE1D_ARRAY ||
img.getType() == CL_MEM_OBJECT_IMAGE2D_ARRAY) &&
image_slice_pitch == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1884,36 +2164,18 @@ cl_int ValidateEnqueueReadBufferRect(cl_command_queue command_queue, ...@@ -1884,36 +2164,18 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u)) if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{ {
return CL_INVALID_COMMAND_QUEUE; return CL_INVALID_COMMAND_QUEUE;
} }
errorCode = ValidateEnqueueBuffer(queue, buffer, true, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, buffer, true, false));
if (errorCode != CL_SUCCESS) ANGLE_TRY(ValidateBufferRect(buffer->cast<Buffer>(), buffer_origin, region, buffer_row_pitch,
{ buffer_slice_pitch));
return errorCode; ANGLE_TRY(ValidateHostRect(host_origin, region, host_row_pitch, host_slice_pitch, ptr));
}
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;
} }
...@@ -1933,36 +2195,18 @@ cl_int ValidateEnqueueWriteBufferRect(cl_command_queue command_queue, ...@@ -1933,36 +2195,18 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u)) if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{ {
return CL_INVALID_COMMAND_QUEUE; return CL_INVALID_COMMAND_QUEUE;
} }
errorCode = ValidateEnqueueBuffer(queue, buffer, false, true); ANGLE_TRY(ValidateEnqueueBuffer(queue, buffer, false, true));
if (errorCode != CL_SUCCESS) ANGLE_TRY(ValidateBufferRect(buffer->cast<Buffer>(), buffer_origin, region, buffer_row_pitch,
{ buffer_slice_pitch));
return errorCode; ANGLE_TRY(ValidateHostRect(host_origin, region, host_row_pitch, host_slice_pitch, ptr));
}
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;
} }
...@@ -1981,43 +2225,22 @@ cl_int ValidateEnqueueCopyBufferRect(cl_command_queue command_queue, ...@@ -1981,43 +2225,22 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u)) if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 1u))
{ {
return CL_INVALID_COMMAND_QUEUE; return CL_INVALID_COMMAND_QUEUE;
} }
errorCode = ValidateEnqueueBuffer(queue, src_buffer, false, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, src_buffer, false, false));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &src = src_buffer->cast<Buffer>(); const Buffer &src = src_buffer->cast<Buffer>();
errorCode = ValidateEnqueueBuffer(queue, dst_buffer, false, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, dst_buffer, false, false));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const Buffer &dst = dst_buffer->cast<Buffer>(); const Buffer &dst = dst_buffer->cast<Buffer>();
errorCode = ValidateBufferRect(src, src_origin, region, src_row_pitch, src_slice_pitch); ANGLE_TRY(ValidateBufferRect(src, src_origin, region, src_row_pitch, src_slice_pitch));
if (errorCode != CL_SUCCESS) ANGLE_TRY(ValidateBufferRect(dst, dst_origin, region, dst_row_pitch, dst_slice_pitch));
{
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 // 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. // is not equal to dst_slice_pitch or src_row_pitch is not equal to dst_row_pitch.
...@@ -2235,31 +2458,7 @@ cl_int ValidateCreateImage(cl_context context, ...@@ -2235,31 +2458,7 @@ cl_int ValidateCreateImage(cl_context context,
// image dimensions described in the Device Queries table for all devices in context. // image dimensions described in the Device Queries table for all devices in context.
const DevicePtrs &devices = ctx.getDevices(); const DevicePtrs &devices = ctx.getDevices();
if (std::find_if(devices.cbegin(), devices.cend(), [&](const DevicePtr &ptr) { if (std::find_if(devices.cbegin(), devices.cend(), [&](const DevicePtr &ptr) {
switch (image_desc->image_type) return ptr->supportsNativeImageDimensions(*image_desc);
{
case CL_MEM_OBJECT_IMAGE1D:
return image_desc->image_width <= ptr->getInfo().mImage2D_MaxWidth;
case CL_MEM_OBJECT_IMAGE2D:
return image_desc->image_width <= ptr->getInfo().mImage2D_MaxWidth &&
image_desc->image_height <= ptr->getInfo().mImage2D_MaxHeight;
case CL_MEM_OBJECT_IMAGE3D:
return image_desc->image_width <= ptr->getInfo().mImage3D_MaxWidth &&
image_desc->image_height <= ptr->getInfo().mImage3D_MaxHeight &&
image_desc->image_depth <= ptr->getInfo().mImage3D_MaxDepth;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
return image_desc->image_width <= ptr->getInfo().mImage2D_MaxWidth &&
image_desc->image_array_size <= ptr->getInfo().mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
return image_desc->image_width <= ptr->getInfo().mImage2D_MaxWidth &&
image_desc->image_height <= ptr->getInfo().mImage2D_MaxHeight &&
image_desc->image_array_size <= ptr->getInfo().mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
return image_desc->image_width <= ptr->getInfo().mImageMaxBufferSize;
default:
ASSERT(false);
break;
}
return false;
}) == devices.cend()) }) == devices.cend())
{ {
return CL_INVALID_IMAGE_SIZE; return CL_INVALID_IMAGE_SIZE;
...@@ -2404,23 +2603,15 @@ cl_int ValidateEnqueueFillBuffer(cl_command_queue command_queue, ...@@ -2404,23 +2603,15 @@ 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, ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, false, num_events_in_wait_list,
event_wait_list); event_wait_list));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
const CommandQueue &queue = command_queue->cast<CommandQueue>(); const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 2u)) if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 2u))
{ {
return CL_INVALID_COMMAND_QUEUE; return CL_INVALID_COMMAND_QUEUE;
} }
errorCode = ValidateEnqueueBuffer(queue, buffer, false, false); ANGLE_TRY(ValidateEnqueueBuffer(queue, buffer, false, false));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_VALUE if offset or offset + size require accessing // CL_INVALID_VALUE if offset or offset + size require accessing
// elements outside the buffer object respectively. // elements outside the buffer object respectively.
...@@ -2455,6 +2646,25 @@ cl_int ValidateEnqueueFillImage(cl_command_queue command_queue, ...@@ -2455,6 +2646,25 @@ cl_int ValidateEnqueueFillImage(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)
{ {
ANGLE_TRY(ValidateCommandQueueAndEventWaitList(command_queue, true, num_events_in_wait_list,
event_wait_list));
const CommandQueue &queue = command_queue->cast<CommandQueue>();
if (!queue.getContext().getPlatform().isVersionOrNewer(1u, 2u))
{
return CL_INVALID_COMMAND_QUEUE;
}
ANGLE_TRY(ValidateEnqueueImage(queue, image, false, false));
const Image &img = image->cast<Image>();
ANGLE_TRY(ValidateImageForDevice(img, queue.getDevice(), origin, region));
// CL_INVALID_VALUE if fill_color is NULL.
if (fill_color == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -2834,11 +3044,7 @@ cl_int ValidateCreateBufferWithProperties(cl_context context, ...@@ -2834,11 +3044,7 @@ cl_int ValidateCreateBufferWithProperties(cl_context context,
size_t size, size_t size,
const void *host_ptr) const void *host_ptr)
{ {
const cl_int errorCode = ValidateCreateBuffer(context, flags, size, host_ptr); ANGLE_TRY(ValidateCreateBuffer(context, flags, size, host_ptr));
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_CONTEXT if context is not a valid context. // CL_INVALID_CONTEXT if context is not a valid context.
if (!context->cast<Context>().getPlatform().isVersionOrNewer(3u, 0u)) if (!context->cast<Context>().getPlatform().isVersionOrNewer(3u, 0u))
...@@ -2864,12 +3070,7 @@ cl_int ValidateCreateImageWithProperties(cl_context context, ...@@ -2864,12 +3070,7 @@ cl_int ValidateCreateImageWithProperties(cl_context context,
const cl_image_desc *image_desc, const cl_image_desc *image_desc,
const void *host_ptr) const void *host_ptr)
{ {
const cl_int errorCode = ANGLE_TRY(ValidateCreateImage(context, flags, image_format, image_desc, host_ptr));
ValidateCreateImage(context, flags, image_format, image_desc, host_ptr);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
// CL_INVALID_CONTEXT if context is not a valid context. // CL_INVALID_CONTEXT if context is not a valid context.
if (!context->cast<Context>().getPlatform().isVersionOrNewer(3u, 0u)) if (!context->cast<Context>().getPlatform().isVersionOrNewer(3u, 0u))
......
...@@ -835,8 +835,9 @@ cl_int EnqueueReadImage(cl_command_queue command_queue, ...@@ -835,8 +835,9 @@ cl_int EnqueueReadImage(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(EnqueueReadImage); return command_queue->cast<CommandQueue>().enqueueReadImage(
return 0; image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list,
event_wait_list, event);
} }
cl_int EnqueueWriteImage(cl_command_queue command_queue, cl_int EnqueueWriteImage(cl_command_queue command_queue,
...@@ -851,8 +852,9 @@ cl_int EnqueueWriteImage(cl_command_queue command_queue, ...@@ -851,8 +852,9 @@ cl_int EnqueueWriteImage(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(EnqueueWriteImage); return command_queue->cast<CommandQueue>().enqueueWriteImage(
return 0; image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr,
num_events_in_wait_list, event_wait_list, event);
} }
cl_int EnqueueFillImage(cl_command_queue command_queue, cl_int EnqueueFillImage(cl_command_queue command_queue,
...@@ -864,8 +866,8 @@ cl_int EnqueueFillImage(cl_command_queue command_queue, ...@@ -864,8 +866,8 @@ cl_int EnqueueFillImage(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(EnqueueFillImage); return command_queue->cast<CommandQueue>().enqueueFillImage(
return 0; image, fill_color, origin, region, num_events_in_wait_list, event_wait_list, event);
} }
cl_int EnqueueCopyImage(cl_command_queue command_queue, cl_int EnqueueCopyImage(cl_command_queue command_queue,
...@@ -878,8 +880,9 @@ cl_int EnqueueCopyImage(cl_command_queue command_queue, ...@@ -878,8 +880,9 @@ cl_int EnqueueCopyImage(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(EnqueueCopyImage); return command_queue->cast<CommandQueue>().enqueueCopyImage(
return 0; src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list,
event_wait_list, event);
} }
cl_int EnqueueCopyImageToBuffer(cl_command_queue command_queue, cl_int EnqueueCopyImageToBuffer(cl_command_queue command_queue,
...@@ -892,8 +895,9 @@ cl_int EnqueueCopyImageToBuffer(cl_command_queue command_queue, ...@@ -892,8 +895,9 @@ cl_int EnqueueCopyImageToBuffer(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(EnqueueCopyImageToBuffer); return command_queue->cast<CommandQueue>().enqueueCopyImageToBuffer(
return 0; src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list,
event_wait_list, event);
} }
cl_int EnqueueCopyBufferToImage(cl_command_queue command_queue, cl_int EnqueueCopyBufferToImage(cl_command_queue command_queue,
...@@ -906,8 +910,9 @@ cl_int EnqueueCopyBufferToImage(cl_command_queue command_queue, ...@@ -906,8 +910,9 @@ cl_int EnqueueCopyBufferToImage(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(EnqueueCopyBufferToImage); return command_queue->cast<CommandQueue>().enqueueCopyBufferToImage(
return 0; src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list,
event_wait_list, event);
} }
void *EnqueueMapBuffer(cl_command_queue command_queue, void *EnqueueMapBuffer(cl_command_queue command_queue,
...@@ -939,8 +944,9 @@ void *EnqueueMapImage(cl_command_queue command_queue, ...@@ -939,8 +944,9 @@ void *EnqueueMapImage(cl_command_queue command_queue,
cl_event *event, cl_event *event,
cl_int &errorCode) cl_int &errorCode)
{ {
WARN_NOT_SUPPORTED(EnqueueMapImage); return command_queue->cast<CommandQueue>().enqueueMapImage(
return 0; image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch,
num_events_in_wait_list, event_wait_list, event, errorCode);
} }
cl_int EnqueueUnmapMemObject(cl_command_queue command_queue, cl_int EnqueueUnmapMemObject(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