Commit 2c8d9a9a by John Plate Committed by Angle LUCI CQ

CL: Remaining functions for OpenCL 1.2

Add support for the remaining functions for OpenCL 1.2 for the front end and pass-through back end. Also fix several bugs discovered by the conformance tests. Bug: angleproject:6015 Change-Id: I1dca1c3f4c1d9aea7f0501094c171116ea01381f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2954259Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: John Plate <jplate@google.com>
parent 88631e50
......@@ -29,11 +29,10 @@ using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo,
size_t cb,
void *user_data);
using MemoryCB = void(CL_CALLBACK *)(cl_mem memobj, void *user_data);
using ProgramCB = void(CL_CALLBACK *)(cl_program program, void *user_data);
using EventCB = void(CL_CALLBACK *)(cl_event event, cl_int event_command_status, void *user_data);
using UserFunc = void(CL_CALLBACK *)(void *args);
using EventCB = void(CL_CALLBACK *)(cl_event event, cl_int event_command_status, void *user_data);
using UserFunc = void(CL_CALLBACK *)(void *args);
template <typename T = void>
struct Dispatch
......@@ -80,6 +79,11 @@ struct NativeObject : public Dispatch<>
NativeObjectType *getNative() { return static_cast<NativeObjectType *>(this); }
const NativeObjectType *getNative() const
{
return static_cast<const NativeObjectType *>(this);
}
static NativeObjectType *CastNative(NativeObjectType *p) { return p; }
};
......
......@@ -31,7 +31,7 @@ class Buffer final : public Memory
public:
~Buffer() override;
cl_mem_object_type getType() const final;
MemObjectType getType() const final;
bool isSubBuffer() const;
......@@ -60,12 +60,12 @@ inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
inline bool Buffer::IsValid(const _cl_mem *buffer)
{
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == CL_MEM_OBJECT_BUFFER;
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == MemObjectType::Buffer;
}
inline cl_mem_object_type Buffer::getType() const
inline MemObjectType Buffer::getType() const
{
return CL_MEM_OBJECT_BUFFER;
return MemObjectType::Buffer;
}
inline bool Buffer::isSubBuffer() const
......
......@@ -131,12 +131,17 @@ cl_mem Context::createImage(const cl_mem_properties *properties,
void *hostPtr,
cl_int &errorCode)
{
const ImageDescriptor imageDesc = {
desc->image_type, desc->image_width, desc->image_height,
desc->image_depth, desc->image_array_size, desc->image_row_pitch,
desc->image_slice_pitch, desc->num_mip_levels, desc->num_samples};
const ImageDescriptor imageDesc = {FromCLenum<MemObjectType>(desc->image_type),
desc->image_width,
desc->image_height,
desc->image_depth,
desc->image_array_size,
desc->image_row_pitch,
desc->image_slice_pitch,
desc->num_mip_levels,
desc->num_samples};
return Object::Create<Image>(errorCode, *this, Memory::PropArray{}, flags, *format, imageDesc,
&desc->buffer->cast<Memory>(), hostPtr);
Memory::Cast(desc->buffer), hostPtr);
}
cl_mem Context::createImage2D(MemFlags flags,
......@@ -148,7 +153,7 @@ cl_mem Context::createImage2D(MemFlags flags,
cl_int &errorCode)
{
const ImageDescriptor imageDesc = {
CL_MEM_OBJECT_IMAGE2D, width, height, 0u, 0u, rowPitch, 0u, 0u, 0u};
MemObjectType::Image2D, width, height, 0u, 0u, rowPitch, 0u, 0u, 0u};
return Object::Create<Image>(errorCode, *this, Memory::PropArray{}, flags, *format, imageDesc,
nullptr, hostPtr);
}
......@@ -164,11 +169,21 @@ cl_mem Context::createImage3D(MemFlags flags,
cl_int &errorCode)
{
const ImageDescriptor imageDesc = {
CL_MEM_OBJECT_IMAGE3D, width, height, depth, 0u, rowPitch, slicePitch, 0u, 0u};
MemObjectType::Image3D, width, height, depth, 0u, rowPitch, slicePitch, 0u, 0u};
return Object::Create<Image>(errorCode, *this, Memory::PropArray{}, flags, *format, imageDesc,
nullptr, hostPtr);
}
cl_int Context::getSupportedImageFormats(MemFlags flags,
MemObjectType imageType,
cl_uint numEntries,
cl_image_format *imageFormats,
cl_uint *numImageFormats)
{
return mImpl->getSupportedImageFormats(flags, imageType, numEntries, imageFormats,
numImageFormats);
}
cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *properties,
cl_int &errorCode)
{
......
......@@ -62,6 +62,12 @@ class Context final : public _cl_context, public Object
void *hostPtr,
cl_int &errorCode);
cl_int getSupportedImageFormats(MemFlags flags,
MemObjectType imageType,
cl_uint numEntries,
cl_image_format *imageFormats,
cl_uint *numImageFormats);
cl_sampler createSamplerWithProperties(const cl_sampler_properties *properties,
cl_int &errorCode);
......
......@@ -285,7 +285,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copySize = sizeof(valPointer);
break;
case DeviceInfo::ParentDevice:
valPointer = mParent->getNative();
valPointer = Device::CastNative(mParent.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
......@@ -388,25 +388,25 @@ bool Device::supportsBuiltInKernel(const std::string &name) const
bool Device::supportsNativeImageDimensions(const cl_image_desc &desc) const
{
switch (desc.image_type)
switch (FromCLenum<MemObjectType>(desc.image_type))
{
case CL_MEM_OBJECT_IMAGE1D:
case MemObjectType::Image1D:
return desc.image_width <= mInfo.mImage2D_MaxWidth;
case CL_MEM_OBJECT_IMAGE2D:
case MemObjectType::Image2D:
return desc.image_width <= mInfo.mImage2D_MaxWidth &&
desc.image_height <= mInfo.mImage2D_MaxHeight;
case CL_MEM_OBJECT_IMAGE3D:
case MemObjectType::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:
case MemObjectType::Image1D_Array:
return desc.image_width <= mInfo.mImage2D_MaxWidth &&
desc.image_array_size <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case MemObjectType::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:
case MemObjectType::Image1D_Buffer:
return desc.image_width <= mInfo.mImageMaxBufferSize;
default:
ASSERT(false);
......@@ -419,21 +419,21 @@ bool Device::supportsImageDimensions(const ImageDescriptor &desc) const
{
switch (desc.type)
{
case CL_MEM_OBJECT_IMAGE1D:
case MemObjectType::Image1D:
return desc.width <= mInfo.mImage2D_MaxWidth;
case CL_MEM_OBJECT_IMAGE2D:
case MemObjectType::Image2D:
return desc.width <= mInfo.mImage2D_MaxWidth && desc.height <= mInfo.mImage2D_MaxHeight;
case CL_MEM_OBJECT_IMAGE3D:
case MemObjectType::Image3D:
return desc.width <= mInfo.mImage3D_MaxWidth &&
desc.height <= mInfo.mImage3D_MaxHeight && desc.depth <= mInfo.mImage3D_MaxDepth;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case MemObjectType::Image1D_Array:
return desc.width <= mInfo.mImage2D_MaxWidth &&
desc.arraySize <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case MemObjectType::Image2D_Array:
return desc.width <= mInfo.mImage2D_MaxWidth &&
desc.height <= mInfo.mImage2D_MaxHeight &&
desc.arraySize <= mInfo.mImageMaxArraySize;
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
case MemObjectType::Image1D_Buffer:
return desc.width <= mInfo.mImageMaxBufferSize;
default:
ASSERT(false);
......
......@@ -106,6 +106,14 @@ cl_int Event::setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, voi
return CL_SUCCESS;
}
cl_int Event::getProfilingInfo(ProfilingInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet)
{
return mImpl->getProfilingInfo(name, valueSize, value, valueSizeRet);
}
Event::~Event() = default;
void Event::callback(cl_int commandStatus)
......
......@@ -28,6 +28,11 @@ class Event final : public _cl_event, public Object
cl_int setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData);
cl_int getProfilingInfo(ProfilingInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet);
public:
~Event() override;
......
......@@ -93,20 +93,16 @@ cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *val
return CL_SUCCESS;
}
bool Image::IsValid(const _cl_mem *image)
bool Image::IsTypeValid(MemObjectType imageType)
{
if (!Memory::IsValid(image))
switch (imageType)
{
return false;
}
switch (image->cast<Memory>().getType())
{
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE2D:
case CL_MEM_OBJECT_IMAGE3D:
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
case MemObjectType::Image1D:
case MemObjectType::Image2D:
case MemObjectType::Image3D:
case MemObjectType::Image1D_Array:
case MemObjectType::Image2D_Array:
case MemObjectType::Image1D_Buffer:
break;
default:
return false;
......@@ -120,17 +116,17 @@ 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:
case MemObjectType::Image1D:
case MemObjectType::Image1D_Buffer:
return origin[0] + region[0] <= mDesc.width;
case CL_MEM_OBJECT_IMAGE2D:
case MemObjectType::Image2D:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.height;
case CL_MEM_OBJECT_IMAGE3D:
case MemObjectType::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:
case MemObjectType::Image1D_Array:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.arraySize;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case MemObjectType::Image2D_Array:
return origin[0] + region[0] <= mDesc.width && origin[1] + region[1] <= mDesc.height &&
origin[2] + region[2] <= mDesc.arraySize;
default:
......
......@@ -22,12 +22,13 @@ class Image final : public Memory
cl_int getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
static bool IsTypeValid(MemObjectType imageType);
static bool IsValid(const _cl_mem *image);
public:
~Image() override;
cl_mem_object_type getType() const final;
MemObjectType getType() const final;
const cl_image_format &getFormat() const;
const ImageDescriptor &getDescriptor() const;
......@@ -54,7 +55,12 @@ class Image final : public Memory
friend class Object;
};
inline cl_mem_object_type Image::getType() const
inline bool Image::IsValid(const _cl_mem *image)
{
return Memory::IsValid(image) && IsTypeValid(image->cast<Memory>().getType());
}
inline MemObjectType Image::getType() const
{
return mDesc.type;
}
......
......@@ -15,6 +15,11 @@
namespace cl
{
cl_int Kernel::setArg(cl_uint argIndex, size_t argSize, const void *argValue)
{
return mImpl->setArg(argIndex, argSize, argValue);
}
cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
cl_uint valUInt = 0u;
......
......@@ -19,6 +19,8 @@ class Kernel final : public _cl_kernel, public Object
public:
// Front end entry functions, only called from OpenCL entry points
cl_int setArg(cl_uint argIndex, size_t argSize, const void *argValue);
cl_int getInfo(KernelInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_int getWorkGroupInfo(cl_device_id device,
......
......@@ -15,6 +15,12 @@
namespace cl
{
cl_int Memory::setDestructorCallback(MemoryCB pfnNotify, void *userData)
{
mDestructorCallbacks.emplace(pfnNotify, userData);
return CL_SUCCESS;
}
cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
static_assert(
......@@ -29,7 +35,7 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu
switch (name)
{
case MemInfo::Type:
valUInt = getType();
valUInt = ToCLenum(getType());
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
......@@ -101,7 +107,16 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu
return CL_SUCCESS;
}
Memory::~Memory() = default;
Memory::~Memory()
{
while (!mDestructorCallbacks.empty())
{
const MemoryCB callback = mDestructorCallbacks.top().first;
void *const userData = mDestructorCallbacks.top().second;
mDestructorCallbacks.pop();
callback(this, userData);
}
}
MemFlags Memory::getEffectiveFlags() const
{
......
......@@ -12,6 +12,8 @@
#include "libANGLE/CLObject.h"
#include "libANGLE/renderer/CLMemoryImpl.h"
#include <stack>
namespace cl
{
......@@ -20,6 +22,8 @@ class Memory : public _cl_mem, public Object
public:
// Front end entry functions, only called from OpenCL entry points
cl_int setDestructorCallback(MemoryCB pfnNotify, void *userData);
cl_int getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
public:
......@@ -27,7 +31,7 @@ class Memory : public _cl_mem, public Object
~Memory() override;
virtual cl_mem_object_type getType() const = 0;
virtual MemObjectType getType() const = 0;
const Context &getContext() const;
const PropArray &getProperties() const;
......@@ -42,7 +46,11 @@ class Memory : public _cl_mem, public Object
MemFlags getEffectiveFlags() const;
static Memory *Cast(cl_mem memobj);
protected:
using CallbackData = std::pair<MemoryCB, void *>;
Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
......@@ -77,6 +85,7 @@ class Memory : public _cl_mem, public Object
const rx::CLMemoryImpl::Ptr mImpl;
const size_t mSize;
std::stack<CallbackData> mDestructorCallbacks;
cl_uint mMapCount = 0u;
friend class Buffer;
......@@ -124,6 +133,11 @@ inline T &Memory::getImpl() const
return static_cast<T &>(*mImpl);
}
inline Memory *Memory::Cast(cl_mem memobj)
{
return static_cast<Memory *>(memobj);
}
} // namespace cl
#endif // LIBANGLE_CLMEMORY_H_
......@@ -70,16 +70,7 @@ void Platform::Initialize(const cl_icd_dispatch &dispatch,
ERR() << "Already initialized";
return;
}
_cl_platform_id::sDispatch = &dispatch;
_cl_device_id::sDispatch = &dispatch;
_cl_context::sDispatch = &dispatch;
_cl_command_queue::sDispatch = &dispatch;
_cl_mem::sDispatch = &dispatch;
_cl_program::sDispatch = &dispatch;
_cl_kernel::sDispatch = &dispatch;
_cl_event::sDispatch = &dispatch;
_cl_sampler::sDispatch = &dispatch;
Dispatch::sDispatch = &dispatch;
platforms.reserve(createFuncs.size());
while (!createFuncs.empty())
......
......@@ -17,6 +17,7 @@
// Include frequently used standard headers
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <memory>
......@@ -61,7 +62,7 @@ using ProgramPtrs = std::vector<ProgramPtr>;
struct ImageDescriptor
{
cl_mem_object_type type;
MemObjectType type;
size_t width;
size_t height;
size_t depth;
......
......@@ -41,6 +41,12 @@ class CLContextImpl : angle::NonCopyable
void *hostPtr,
cl_int &errorCode) = 0;
virtual cl_int getSupportedImageFormats(cl::MemFlags flags,
cl::MemObjectType imageType,
cl_uint numEntries,
cl_image_format *imageFormats,
cl_uint *numImageFormats) = 0;
virtual CLSamplerImpl::Ptr createSampler(const cl::Sampler &sampler, cl_int &errorCode) = 0;
virtual CLProgramImpl::Ptr createProgramWithSource(const cl::Program &program,
......
......@@ -28,6 +28,11 @@ class CLEventImpl : angle::NonCopyable
virtual cl_int setCallback(cl::Event &event, cl_int commandExecCallbackType) = 0;
virtual cl_int getProfilingInfo(cl::ProfilingInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) = 0;
protected:
const cl::Event &mEvent;
};
......
......@@ -31,12 +31,12 @@ class CLKernelImpl : angle::NonCopyable
WorkGroupInfo(WorkGroupInfo &&);
WorkGroupInfo &operator=(WorkGroupInfo &&);
size_t mGlobalWorkSize[3] = {};
size_t mWorkGroupSize = 0u;
size_t mCompileWorkGroupSize[3] = {};
cl_ulong mLocalMemSize = 0u;
size_t mPrefWorkGroupSizeMultiple = 0u;
cl_ulong mPrivateMemSize = 0u;
std::array<size_t, 3u> mGlobalWorkSize = {};
size_t mWorkGroupSize = 0u;
std::array<size_t, 3u> mCompileWorkGroupSize = {};
cl_ulong mLocalMemSize = 0u;
size_t mPrefWorkGroupSizeMultiple = 0u;
cl_ulong mPrivateMemSize = 0u;
};
struct ArgInfo
......@@ -83,6 +83,8 @@ class CLKernelImpl : angle::NonCopyable
CLKernelImpl(const cl::Kernel &kernel);
virtual ~CLKernelImpl();
virtual cl_int setArg(cl_uint argIndex, size_t argSize, const void *argValue) = 0;
virtual Info createInfo(cl_int &errorCode) const = 0;
protected:
......
......@@ -7,11 +7,14 @@
#include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/renderer/cl/CLEventCL.h"
#include "libANGLE/renderer/cl/CLKernelCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLImage.h"
#include "libANGLE/CLKernel.h"
#include "libANGLE/CLMemory.h"
......@@ -36,10 +39,24 @@ void CheckCreateEvent(cl_int errorCode, cl_event nativeEvent, CLEventImpl::Creat
CLCommandQueueCL::CLCommandQueueCL(const cl::CommandQueue &commandQueue, cl_command_queue native)
: CLCommandQueueImpl(commandQueue), mNative(native)
{}
{
if (commandQueue.getProperties().isSet(CL_QUEUE_ON_DEVICE))
{
commandQueue.getContext().getImpl<CLContextCL>().mDeviceQueues.emplace(
commandQueue.getNative());
}
}
CLCommandQueueCL::~CLCommandQueueCL()
{
if (mCommandQueue.getProperties().isSet(CL_QUEUE_ON_DEVICE))
{
const size_t numRemoved =
mCommandQueue.getContext().getImpl<CLContextCL>().mDeviceQueues.erase(
mCommandQueue.getNative());
ASSERT(numRemoved == 1u);
}
if (mNative->getDispatch().clReleaseCommandQueue(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL command-queue";
......
......@@ -20,6 +20,8 @@ class CLCommandQueueCL : public CLCommandQueueImpl
CLCommandQueueCL(const cl::CommandQueue &commandQueue, cl_command_queue native);
~CLCommandQueueCL() override;
cl_command_queue getNative() const;
cl_int setProperty(cl::CommandQueueProperties properties, cl_bool enable) override;
cl_int enqueueReadBuffer(const cl::Buffer &buffer,
......@@ -212,6 +214,11 @@ class CLCommandQueueCL : public CLCommandQueueImpl
const cl_command_queue mNative;
};
inline cl_command_queue CLCommandQueueCL::getNative() const
{
return mNative;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLCOMMANDQUEUECL_H_
......@@ -135,12 +135,12 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
if (mContext.getPlatform().isVersionOrNewer(1u, 2u))
{
const cl_mem_object_type nativeType = cl::ToCLenum(desc.type);
const cl_mem nativeParent =
image.getParent() ? image.getParent()->getImpl<CLMemoryCL>().getNative() : nullptr;
const cl_image_desc nativeDesc = {
desc.type, desc.width,
desc.height, desc.depth,
desc.arraySize, desc.rowPitch,
desc.slicePitch, desc.numMipLevels,
desc.numSamples, {cl::Memory::CastNative(image.getParent().get())}};
nativeType, desc.width, desc.height, desc.depth, desc.arraySize,
desc.rowPitch, desc.slicePitch, desc.numMipLevels, desc.numSamples, {nativeParent}};
if (image.getProperties().empty())
{
......@@ -158,12 +158,12 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
{
switch (desc.type)
{
case CL_MEM_OBJECT_IMAGE2D:
case cl::MemObjectType::Image2D:
nativeImage = mNative->getDispatch().clCreateImage2D(
mNative, image.getFlags().get(), &format, desc.width, desc.height,
desc.rowPitch, hostPtr, &errorCode);
break;
case CL_MEM_OBJECT_IMAGE3D:
case cl::MemObjectType::Image3D:
nativeImage = mNative->getDispatch().clCreateImage3D(
mNative, image.getFlags().get(), &format, desc.width, desc.height, desc.depth,
desc.rowPitch, desc.slicePitch, hostPtr, &errorCode);
......@@ -178,6 +178,16 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
return CLMemoryImpl::Ptr(nativeImage != nullptr ? new CLMemoryCL(image, nativeImage) : nullptr);
}
cl_int CLContextCL::getSupportedImageFormats(cl::MemFlags flags,
cl::MemObjectType imageType,
cl_uint numEntries,
cl_image_format *imageFormats,
cl_uint *numImageFormats)
{
return mNative->getDispatch().clGetSupportedImageFormats(
mNative, flags.get(), cl::ToCLenum(imageType), numEntries, imageFormats, numImageFormats);
}
CLSamplerImpl::Ptr CLContextCL::createSampler(const cl::Sampler &sampler, cl_int &errorCode)
{
cl_sampler nativeSampler = nullptr;
......
......@@ -8,8 +8,12 @@
#ifndef LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_
#define LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLContextImpl.h"
#include <unordered_set>
namespace rx
{
......@@ -19,6 +23,10 @@ class CLContextCL : public CLContextImpl
CLContextCL(const cl::Context &context, cl_context native);
~CLContextCL() override;
bool hasMemory(cl_mem memory) const;
bool hasSampler(cl_sampler sampler) const;
bool hasDeviceQueue(cl_command_queue queue) const;
cl::DevicePtrs getDevices(cl_int &errorCode) const override;
CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue,
......@@ -35,6 +43,12 @@ class CLContextCL : public CLContextImpl
void *hostPtr,
cl_int &errorCode) override;
cl_int getSupportedImageFormats(cl::MemFlags flags,
cl::MemObjectType imageType,
cl_uint numEntries,
cl_image_format *imageFormats,
cl_uint *numImageFormats) override;
CLSamplerImpl::Ptr createSampler(const cl::Sampler &sampler, cl_int &errorCode) override;
CLProgramImpl::Ptr createProgramWithSource(const cl::Program &program,
......@@ -69,8 +83,31 @@ class CLContextCL : public CLContextImpl
private:
const cl_context mNative;
std::unordered_set<const _cl_mem *> mMemories;
std::unordered_set<const _cl_sampler *> mSamplers;
std::unordered_set<const _cl_command_queue *> mDeviceQueues;
friend class CLCommandQueueCL;
friend class CLMemoryCL;
friend class CLSamplerCL;
};
inline bool CLContextCL::hasMemory(cl_mem memory) const
{
return mMemories.find(memory) != mMemories.cend();
}
inline bool CLContextCL::hasSampler(cl_sampler sampler) const
{
return mSamplers.find(sampler) != mSamplers.cend();
}
inline bool CLContextCL::hasDeviceQueue(cl_command_queue queue) const
{
return mDeviceQueues.find(queue) != mDeviceQueues.cend();
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_
......@@ -101,6 +101,14 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
return Info{};
}
info.mVersionStr.assign(valString.data());
// Limit version number to supported version
if (info.mVersionStr[7] != '1')
{
info.mVersionStr[7] = '1';
info.mVersionStr[9] = '2';
}
info.mVersion = ExtractCLVersion(info.mVersionStr);
if (info.mVersion == 0u)
{
......
......@@ -41,6 +41,15 @@ cl_int CLEventCL::setCallback(cl::Event &event, cl_int commandExecCallbackType)
&event);
}
cl_int CLEventCL::getProfilingInfo(cl::ProfilingInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet)
{
return mNative->getDispatch().clGetEventProfilingInfo(mNative, cl::ToCLenum(name), valueSize,
value, valueSizeRet);
}
std::vector<cl_event> CLEventCL::Cast(const cl::EventPtrs &events)
{
std::vector<cl_event> nativeEvents;
......
......@@ -29,6 +29,11 @@ class CLEventCL : public CLEventImpl
cl_int setCallback(cl::Event &event, cl_int commandExecCallbackType) override;
cl_int getProfilingInfo(cl::ProfilingInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) override;
static std::vector<cl_event> Cast(const cl::EventPtrs &events);
private:
......
......@@ -7,13 +7,19 @@
#include "libANGLE/renderer/cl/CLKernelCL.h"
#include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/renderer/cl/CLSamplerCL.h"
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLKernel.h"
#include "libANGLE/CLMemory.h"
#include "libANGLE/CLPlatform.h"
#include "libANGLE/CLProgram.h"
#include "libANGLE/Debug.h"
#include "libANGLE/CLSampler.h"
namespace rx
{
......@@ -42,7 +48,11 @@ bool GetArgInfo(cl_kernel kernel,
{
errorCode = kernel->getDispatch().clGetKernelArgInfo(kernel, index, cl::ToCLenum(name),
sizeof(T), &value, nullptr);
return errorCode == CL_SUCCESS || errorCode == CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
if (errorCode == CL_KERNEL_ARG_INFO_NOT_AVAILABLE)
{
errorCode = CL_SUCCESS;
}
return errorCode == CL_SUCCESS;
}
template <typename T>
......@@ -64,6 +74,7 @@ bool GetArgString(cl_kernel kernel,
nullptr, &size);
if (errorCode == CL_KERNEL_ARG_INFO_NOT_AVAILABLE)
{
errorCode = CL_SUCCESS;
return true;
}
else if (errorCode != CL_SUCCESS)
......@@ -115,6 +126,47 @@ CLKernelCL::~CLKernelCL()
}
}
cl_int CLKernelCL::setArg(cl_uint argIndex, size_t argSize, const void *argValue)
{
void *value = nullptr;
if (argValue != nullptr)
{
// If argument is a CL object, fetch the mapped value
const CLContextCL &ctx = mKernel.getProgram().getContext().getImpl<CLContextCL>();
if (argSize == sizeof(cl_mem))
{
cl_mem memory = *static_cast<const cl_mem *>(argValue);
if (ctx.hasMemory(memory))
{
value = memory->cast<cl::Memory>().getImpl<CLMemoryCL>().getNative();
}
}
if (value == nullptr && argSize == sizeof(cl_sampler))
{
cl_sampler sampler = *static_cast<const cl_sampler *>(argValue);
if (ctx.hasSampler(sampler))
{
value = sampler->cast<cl::Sampler>().getImpl<CLSamplerCL>().getNative();
}
}
if (value == nullptr && argSize == sizeof(cl_command_queue))
{
cl_command_queue queue = *static_cast<const cl_command_queue *>(argValue);
if (ctx.hasDeviceQueue(queue))
{
value = queue->cast<cl::CommandQueue>().getImpl<CLCommandQueueCL>().getNative();
}
}
}
// If mapped value was found, use it instead of original value
if (value != nullptr)
{
argValue = &value;
}
return mNative->getDispatch().clSetKernelArg(mNative, argIndex, argSize, argValue);
}
CLKernelImpl::Info CLKernelCL::createInfo(cl_int &errorCode) const
{
const cl::Context &ctx = mKernel.getProgram().getContext();
......@@ -133,7 +185,9 @@ CLKernelImpl::Info CLKernelCL::createInfo(cl_int &errorCode) const
{
const cl_device_id device = ctx.getDevices()[index]->getImpl<CLDeviceCL>().getNative();
WorkGroupInfo &workGroup = info.mWorkGroups[index];
if ((ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
ctx.getDevices()[index]->supportsBuiltInKernel(info.mFunctionName) &&
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::GlobalWorkSize,
workGroup.mGlobalWorkSize, errorCode)) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::WorkGroupSize,
......
......@@ -23,6 +23,8 @@ class CLKernelCL : public CLKernelImpl
cl_kernel getNative() const;
cl_int setArg(cl_uint argIndex, size_t argSize, const void *argValue) override;
Info createInfo(cl_int &errorCode) const override;
private:
......
......@@ -7,17 +7,26 @@
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLContext.h"
namespace rx
{
CLMemoryCL::CLMemoryCL(const cl::Memory &memory, cl_mem native)
: CLMemoryImpl(memory), mNative(native)
{}
{
memory.getContext().getImpl<CLContextCL>().mMemories.emplace(memory.getNative());
}
CLMemoryCL::~CLMemoryCL()
{
const size_t numRemoved =
mMemory.getContext().getImpl<CLContextCL>().mMemories.erase(mMemory.getNative());
ASSERT(numRemoved == 1u);
if (mNative->getDispatch().clReleaseMemObject(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL memory object";
......
......@@ -129,6 +129,13 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
info.mName = GetPlatformString(mNative, cl::PlatformInfo::Name);
info.mExtensions = GetPlatformString(mNative, cl::PlatformInfo::Extensions);
// Limit version number to supported version
if (info.mVersionStr[7] != '1')
{
info.mVersionStr[7] = '1';
info.mVersionStr[9] = '2';
}
if (vendor.empty() || info.mProfile.empty() || info.mVersionStr.empty() || info.mName.empty() ||
info.mExtensions.empty())
{
......
......@@ -134,7 +134,7 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels,
std::vector<cl_kernel> nativeKernels(numKernels, nullptr);
const cl_int errorCode = mNative->getDispatch().clCreateKernelsInProgram(
mNative, numKernels, nativeKernels.data(), nullptr);
mNative, numKernels, nativeKernels.data(), numKernelsRet);
if (errorCode == CL_SUCCESS)
{
for (cl_kernel nativeKernel : nativeKernels)
......
......@@ -7,17 +7,26 @@
#include "libANGLE/renderer/cl/CLSamplerCL.h"
#include "libANGLE/Debug.h"
#include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLSampler.h"
namespace rx
{
CLSamplerCL::CLSamplerCL(const cl::Sampler &sampler, cl_sampler native)
: CLSamplerImpl(sampler), mNative(native)
{}
{
sampler.getContext().getImpl<CLContextCL>().mSamplers.emplace(sampler.getNative());
}
CLSamplerCL::~CLSamplerCL()
{
const size_t numRemoved =
mSampler.getContext().getImpl<CLContextCL>().mSamplers.erase(mSampler.getNative());
ASSERT(numRemoved == 1u);
if (mNative->getDispatch().clReleaseSampler(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL sampler";
......
......@@ -21,10 +21,17 @@ class CLSamplerCL : public CLSamplerImpl
CLSamplerCL(const cl::Sampler &sampler, cl_sampler native);
~CLSamplerCL() override;
cl_sampler getNative() const;
private:
const cl_sampler mNative;
};
inline cl_sampler CLSamplerCL::getNative() const
{
return mNative;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLSAMPLERCL_H_
......@@ -13,9 +13,15 @@
namespace rx
{
class CLCommandQueueCL;
class CLContextCL;
class CLDeviceCL;
class CLEventCL;
class CLKernelCL;
class CLMemoryCL;
class CLPlatformCL;
class CLProgramCL;
class CLSamplerCL;
} // namespace rx
......
......@@ -493,8 +493,8 @@ cl_int ValidateImageForDevice(const Image &image,
{
// 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:
case MemObjectType::Image1D:
case MemObjectType::Image1D_Buffer:
if (origin[1] != 0u || origin[2] != 0u || region[1] != 1u || region[2] != 1u)
{
return CL_INVALID_VALUE;
......@@ -502,15 +502,15 @@ cl_int ValidateImageForDevice(const Image &image,
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:
case MemObjectType::Image2D:
case MemObjectType::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:
case MemObjectType::Image3D:
case MemObjectType::Image2D_Array:
break;
default:
ASSERT(false);
......@@ -535,6 +535,7 @@ cl_int ValidateImageForDevice(const Image &image,
}
cl_int ValidateHostRegionForImage(const Image &image,
const size_t region[3],
size_t rowPitch,
size_t slicePitch,
const void *ptr)
......@@ -542,23 +543,23 @@ cl_int ValidateHostRegionForImage(const Image &image,
// 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();
rowPitch = image.getElementSize() * region[0];
}
else if (rowPitch < image.getRowSize())
else if (rowPitch < image.getElementSize() * region[0])
{
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)
if (image.getType() == MemObjectType::Image1D ||
image.getType() == MemObjectType::Image1D_Buffer ||
image.getType() == MemObjectType::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)
if (slicePitch < rowPitch * region[1])
{
return CL_INVALID_VALUE;
}
......@@ -958,6 +959,24 @@ cl_int ValidateGetSupportedImageFormats(cl_context context,
const cl_image_format *image_formats,
const cl_uint *num_image_formats)
{
// CL_INVALID_CONTEXT if context is not a valid context.
if (!Context::IsValid(context))
{
return CL_INVALID_CONTEXT;
}
const Context &ctx = context->cast<Context>();
// CL_INVALID_VALUE if flags or image_type are not valid,
if (!ValidateMemoryFlags(flags, ctx.getPlatform()) || !Image::IsTypeValid(image_type))
{
return CL_INVALID_VALUE;
}
// or if num_entries is 0 and image_formats is not NULL.
if (num_entries == 0u && image_formats != nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -1327,6 +1346,97 @@ cl_int ValidateSetKernelArg(cl_kernel kernel,
size_t arg_size,
const void *arg_value)
{
// CL_INVALID_KERNEL if kernel is not a valid kernel object.
if (!Kernel::IsValid(kernel))
{
return CL_INVALID_KERNEL;
}
const Kernel &krnl = kernel->cast<Kernel>();
// CL_INVALID_ARG_INDEX if arg_index is not a valid argument index.
if (arg_index >= krnl.getInfo().mArgs.size())
{
return CL_INVALID_ARG_INDEX;
}
if (arg_size == sizeof(cl_mem) && arg_value != nullptr)
{
const std::string &typeName = krnl.getInfo().mArgs[arg_index].mTypeName;
// CL_INVALID_MEM_OBJECT for an argument declared to be a memory object
// when the specified arg_value is not a valid memory object.
if (typeName == "image1d_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) || image->cast<Image>().getType() != MemObjectType::Image1D)
{
return CL_INVALID_MEM_OBJECT;
}
}
else if (typeName == "image2d_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) || image->cast<Image>().getType() != MemObjectType::Image2D)
{
return CL_INVALID_MEM_OBJECT;
}
}
else if (typeName == "image3d_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) || image->cast<Image>().getType() != MemObjectType::Image3D)
{
return CL_INVALID_MEM_OBJECT;
}
}
else if (typeName == "image1d_array_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) ||
image->cast<Image>().getType() != MemObjectType::Image1D_Array)
{
return CL_INVALID_MEM_OBJECT;
}
}
else if (typeName == "image2d_array_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) ||
image->cast<Image>().getType() != MemObjectType::Image2D_Array)
{
return CL_INVALID_MEM_OBJECT;
}
}
else if (typeName == "image1d_buffer_t")
{
const cl_mem image = *static_cast<const cl_mem *>(arg_value);
if (!Image::IsValid(image) ||
image->cast<Image>().getType() != MemObjectType::Image1D_Buffer)
{
return CL_INVALID_MEM_OBJECT;
}
}
// CL_INVALID_SAMPLER for an argument declared to be of type sampler_t
// when the specified arg_value is not a valid sampler object.
else if (typeName == "sampler_t")
{
if (!Sampler::IsValid(*static_cast<const cl_sampler *>(arg_value)))
{
return CL_INVALID_SAMPLER;
}
}
// CL_INVALID_DEVICE_QUEUE for an argument declared to be of type queue_t
// when the specified arg_value is not a valid device queue object.
else if (typeName == "queue_t")
{
const cl_command_queue queue = *static_cast<const cl_command_queue *>(arg_value);
if (!CommandQueue::IsValid(queue) || !queue->cast<CommandQueue>().isOnDevice())
{
return CL_INVALID_DEVICE_QUEUE;
}
}
}
return CL_SUCCESS;
}
......@@ -1502,6 +1612,39 @@ cl_int ValidateGetEventProfilingInfo(cl_event event,
const void *param_value,
const size_t *param_value_size_ret)
{
// CL_INVALID_EVENT if event is a not a valid event object.
if (!Event::IsValid(event))
{
return CL_INVALID_EVENT;
}
const Event &evt = event->cast<Event>();
// CL_PROFILING_INFO_NOT_AVAILABLE
// if the CL_QUEUE_PROFILING_ENABLE flag is not set for the command-queue,
if (evt.getCommandQueue()->getProperties().isNotSet(CL_QUEUE_PROFILING_ENABLE))
{
return CL_PROFILING_INFO_NOT_AVAILABLE;
}
// or if event is a user event object.
if (evt.getCommandType() == CL_COMMAND_USER)
{
return CL_PROFILING_INFO_NOT_AVAILABLE;
}
// CL_INVALID_VALUE if param_name is not valid.
const cl_version version = evt.getContext().getPlatform().getVersion();
switch (param_name)
{
case ProfilingInfo::CommandComplete:
ANGLE_VALIDATE_VERSION(version, 2, 0);
break;
case ProfilingInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
return CL_SUCCESS;
}
......@@ -1639,7 +1782,7 @@ cl_int ValidateEnqueueReadImage(cl_command_queue command_queue,
const Image &img = image->cast<Image>();
ANGLE_TRY(ValidateImageForDevice(img, queue.getDevice(), origin, region));
ANGLE_TRY(ValidateHostRegionForImage(img, row_pitch, slice_pitch, ptr));
ANGLE_TRY(ValidateHostRegionForImage(img, region, row_pitch, slice_pitch, ptr));
return CL_SUCCESS;
}
......@@ -1664,7 +1807,7 @@ cl_int ValidateEnqueueWriteImage(cl_command_queue command_queue,
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));
ANGLE_TRY(ValidateHostRegionForImage(img, region, input_row_pitch, input_slice_pitch, ptr));
return CL_SUCCESS;
}
......@@ -1703,11 +1846,11 @@ cl_int ValidateEnqueueCopyImage(cl_command_queue command_queue,
// and the source and destination regions overlap.
if (&src == &dst)
{
const cl_mem_object_type type = src.getType();
const MemObjectType 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)
if (type == MemObjectType::Image1D || type == MemObjectType::Image1D_Buffer)
{
return CL_MEM_COPY_OVERLAP;
}
......@@ -1715,7 +1858,7 @@ cl_int ValidateEnqueueCopyImage(cl_command_queue command_queue,
// 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)
if (type == MemObjectType::Image2D || type == MemObjectType::Image1D_Array)
{
return CL_MEM_COPY_OVERLAP;
}
......@@ -1753,7 +1896,7 @@ cl_int ValidateEnqueueCopyImageToBuffer(cl_command_queue command_queue,
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() == &dst)
if (src.getType() == MemObjectType::Image1D_Buffer && src.getParent() == &dst)
{
return CL_INVALID_MEM_OBJECT;
}
......@@ -1762,12 +1905,12 @@ cl_int ValidateEnqueueCopyImageToBuffer(cl_command_queue command_queue,
// 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)
const MemObjectType type = src.getType();
size_t dst_cb = src.getElementSize() * region[0];
if (type != MemObjectType::Image1D && type != MemObjectType::Image1D_Buffer)
{
dst_cb *= region[1];
if (type != CL_MEM_OBJECT_IMAGE2D && type != CL_MEM_OBJECT_IMAGE1D_ARRAY)
if (type != MemObjectType::Image2D && type != MemObjectType::Image1D_Array)
{
dst_cb *= region[2];
}
......@@ -1801,7 +1944,7 @@ cl_int ValidateEnqueueCopyBufferToImage(cl_command_queue command_queue,
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() == &src)
if (dst.getType() == MemObjectType::Image1D_Buffer && dst.getParent() == &src)
{
return CL_INVALID_MEM_OBJECT;
}
......@@ -1810,12 +1953,12 @@ cl_int ValidateEnqueueCopyBufferToImage(cl_command_queue command_queue,
// 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)
const MemObjectType type = dst.getType();
size_t src_cb = dst.getElementSize() * region[0];
if (type != MemObjectType::Image1D && type != MemObjectType::Image1D_Buffer)
{
src_cb *= region[1];
if (type != CL_MEM_OBJECT_IMAGE2D && type != CL_MEM_OBJECT_IMAGE1D_ARRAY)
if (type != MemObjectType::Image2D && type != MemObjectType::Image1D_Array)
{
src_cb *= region[2];
}
......@@ -1901,8 +2044,8 @@ cl_int ValidateEnqueueMapImage(cl_command_queue command_queue,
// 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) &&
if ((img.getType() == MemObjectType::Image3D || img.getType() == MemObjectType::Image1D_Array ||
img.getType() == MemObjectType::Image2D_Array) &&
image_slice_pitch == nullptr)
{
return CL_INVALID_VALUE;
......@@ -1928,7 +2071,7 @@ cl_int ValidateEnqueueUnmapMemObject(cl_command_queue command_queue,
return CL_INVALID_MEM_OBJECT;
}
const Memory &memory = memobj->cast<Memory>();
if (memory.getType() == CL_MEM_OBJECT_PIPE)
if (memory.getType() == MemObjectType::Pipe)
{
return CL_INVALID_MEM_OBJECT;
}
......@@ -2391,6 +2534,18 @@ cl_int ValidateSetMemObjectDestructorCallback(cl_mem memobj,
void *user_data),
const void *user_data)
{
// CL_INVALID_MEM_OBJECT if memobj is not a valid memory object.
if (!Memory::IsValid(memobj))
{
return CL_INVALID_MEM_OBJECT;
}
// CL_INVALID_VALUE if pfn_notify is NULL.
if (pfn_notify == nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
......@@ -2656,41 +2811,41 @@ cl_int ValidateCreateImage(cl_context context,
const size_t sliceSize = imageHeight * rowPitch;
// CL_INVALID_IMAGE_DESCRIPTOR if values specified in image_desc are not valid.
switch (image_desc->image_type)
switch (FromCLenum<MemObjectType>(image_desc->image_type))
{
case CL_MEM_OBJECT_IMAGE1D:
case MemObjectType::Image1D:
if (image_desc->image_width == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
break;
case CL_MEM_OBJECT_IMAGE2D:
case MemObjectType::Image2D:
if (image_desc->image_width == 0u || image_desc->image_height == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
break;
case CL_MEM_OBJECT_IMAGE3D:
case MemObjectType::Image3D:
if (image_desc->image_width == 0u || image_desc->image_height == 0u ||
image_desc->image_depth == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case MemObjectType::Image1D_Array:
if (image_desc->image_width == 0u || image_desc->image_array_size == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case MemObjectType::Image2D_Array:
if (image_desc->image_width == 0u || image_desc->image_height == 0u ||
image_desc->image_array_size == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
}
break;
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
case MemObjectType::Image1D_Buffer:
if (image_desc->image_width == 0u)
{
return CL_INVALID_IMAGE_DESCRIPTOR;
......
......@@ -309,8 +309,8 @@ cl_int GetSupportedImageFormats(cl_context context,
cl_image_format *image_formats,
cl_uint *num_image_formats)
{
WARN_NOT_SUPPORTED(GetSupportedImageFormats);
return 0;
return context->cast<Context>().getSupportedImageFormats(flags, image_type, num_entries,
image_formats, num_image_formats);
}
cl_int GetMemObjectInfo(cl_mem memobj,
......@@ -347,8 +347,7 @@ cl_int SetMemObjectDestructorCallback(cl_mem memobj,
void(CL_CALLBACK *pfn_notify)(cl_mem memobj, void *user_data),
void *user_data)
{
WARN_NOT_SUPPORTED(SetMemObjectDestructorCallback);
return 0;
return memobj->cast<Memory>().setDestructorCallback(pfn_notify, user_data);
}
void *SVMAlloc(cl_context context, SVM_MemFlags flags, size_t size, cl_uint alignment)
......@@ -567,8 +566,7 @@ cl_int ReleaseKernel(cl_kernel kernel)
cl_int SetKernelArg(cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void *arg_value)
{
WARN_NOT_SUPPORTED(SetKernelArg);
return 0;
return kernel->cast<Kernel>().setArg(arg_index, arg_size, arg_value);
}
cl_int SetKernelArgSVMPointer(cl_kernel kernel, cl_uint arg_index, const void *arg_value)
......@@ -688,8 +686,8 @@ cl_int GetEventProfilingInfo(cl_event event,
void *param_value,
size_t *param_value_size_ret)
{
WARN_NOT_SUPPORTED(GetEventProfilingInfo);
return 0;
return event->cast<Event>().getProfilingInfo(param_name, param_value_size, param_value,
param_value_size_ret);
}
cl_int Flush(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