Commit efd8da4d by John Plate Committed by Angle LUCI CQ

CL: buffer object creation for front end and pass-through

Add Buffer object to front end and Memory object to back end. Implement creation of buffer and sub-buffer objects. Make cl::Object destructor virtual to support destruction of Buffer. Cache more Device info for Buffer validation. Add missing and move existing version checks into validation. Bug: angleproject:5956 Change-Id: Iea7665be5f6bdd8469e81f5fe4935a9fb0e03436 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2912677Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: John Plate <jplate@google.com>
parent 63f062e4
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLBuffer.cpp: Implements the cl::Buffer class.
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLContext.h"
namespace cl
{
Buffer::~Buffer() = default;
cl_mem Buffer::createSubBuffer(cl_mem_flags flags,
cl_buffer_create_type createType,
const void *createInfo,
cl_int *errcodeRet)
{
const cl_buffer_region &region = *static_cast<const cl_buffer_region *>(createInfo);
mContext->mMemories.emplace_back(
new Buffer(*this, flags, region.origin, region.size, errcodeRet));
if (!mContext->mMemories.back()->mImpl)
{
mContext->mMemories.back()->release();
return nullptr;
}
return mContext->mMemories.back().get();
}
Buffer::Buffer(Context &context,
PropArray &&properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet)
: Memory(*this, context, std::move(properties), flags, size, hostPtr, errcodeRet)
{}
Buffer::Buffer(Buffer &parent, cl_mem_flags flags, size_t offset, size_t size, cl_int *errcodeRet)
: Memory(*this, parent, flags, offset, size, errcodeRet)
{}
} // namespace cl
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLBuffer.h: Defines the cl::Buffer class, which is a collection of elements.
#ifndef LIBANGLE_CLBUFFER_H_
#define LIBANGLE_CLBUFFER_H_
#include "libANGLE/CLMemory.h"
namespace cl
{
class Buffer final : public Memory
{
public:
~Buffer() override;
cl_mem_object_type getType() const final;
bool isSubBuffer() const;
bool isRegionValid(const cl_buffer_region &region) const;
cl_mem createSubBuffer(cl_mem_flags flags,
cl_buffer_create_type createType,
const void *createInfo,
cl_int *errcodeRet);
static bool IsValid(const _cl_mem *buffer);
private:
Buffer(Context &context,
PropArray &&properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet);
Buffer(Buffer &parent, cl_mem_flags flags, size_t offset, size_t size, cl_int *errcodeRet);
friend class Context;
};
inline cl_mem_object_type Buffer::getType() const
{
return CL_MEM_OBJECT_BUFFER;
}
inline bool Buffer::isSubBuffer() const
{
return bool(mParent);
}
inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
{
return region.origin < mSize && region.origin + region.size <= mSize;
}
inline bool Buffer::IsValid(const _cl_mem *buffer)
{
return Memory::IsValid(buffer) &&
static_cast<const Memory *>(buffer)->getType() == CL_MEM_OBJECT_BUFFER;
}
} // namespace cl
#endif // LIBANGLE_CLBUFFER_H_
...@@ -129,30 +129,30 @@ bool CommandQueue::IsValid(const _cl_command_queue *commandQueue) ...@@ -129,30 +129,30 @@ bool CommandQueue::IsValid(const _cl_command_queue *commandQueue)
}) != platforms.cend(); }) != platforms.cend();
} }
CommandQueue::CommandQueue(ContextRefPtr &&context, CommandQueue::CommandQueue(Context &context,
DeviceRefPtr &&device, Device &device,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_int *errcodeRet) cl_int *errcodeRet)
: _cl_command_queue(context->getDispatch()), : _cl_command_queue(context.getDispatch()),
mContext(std::move(context)), mContext(&context),
mDevice(std::move(device)), mDevice(&device),
mProperties(properties), mProperties(properties),
mImpl(mContext->mImpl->createCommandQueue(*this, errcodeRet)) mImpl(context.mImpl->createCommandQueue(*this, errcodeRet))
{} {}
CommandQueue::CommandQueue(ContextRefPtr &&context, CommandQueue::CommandQueue(Context &context,
DeviceRefPtr &&device, Device &device,
PropArray &&propArray, PropArray &&propArray,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_uint size, cl_uint size,
cl_int *errcodeRet) cl_int *errcodeRet)
: _cl_command_queue(context->getDispatch()), : _cl_command_queue(context.getDispatch()),
mContext(std::move(context)), mContext(&context),
mDevice(std::move(device)), mDevice(&device),
mPropArray(std::move(propArray)), mPropArray(std::move(propArray)),
mProperties(properties), mProperties(properties),
mSize(size), mSize(size),
mImpl(mContext->mImpl->createCommandQueue(*this, errcodeRet)) mImpl(context.mImpl->createCommandQueue(*this, errcodeRet))
{ {
if ((mProperties & CL_QUEUE_ON_DEVICE_DEFAULT) != 0u) if ((mProperties & CL_QUEUE_ON_DEVICE_DEFAULT) != 0u)
{ {
......
...@@ -25,7 +25,7 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -25,7 +25,7 @@ class CommandQueue final : public _cl_command_queue, public Object
static constexpr cl_uint kNoSize = std::numeric_limits<cl_uint>::max(); static constexpr cl_uint kNoSize = std::numeric_limits<cl_uint>::max();
~CommandQueue(); ~CommandQueue() override;
const Context &getContext() const; const Context &getContext() const;
const Device &getDevice() const; const Device &getDevice() const;
...@@ -45,13 +45,13 @@ class CommandQueue final : public _cl_command_queue, public Object ...@@ -45,13 +45,13 @@ class CommandQueue final : public _cl_command_queue, public Object
static bool IsValid(const _cl_command_queue *commandQueue); static bool IsValid(const _cl_command_queue *commandQueue);
private: private:
CommandQueue(ContextRefPtr &&context, CommandQueue(Context &context,
DeviceRefPtr &&device, Device &device,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_int *errcodeRet); cl_int *errcodeRet);
CommandQueue(ContextRefPtr &&context, CommandQueue(Context &context,
DeviceRefPtr &&device, Device &device,
PropArray &&propArray, PropArray &&propArray,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_uint size, cl_uint size,
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#include <cstring> #include <cstring>
...@@ -79,8 +80,8 @@ cl_command_queue Context::createCommandQueue(cl_device_id device, ...@@ -79,8 +80,8 @@ cl_command_queue Context::createCommandQueue(cl_device_id device,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_int *errcodeRet) cl_int *errcodeRet)
{ {
mCommandQueues.emplace_back(new CommandQueue( mCommandQueues.emplace_back(
ContextRefPtr(this), DeviceRefPtr(static_cast<Device *>(device)), properties, errcodeRet)); new CommandQueue(*this, *static_cast<Device *>(device), properties, errcodeRet));
if (!mCommandQueues.back()->mImpl) if (!mCommandQueues.back()->mImpl)
{ {
mCommandQueues.back()->release(); mCommandQueues.back()->release();
...@@ -117,8 +118,7 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device, ...@@ -117,8 +118,7 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
propArray.insert(propArray.cend(), properties, propIt); propArray.insert(propArray.cend(), properties, propIt);
} }
mCommandQueues.emplace_back(new CommandQueue(ContextRefPtr(this), mCommandQueues.emplace_back(new CommandQueue(*this, *static_cast<Device *>(device),
DeviceRefPtr(static_cast<Device *>(device)),
std::move(propArray), props, size, errcodeRet)); std::move(propArray), props, size, errcodeRet));
if (!mCommandQueues.back()->mImpl) if (!mCommandQueues.back()->mImpl)
{ {
...@@ -128,6 +128,21 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device, ...@@ -128,6 +128,21 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
return mCommandQueues.back().get(); return mCommandQueues.back().get();
} }
cl_mem Context::createBuffer(const cl_mem_properties *properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet)
{
mMemories.emplace_back(new Buffer(*this, {}, flags, size, hostPtr, errcodeRet));
if (!mMemories.back()->mImpl)
{
mMemories.back()->release();
return nullptr;
}
return mMemories.back().get();
}
bool Context::IsValid(const _cl_context *context) bool Context::IsValid(const _cl_context *context)
{ {
const Platform::PtrList &platforms = Platform::GetPlatforms(); const Platform::PtrList &platforms = Platform::GetPlatforms();
...@@ -191,6 +206,23 @@ void Context::destroyCommandQueue(CommandQueue *commandQueue) ...@@ -191,6 +206,23 @@ void Context::destroyCommandQueue(CommandQueue *commandQueue)
} }
} }
void Context::destroyMemory(Memory *memory)
{
auto memoryIt = mMemories.cbegin();
while (memoryIt != mMemories.cend() && memoryIt->get() != memory)
{
++memoryIt;
}
if (memoryIt != mMemories.cend())
{
mMemories.erase(memoryIt);
}
else
{
ERR() << "Memory not found";
}
}
void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData) void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData)
{ {
Context *const context = static_cast<Context *>(userData); Context *const context = static_cast<Context *>(userData);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLMemory.h"
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLContextImpl.h"
namespace cl namespace cl
...@@ -22,11 +23,14 @@ class Context final : public _cl_context, public Object ...@@ -22,11 +23,14 @@ class Context final : public _cl_context, public Object
using PtrList = std::list<ContextPtr>; using PtrList = std::list<ContextPtr>;
using PropArray = std::vector<cl_context_properties>; using PropArray = std::vector<cl_context_properties>;
~Context(); ~Context() override;
const Platform &getPlatform() const noexcept; const Platform &getPlatform() const noexcept;
bool hasDevice(const _cl_device_id *device) const; bool hasDevice(const _cl_device_id *device) const;
const DeviceRefList &getDevices() const;
bool hasCommandQueue(const _cl_command_queue *commandQueue) const; bool hasCommandQueue(const _cl_command_queue *commandQueue) const;
bool hasMemory(const _cl_mem *memory) const;
void retain() noexcept; void retain() noexcept;
bool release(); bool release();
...@@ -41,6 +45,12 @@ class Context final : public _cl_context, public Object ...@@ -41,6 +45,12 @@ class Context final : public _cl_context, public Object
const cl_queue_properties *properties, const cl_queue_properties *properties,
cl_int *errcodeRet); cl_int *errcodeRet);
cl_mem createBuffer(const cl_mem_properties *properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet);
static bool IsValid(const _cl_context *context); static bool IsValid(const _cl_context *context);
private: private:
...@@ -61,6 +71,7 @@ class Context final : public _cl_context, public Object ...@@ -61,6 +71,7 @@ class Context final : public _cl_context, public Object
cl_int *errcodeRet); cl_int *errcodeRet);
void destroyCommandQueue(CommandQueue *commandQueue); void destroyCommandQueue(CommandQueue *commandQueue);
void destroyMemory(Memory *memory);
static void CL_CALLBACK ErrorCallback(const char *errinfo, static void CL_CALLBACK ErrorCallback(const char *errinfo,
const void *privateInfo, const void *privateInfo,
...@@ -75,8 +86,11 @@ class Context final : public _cl_context, public Object ...@@ -75,8 +86,11 @@ class Context final : public _cl_context, public Object
void *const mUserData; void *const mUserData;
CommandQueue::PtrList mCommandQueues; CommandQueue::PtrList mCommandQueues;
Memory::PtrList mMemories;
friend class Buffer;
friend class CommandQueue; friend class CommandQueue;
friend class Memory;
friend class Platform; friend class Platform;
}; };
...@@ -92,6 +106,11 @@ inline bool Context::hasDevice(const _cl_device_id *device) const ...@@ -92,6 +106,11 @@ inline bool Context::hasDevice(const _cl_device_id *device) const
}) != mDevices.cend(); }) != mDevices.cend();
} }
inline const DeviceRefList &Context::getDevices() const
{
return mDevices;
}
inline bool Context::hasCommandQueue(const _cl_command_queue *commandQueue) const inline bool Context::hasCommandQueue(const _cl_command_queue *commandQueue) const
{ {
return std::find_if(mCommandQueues.cbegin(), mCommandQueues.cend(), return std::find_if(mCommandQueues.cbegin(), mCommandQueues.cend(),
...@@ -99,6 +118,13 @@ inline bool Context::hasCommandQueue(const _cl_command_queue *commandQueue) cons ...@@ -99,6 +118,13 @@ inline bool Context::hasCommandQueue(const _cl_command_queue *commandQueue) cons
mCommandQueues.cend(); mCommandQueues.cend();
} }
inline bool Context::hasMemory(const _cl_mem *memory) const
{
return std::find_if(mMemories.cbegin(), mMemories.cend(), [=](const MemoryPtr &ptr) {
return ptr.get() == memory;
}) != mMemories.cend();
}
inline void Context::retain() noexcept inline void Context::retain() noexcept
{ {
addRef(); addRef();
......
...@@ -112,7 +112,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -112,7 +112,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
case DeviceInfo::QueueOnDeviceMaxSize: case DeviceInfo::QueueOnDeviceMaxSize:
case DeviceInfo::MaxOnDeviceQueues: case DeviceInfo::MaxOnDeviceQueues:
case DeviceInfo::MaxOnDeviceEvents: case DeviceInfo::MaxOnDeviceEvents:
case DeviceInfo::NumericVersion:
case DeviceInfo::PreferredInteropUserSync: case DeviceInfo::PreferredInteropUserSync:
case DeviceInfo::PartitionMaxSubDevices: case DeviceInfo::PartitionMaxSubDevices:
case DeviceInfo::PreferredPlatformAtomicAlignment: case DeviceInfo::PreferredPlatformAtomicAlignment:
...@@ -130,7 +129,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -130,7 +129,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
break; break;
// Handle all cl_ulong and aliased types // Handle all cl_ulong and aliased types
case DeviceInfo::MaxMemAllocSize:
case DeviceInfo::SingleFpConfig: case DeviceInfo::SingleFpConfig:
case DeviceInfo::DoubleFpConfig: case DeviceInfo::DoubleFpConfig:
case DeviceInfo::GlobalMemCacheSize: case DeviceInfo::GlobalMemCacheSize:
...@@ -178,7 +176,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -178,7 +176,6 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
case DeviceInfo::Vendor: case DeviceInfo::Vendor:
case DeviceInfo::DriverVersion: case DeviceInfo::DriverVersion:
case DeviceInfo::Profile: case DeviceInfo::Profile:
case DeviceInfo::Version:
case DeviceInfo::OpenCL_C_Version: case DeviceInfo::OpenCL_C_Version:
case DeviceInfo::LatestConformanceVersionPassed: case DeviceInfo::LatestConformanceVersionPassed:
result = mImpl->getInfoStringLength(name, &copySize); result = mImpl->getInfoStringLength(name, &copySize);
...@@ -206,38 +203,34 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -206,38 +203,34 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copySize = mInfo.mMaxWorkItemSizes.size() * copySize = mInfo.mMaxWorkItemSizes.size() *
sizeof(decltype(mInfo.mMaxWorkItemSizes)::value_type); sizeof(decltype(mInfo.mMaxWorkItemSizes)::value_type);
break; break;
case DeviceInfo::MaxMemAllocSize:
copyValue = &mInfo.mMaxMemAllocSize;
copySize = sizeof(mInfo.mMaxMemAllocSize);
break;
case DeviceInfo::ILsWithVersion: case DeviceInfo::ILsWithVersion:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mILsWithVersion.data(); copyValue = mInfo.mILsWithVersion.data();
copySize = copySize =
mInfo.mILsWithVersion.size() * sizeof(decltype(mInfo.mILsWithVersion)::value_type); mInfo.mILsWithVersion.size() * sizeof(decltype(mInfo.mILsWithVersion)::value_type);
break; break;
case DeviceInfo::BuiltInKernelsWithVersion: case DeviceInfo::BuiltInKernelsWithVersion:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mBuiltInKernelsWithVersion.data(); copyValue = mInfo.mBuiltInKernelsWithVersion.data();
copySize = mInfo.mBuiltInKernelsWithVersion.size() * copySize = mInfo.mBuiltInKernelsWithVersion.size() *
sizeof(decltype(mInfo.mBuiltInKernelsWithVersion)::value_type); sizeof(decltype(mInfo.mBuiltInKernelsWithVersion)::value_type);
break; break;
case DeviceInfo::Version:
copyValue = mInfo.mVersionStr.c_str();
copySize = mInfo.mVersionStr.length() + 1u;
break;
case DeviceInfo::NumericVersion:
copyValue = &mInfo.mVersion;
copySize = sizeof(mInfo.mVersion);
break;
case DeviceInfo::OpenCL_C_AllVersions: case DeviceInfo::OpenCL_C_AllVersions:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mOpenCL_C_AllVersions.data(); copyValue = mInfo.mOpenCL_C_AllVersions.data();
copySize = mInfo.mOpenCL_C_AllVersions.size() * copySize = mInfo.mOpenCL_C_AllVersions.size() *
sizeof(decltype(mInfo.mOpenCL_C_AllVersions)::value_type); sizeof(decltype(mInfo.mOpenCL_C_AllVersions)::value_type);
break; break;
case DeviceInfo::OpenCL_C_Features: case DeviceInfo::OpenCL_C_Features:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mOpenCL_C_Features.data(); copyValue = mInfo.mOpenCL_C_Features.data();
copySize = mInfo.mOpenCL_C_Features.size() * copySize = mInfo.mOpenCL_C_Features.size() *
sizeof(decltype(mInfo.mOpenCL_C_Features)::value_type); sizeof(decltype(mInfo.mOpenCL_C_Features)::value_type);
...@@ -247,28 +240,16 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -247,28 +240,16 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copySize = mInfo.mExtensions.length() + 1u; copySize = mInfo.mExtensions.length() + 1u;
break; break;
case DeviceInfo::ExtensionsWithVersion: case DeviceInfo::ExtensionsWithVersion:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mExtensionsWithVersion.data(); copyValue = mInfo.mExtensionsWithVersion.data();
copySize = mInfo.mExtensionsWithVersion.size() * copySize = mInfo.mExtensionsWithVersion.size() *
sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type); sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type);
break; break;
case DeviceInfo::PartitionProperties: case DeviceInfo::PartitionProperties:
if (mInfo.mVersion < CL_MAKE_VERSION(1, 2, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mPartitionProperties.data(); copyValue = mInfo.mPartitionProperties.data();
copySize = mInfo.mPartitionProperties.size() * copySize = mInfo.mPartitionProperties.size() *
sizeof(decltype(mInfo.mPartitionProperties)::value_type); sizeof(decltype(mInfo.mPartitionProperties)::value_type);
break; break;
case DeviceInfo::PartitionType: case DeviceInfo::PartitionType:
if (mInfo.mVersion < CL_MAKE_VERSION(1, 2, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mPartitionType.data(); copyValue = mInfo.mPartitionType.data();
copySize = copySize =
mInfo.mPartitionType.size() * sizeof(decltype(mInfo.mPartitionType)::value_type); mInfo.mPartitionType.size() * sizeof(decltype(mInfo.mPartitionType)::value_type);
...@@ -281,19 +262,11 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -281,19 +262,11 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
copySize = sizeof(valPointer); copySize = sizeof(valPointer);
break; break;
case DeviceInfo::ParentDevice: case DeviceInfo::ParentDevice:
if (mInfo.mVersion < CL_MAKE_VERSION(1, 2, 0))
{
return CL_INVALID_VALUE;
}
valPointer = static_cast<cl_device_id>(mParent.get()); valPointer = static_cast<cl_device_id>(mParent.get());
copyValue = &valPointer; copyValue = &valPointer;
copySize = sizeof(valPointer); copySize = sizeof(valPointer);
break; break;
case DeviceInfo::ReferenceCount: case DeviceInfo::ReferenceCount:
if (mInfo.mVersion < CL_MAKE_VERSION(1, 2, 0))
{
return CL_INVALID_VALUE;
}
copyValue = getRefCountPtr(); copyValue = getRefCountPtr();
copySize = sizeof(*getRefCountPtr()); copySize = sizeof(*getRefCountPtr());
break; break;
...@@ -349,11 +322,11 @@ cl_int Device::createSubDevices(const cl_device_partition_property *properties, ...@@ -349,11 +322,11 @@ cl_int Device::createSubDevices(const cl_device_partition_property *properties,
} }
DevicePtr Device::CreateDevice(Platform &platform, DevicePtr Device::CreateDevice(Platform &platform,
DeviceRefPtr &&parent, Device *parent,
cl_device_type type, cl_device_type type,
const CreateImplFunc &createImplFunc) const CreateImplFunc &createImplFunc)
{ {
DevicePtr device(new Device(platform, std::move(parent), type, createImplFunc)); DevicePtr device(new Device(platform, parent, type, createImplFunc));
return device->mInfo.isValid() ? std::move(device) : DevicePtr{}; return device->mInfo.isValid() ? std::move(device) : DevicePtr{};
} }
...@@ -366,12 +339,12 @@ bool Device::IsValid(const _cl_device_id *device) ...@@ -366,12 +339,12 @@ bool Device::IsValid(const _cl_device_id *device)
} }
Device::Device(Platform &platform, Device::Device(Platform &platform,
DeviceRefPtr &&parent, Device *parent,
cl_device_type type, cl_device_type type,
const CreateImplFunc &createImplFunc) const CreateImplFunc &createImplFunc)
: _cl_device_id(platform.getDispatch()), : _cl_device_id(platform.getDispatch()),
mPlatform(platform), mPlatform(platform),
mParent(std::move(parent)), mParent(parent),
mImpl(createImplFunc(*this)), mImpl(createImplFunc(*this)),
mInfo(mImpl->createInfo(type)) mInfo(mImpl->createInfo(type))
{} {}
......
...@@ -22,7 +22,7 @@ class Device final : public _cl_device_id, public Object ...@@ -22,7 +22,7 @@ class Device final : public _cl_device_id, public Object
public: public:
using CreateImplFunc = std::function<rx::CLDeviceImpl::Ptr(const cl::Device &)>; using CreateImplFunc = std::function<rx::CLDeviceImpl::Ptr(const cl::Device &)>;
~Device(); ~Device() override;
Platform &getPlatform() noexcept; Platform &getPlatform() noexcept;
const Platform &getPlatform() const noexcept; const Platform &getPlatform() const noexcept;
...@@ -32,6 +32,7 @@ class Device final : public _cl_device_id, public Object ...@@ -32,6 +32,7 @@ class Device final : public _cl_device_id, public Object
T &getImpl() const; T &getImpl() const;
const rx::CLDeviceImpl::Info &getInfo() const; const rx::CLDeviceImpl::Info &getInfo() const;
bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
bool hasSubDevice(const _cl_device_id *device) const; bool hasSubDevice(const _cl_device_id *device) const;
void retain() noexcept; void retain() noexcept;
...@@ -48,7 +49,7 @@ class Device final : public _cl_device_id, public Object ...@@ -48,7 +49,7 @@ class Device final : public _cl_device_id, public Object
cl_uint *numDevicesRet); cl_uint *numDevicesRet);
static DevicePtr CreateDevice(Platform &platform, static DevicePtr CreateDevice(Platform &platform,
DeviceRefPtr &&parent, Device *parent,
cl_device_type type, cl_device_type type,
const CreateImplFunc &createImplFunc); const CreateImplFunc &createImplFunc);
...@@ -57,7 +58,7 @@ class Device final : public _cl_device_id, public Object ...@@ -57,7 +58,7 @@ class Device final : public _cl_device_id, public Object
private: private:
Device(Platform &platform, Device(Platform &platform,
DeviceRefPtr &&parent, Device *parent,
cl_device_type type, cl_device_type type,
const CreateImplFunc &createImplFunc); const CreateImplFunc &createImplFunc);
...@@ -101,6 +102,11 @@ inline const rx::CLDeviceImpl::Info &Device::getInfo() const ...@@ -101,6 +102,11 @@ inline const rx::CLDeviceImpl::Info &Device::getInfo() const
return mInfo; return mInfo;
} }
inline bool Device::isVersionOrNewer(cl_uint major, cl_uint minor) const
{
return mInfo.mVersion >= CL_MAKE_VERSION(major, minor, 0u);
}
inline bool Device::hasSubDevice(const _cl_device_id *device) const inline bool Device::hasSubDevice(const _cl_device_id *device) const
{ {
return std::find_if(mSubDevices.cbegin(), mSubDevices.cend(), [=](const DevicePtr &ptr) { return std::find_if(mSubDevices.cbegin(), mSubDevices.cend(), [=](const DevicePtr &ptr) {
......
...@@ -18,7 +18,7 @@ class Event final : public _cl_event, public Object ...@@ -18,7 +18,7 @@ class Event final : public _cl_event, public Object
{ {
public: public:
Event(const cl_icd_dispatch &dispatch); Event(const cl_icd_dispatch &dispatch);
~Event() = default; ~Event() override = default;
}; };
} // namespace cl } // namespace cl
......
...@@ -17,7 +17,7 @@ class Kernel final : public _cl_kernel, public Object ...@@ -17,7 +17,7 @@ class Kernel final : public _cl_kernel, public Object
{ {
public: public:
Kernel(const cl_icd_dispatch &dispatch); Kernel(const cl_icd_dispatch &dispatch);
~Kernel() = default; ~Kernel() override = default;
}; };
} // namespace cl } // namespace cl
......
...@@ -7,9 +7,149 @@ ...@@ -7,9 +7,149 @@
#include "libANGLE/CLMemory.h" #include "libANGLE/CLMemory.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLPlatform.h"
#include <cstring>
namespace cl namespace cl
{ {
Memory::Memory(const cl_icd_dispatch &dispatch) : _cl_mem(dispatch) {} Memory::~Memory() = default;
bool Memory::release()
{
const bool released = removeRef();
if (released)
{
mContext->destroyMemory(this);
}
return released;
}
cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet)
{
static_assert(
std::is_same<cl_uint, cl_bool>::value && std::is_same<cl_uint, cl_mem_object_type>::value,
"OpenCL type mismatch");
cl_uint valUInt = 0u;
void *valPointer = nullptr;
const void *copyValue = nullptr;
size_t copySize = 0u;
switch (name)
{
case MemInfo::Type:
valUInt = getType();
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
case MemInfo::Flags:
copyValue = &mFlags;
copySize = sizeof(mFlags);
break;
case MemInfo::Size:
copyValue = &mSize;
copySize = sizeof(mSize);
break;
case MemInfo::HostPtr:
copyValue = &mHostPtr;
copySize = sizeof(mHostPtr);
break;
case MemInfo::MapCount:
copyValue = &mMapCount;
copySize = sizeof(mMapCount);
break;
case MemInfo::ReferenceCount:
copyValue = getRefCountPtr();
copySize = sizeof(*getRefCountPtr());
break;
case MemInfo::Context:
valPointer = static_cast<cl_context>(mContext.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case MemInfo::AssociatedMemObject:
valPointer = static_cast<cl_mem>(mParent.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case MemInfo::Offset:
copyValue = &mOffset;
copySize = sizeof(mOffset);
break;
case MemInfo::UsesSVM_Pointer:
valUInt = CL_FALSE; // TODO(jplate) Check for SVM pointer anglebug.com/6002
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
case MemInfo::Properties:
copyValue = mProperties.data();
copySize = mProperties.size() * sizeof(decltype(mProperties)::value_type);
break;
default:
return CL_INVALID_VALUE;
}
if (value != nullptr)
{
if (valueSize < copySize)
{
return CL_INVALID_VALUE;
}
if (copyValue != nullptr)
{
std::memcpy(value, copyValue, copySize);
}
}
if (valueSizeRet != nullptr)
{
*valueSizeRet = copySize;
}
return CL_SUCCESS;
}
bool Memory::IsValid(const _cl_mem *memory)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->hasMemory(memory);
}) != platforms.cend();
}
Memory::Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet)
: _cl_mem(context.getDispatch()),
mContext(&context),
mProperties(std::move(properties)),
mFlags(flags),
mHostPtr((flags & CL_MEM_USE_HOST_PTR) != 0u ? hostPtr : nullptr),
mImpl(context.mImpl->createBuffer(buffer, size, hostPtr, errcodeRet)),
mSize(size)
{}
Memory::Memory(const Buffer &buffer,
Buffer &parent,
cl_mem_flags flags,
size_t offset,
size_t size,
cl_int *errcodeRet)
: _cl_mem(parent.getDispatch()),
mContext(parent.mContext),
mFlags(flags),
mHostPtr(parent.mHostPtr != nullptr ? static_cast<char *>(parent.mHostPtr) + offset
: nullptr),
mParent(&parent),
mOffset(offset),
mImpl(parent.mImpl->createSubBuffer(buffer, size, errcodeRet)),
mSize(size)
{}
} // namespace cl } // namespace cl
...@@ -3,24 +3,108 @@ ...@@ -3,24 +3,108 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// CLMemory.h: Defines the cl::Memory class, which is a memory object and represents OpenCL objects // CLMemory.h: Defines the abstract cl::Memory class, which is a memory object
// such as buffers, images and pipes. // and the base class for OpenCL objects such as Buffer, Image and Pipe.
#ifndef LIBANGLE_CLMEMORY_H_ #ifndef LIBANGLE_CLMEMORY_H_
#define LIBANGLE_CLMEMORY_H_ #define LIBANGLE_CLMEMORY_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLObject.h"
#include "libANGLE/renderer/CLMemoryImpl.h"
namespace cl namespace cl
{ {
class Memory final : public _cl_mem, public Object class Memory : public _cl_mem, public Object
{ {
public: public:
Memory(const cl_icd_dispatch &dispatch); using PtrList = std::list<MemoryPtr>;
~Memory() = default; using PropArray = std::vector<cl_mem_properties>;
~Memory() override;
virtual cl_mem_object_type getType() const = 0;
const Context &getContext() const;
const PropArray &getProperties() const;
cl_mem_flags getFlags() const;
void *getHostPtr() const;
const MemoryRefPtr &getParent() const;
size_t getOffset() const;
void retain() noexcept;
bool release();
cl_int getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
static bool IsValid(const _cl_mem *memory);
protected:
Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
cl_mem_flags flags,
size_t size,
void *hostPtr,
cl_int *errcodeRet);
Memory(const Buffer &buffer,
Buffer &parent,
cl_mem_flags flags,
size_t offset,
size_t size,
cl_int *errcodeRet);
const ContextRefPtr mContext;
const PropArray mProperties;
const cl_mem_flags mFlags;
void *const mHostPtr = nullptr;
const MemoryRefPtr mParent;
const size_t mOffset = 0u;
const rx::CLMemoryImpl::Ptr mImpl;
const size_t mSize;
cl_uint mMapCount = 0u;
friend class Buffer;
friend class Context;
}; };
inline const Context &Memory::getContext() const
{
return *mContext;
}
inline const Memory::PropArray &Memory::getProperties() const
{
return mProperties;
}
inline cl_mem_flags Memory::getFlags() const
{
return mFlags;
}
inline void *Memory::getHostPtr() const
{
return mHostPtr;
}
inline const MemoryRefPtr &Memory::getParent() const
{
return mParent;
}
inline size_t Memory::getOffset() const
{
return mOffset;
}
inline void Memory::retain() noexcept
{
addRef();
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLMEMORY_H_ #endif // LIBANGLE_CLMEMORY_H_
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLObject.cpp: Implements the cl::Object class.
#include "libANGLE/CLObject.h"
namespace cl
{
Object::~Object()
{
if (mRefCount != 0u)
{
WARN() << "Deleted object with references";
}
}
} // namespace cl
...@@ -19,17 +19,9 @@ class Object ...@@ -19,17 +19,9 @@ class Object
{ {
public: public:
Object() = default; Object() = default;
virtual ~Object();
~Object()
{
if (mRefCount != 0u)
{
WARN() << "Deleted object with references";
}
}
cl_uint getRefCount() { return mRefCount; } cl_uint getRefCount() { return mRefCount; }
const cl_uint *getRefCountPtr() { return &mRefCount; } const cl_uint *getRefCountPtr() { return &mRefCount; }
protected: protected:
......
...@@ -80,10 +80,6 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -80,10 +80,6 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_
copySize = mInfo.mVersionStr.length() + 1u; copySize = mInfo.mVersionStr.length() + 1u;
break; break;
case PlatformInfo::NumericVersion: case PlatformInfo::NumericVersion:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = &mInfo.mVersion; copyValue = &mInfo.mVersion;
copySize = sizeof(mInfo.mVersion); copySize = sizeof(mInfo.mVersion);
break; break;
...@@ -100,19 +96,11 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -100,19 +96,11 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_
copySize = mInfo.mExtensions.length() + 1u; copySize = mInfo.mExtensions.length() + 1u;
break; break;
case PlatformInfo::ExtensionsWithVersion: case PlatformInfo::ExtensionsWithVersion:
if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mExtensionsWithVersion.data(); copyValue = mInfo.mExtensionsWithVersion.data();
copySize = mInfo.mExtensionsWithVersion.size() * copySize = mInfo.mExtensionsWithVersion.size() *
sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type); sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type);
break; break;
case PlatformInfo::HostTimerResolution: case PlatformInfo::HostTimerResolution:
if (mInfo.mVersion < CL_MAKE_VERSION(2, 1, 0))
{
return CL_INVALID_VALUE;
}
copyValue = &mInfo.mHostTimerRes; copyValue = &mInfo.mHostTimerRes;
copySize = sizeof(mInfo.mHostTimerRes); copySize = sizeof(mInfo.mHostTimerRes);
break; break;
......
...@@ -26,13 +26,16 @@ class Platform final : public _cl_platform_id, public Object ...@@ -26,13 +26,16 @@ class Platform final : public _cl_platform_id, public Object
using PtrList = std::list<PlatformPtr>; using PtrList = std::list<PlatformPtr>;
using CreateImplFunc = std::function<rx::CLPlatformImpl::Ptr(const cl::Platform &)>; using CreateImplFunc = std::function<rx::CLPlatformImpl::Ptr(const cl::Platform &)>;
~Platform(); ~Platform() override;
const rx::CLPlatformImpl::Info &getInfo() const; const rx::CLPlatformImpl::Info &getInfo() const;
bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
bool hasDevice(const _cl_device_id *device) const; bool hasDevice(const _cl_device_id *device) const;
const DevicePtrList &getDevices() const; const DevicePtrList &getDevices() const;
bool hasContext(const _cl_context *context) const; bool hasContext(const _cl_context *context) const;
bool hasCommandQueue(const _cl_command_queue *commandQueue) const; bool hasCommandQueue(const _cl_command_queue *commandQueue) const;
bool hasMemory(const _cl_mem *memory) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet); cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
...@@ -93,6 +96,11 @@ inline const rx::CLPlatformImpl::Info &Platform::getInfo() const ...@@ -93,6 +96,11 @@ inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
return mInfo; return mInfo;
} }
inline bool Platform::isVersionOrNewer(cl_uint major, cl_uint minor) const
{
return mInfo.mVersion >= CL_MAKE_VERSION(major, minor, 0u);
}
inline bool Platform::hasDevice(const _cl_device_id *device) const inline bool Platform::hasDevice(const _cl_device_id *device) const
{ {
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const DevicePtr &ptr) { return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const DevicePtr &ptr) {
...@@ -119,6 +127,13 @@ inline bool Platform::hasCommandQueue(const _cl_command_queue *commandQueue) con ...@@ -119,6 +127,13 @@ inline bool Platform::hasCommandQueue(const _cl_command_queue *commandQueue) con
}) != mContexts.cend(); }) != mContexts.cend();
} }
inline bool Platform::hasMemory(const _cl_mem *memory) const
{
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const ContextPtr &ptr) {
return ptr->hasMemory(memory);
}) != mContexts.cend();
}
inline Platform::PtrList &Platform::GetList() inline Platform::PtrList &Platform::GetList()
{ {
static angle::base::NoDestructor<PtrList> sList; static angle::base::NoDestructor<PtrList> sList;
......
...@@ -17,7 +17,7 @@ class Program final : public _cl_program, public Object ...@@ -17,7 +17,7 @@ class Program final : public _cl_program, public Object
{ {
public: public:
Program(const cl_icd_dispatch &dispatch); Program(const cl_icd_dispatch &dispatch);
~Program() = default; ~Program() override = default;
}; };
} // namespace cl } // namespace cl
......
...@@ -17,7 +17,7 @@ class Sampler final : public _cl_sampler, public Object ...@@ -17,7 +17,7 @@ class Sampler final : public _cl_sampler, public Object
{ {
public: public:
Sampler(const cl_icd_dispatch &dispatch); Sampler(const cl_icd_dispatch &dispatch);
~Sampler() = default; ~Sampler() override = default;
}; };
} // namespace cl } // namespace cl
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
namespace cl namespace cl
{ {
class Buffer;
class CommandQueue; class CommandQueue;
class Context; class Context;
class Device; class Device;
...@@ -47,6 +48,7 @@ using SamplerPtr = std::unique_ptr<Sampler>; ...@@ -47,6 +48,7 @@ using SamplerPtr = std::unique_ptr<Sampler>;
using ContextRefPtr = RefPointer<Context>; using ContextRefPtr = RefPointer<Context>;
using DeviceRefPtr = RefPointer<Device>; using DeviceRefPtr = RefPointer<Device>;
using MemoryRefPtr = RefPointer<Memory>;
using DevicePtrList = std::list<DevicePtr>; using DevicePtrList = std::list<DevicePtr>;
using DeviceRefList = std::vector<DeviceRefPtr>; using DeviceRefList = std::vector<DeviceRefPtr>;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "libANGLE/renderer/CLCommandQueueImpl.h" #include "libANGLE/renderer/CLCommandQueueImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include "libANGLE/renderer/CLMemoryImpl.h"
namespace rx namespace rx
{ {
...@@ -26,6 +27,10 @@ class CLContextImpl : angle::NonCopyable ...@@ -26,6 +27,10 @@ class CLContextImpl : angle::NonCopyable
virtual CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue, virtual CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue,
cl_int *errcodeRet) = 0; cl_int *errcodeRet) = 0;
virtual CLMemoryImpl::Ptr createBuffer(const cl::Buffer &buffer,
size_t size,
void *hostPtr,
cl_int *errcodeRet) = 0;
protected: protected:
const cl::Context &mContext; const cl::Context &mContext;
......
...@@ -32,11 +32,14 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -32,11 +32,14 @@ class CLDeviceImpl : angle::NonCopyable
bool isValid() const { return mType != 0u; } bool isValid() const { return mType != 0u; }
// In the order as they appear in the OpenCL specification V3.0.7, table 5
cl_device_type mType = 0u; cl_device_type mType = 0u;
cl_version mVersion = 0u;
std::vector<size_t> mMaxWorkItemSizes; std::vector<size_t> mMaxWorkItemSizes;
cl_ulong mMaxMemAllocSize = 0u;
NameVersionVector mILsWithVersion; NameVersionVector mILsWithVersion;
NameVersionVector mBuiltInKernelsWithVersion; NameVersionVector mBuiltInKernelsWithVersion;
std::string mVersionStr;
cl_version mVersion = 0u;
NameVersionVector mOpenCL_C_AllVersions; NameVersionVector mOpenCL_C_AllVersions;
NameVersionVector mOpenCL_C_Features; NameVersionVector mOpenCL_C_Features;
std::string mExtensions; std::string mExtensions;
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryImpl.cpp: Implements the class methods for CLMemoryImpl.
#include "libANGLE/renderer/CLMemoryImpl.h"
namespace rx
{
CLMemoryImpl::CLMemoryImpl(const cl::Memory &memory) : mMemory(memory) {}
CLMemoryImpl::~CLMemoryImpl() = default;
} // namespace rx
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryImpl.h: Defines the abstract rx::CLMemoryImpl class.
#ifndef LIBANGLE_RENDERER_CLMEMORYIMPL_H_
#define LIBANGLE_RENDERER_CLMEMORYIMPL_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
class CLMemoryImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLMemoryImpl>;
CLMemoryImpl(const cl::Memory &memory);
virtual ~CLMemoryImpl();
virtual size_t getSize() const = 0;
virtual CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
size_t size,
cl_int *errcodeRet) = 0;
protected:
const cl::Memory &mMemory;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CLMEMORYIMPL_H_
...@@ -15,6 +15,8 @@ _cl_backend_sources = [ ...@@ -15,6 +15,8 @@ _cl_backend_sources = [
"CLContextCL.h", "CLContextCL.h",
"CLDeviceCL.cpp", "CLDeviceCL.cpp",
"CLDeviceCL.h", "CLDeviceCL.h",
"CLMemoryCL.cpp",
"CLMemoryCL.h",
"CLPlatformCL.cpp", "CLPlatformCL.cpp",
"CLPlatformCL.h", "CLPlatformCL.h",
"cl_types.h", "cl_types.h",
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "libANGLE/renderer/cl/cl_types.h" #include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLCommandQueueImpl.h"
namespace rx namespace rx
{ {
......
...@@ -9,9 +9,13 @@ ...@@ -9,9 +9,13 @@
#include "libANGLE/renderer/cl/CLCommandQueueCL.h" #include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h" #include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLMemory.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#include "libANGLE/Debug.h" #include "libANGLE/Debug.h"
...@@ -76,7 +80,7 @@ CLCommandQueueImpl::Ptr CLContextCL::createCommandQueue(const cl::CommandQueue & ...@@ -76,7 +80,7 @@ CLCommandQueueImpl::Ptr CLContextCL::createCommandQueue(const cl::CommandQueue &
const cl::Device &device = commandQueue.getDevice(); const cl::Device &device = commandQueue.getDevice();
const cl_device_id nativeDevice = device.getImpl<CLDeviceCL &>().getNative(); const cl_device_id nativeDevice = device.getImpl<CLDeviceCL &>().getNative();
cl_command_queue nativeQueue = nullptr; cl_command_queue nativeQueue = nullptr;
if (device.getInfo().mVersion < CL_MAKE_VERSION(2, 0, 0)) if (!device.isVersionOrNewer(2u, 0u))
{ {
nativeQueue = mNative->getDispatch().clCreateCommandQueue( nativeQueue = mNative->getDispatch().clCreateCommandQueue(
mNative, nativeDevice, commandQueue.getProperties(), errcodeRet); mNative, nativeDevice, commandQueue.getProperties(), errcodeRet);
...@@ -93,4 +97,24 @@ CLCommandQueueImpl::Ptr CLContextCL::createCommandQueue(const cl::CommandQueue & ...@@ -93,4 +97,24 @@ CLCommandQueueImpl::Ptr CLContextCL::createCommandQueue(const cl::CommandQueue &
nativeQueue != nullptr ? new CLCommandQueueCL(commandQueue, nativeQueue) : nullptr); nativeQueue != nullptr ? new CLCommandQueueCL(commandQueue, nativeQueue) : nullptr);
} }
CLMemoryImpl::Ptr CLContextCL::createBuffer(const cl::Buffer &buffer,
size_t size,
void *hostPtr,
cl_int *errcodeRet)
{
cl_mem nativeBuffer = nullptr;
if (buffer.getProperties().empty())
{
nativeBuffer = mNative->getDispatch().clCreateBuffer(mNative, buffer.getFlags(), size,
hostPtr, errcodeRet);
}
else
{
nativeBuffer = mNative->getDispatch().clCreateBufferWithProperties(
mNative, buffer.getProperties().data(), buffer.getFlags(), size, hostPtr, errcodeRet);
}
return CLMemoryImpl::Ptr(nativeBuffer != nullptr ? new CLMemoryCL(buffer, nativeBuffer)
: nullptr);
}
} // namespace rx } // namespace rx
...@@ -25,6 +25,10 @@ class CLContextCL : public CLContextImpl ...@@ -25,6 +25,10 @@ class CLContextCL : public CLContextImpl
CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue, CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue,
cl_int *errcodeRet) override; cl_int *errcodeRet) override;
CLMemoryImpl::Ptr createBuffer(const cl::Buffer &buffer,
size_t size,
void *hostPtr,
cl_int *errcodeRet) override;
private: private:
const cl_context mNative; const cl_context mNative;
......
...@@ -42,6 +42,19 @@ bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, std::vector<T> &vec ...@@ -42,6 +42,19 @@ bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, std::vector<T> &vec
return false; return false;
} }
// This queries the OpenCL device info for value types with known size
template <typename T>
bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, T &value)
{
if (device->getDispatch().clGetDeviceInfo(device, cl::ToCLenum(name), sizeof(T), &value,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL device info for " << name;
return false;
}
return true;
}
} // namespace } // namespace
CLDeviceCL::~CLDeviceCL() CLDeviceCL::~CLDeviceCL()
...@@ -55,40 +68,46 @@ CLDeviceCL::~CLDeviceCL() ...@@ -55,40 +68,46 @@ CLDeviceCL::~CLDeviceCL()
CLDeviceImpl::Info CLDeviceCL::createInfo(cl_device_type type) const CLDeviceImpl::Info CLDeviceCL::createInfo(cl_device_type type) const
{ {
Info info(type); Info info(type);
std::vector<char> valString; std::vector<char> valString;
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Version, valString))
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes))
{ {
return Info{}; return Info{};
} }
info.mVersion = ExtractCLVersion(valString.data()); // From the OpenCL specification for info name CL_DEVICE_MAX_WORK_ITEM_SIZES:
if (info.mVersion == 0u) // "The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM."
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo
// Custom devices are currently not supported by this back end.
if (info.mMaxWorkItemSizes.size() < 3u || info.mMaxWorkItemSizes[0] == 0u ||
info.mMaxWorkItemSizes[1] == 0u || info.mMaxWorkItemSizes[2] == 0u)
{ {
ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES";
return Info{}; return Info{};
} }
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString)) if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.mMaxMemAllocSize))
{ {
return Info{}; return Info{};
} }
info.mExtensions.assign(valString.data());
RemoveUnsupportedCLExtensions(info.mExtensions);
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes)) if (!GetDeviceInfo(mNative, cl::DeviceInfo::Version, valString))
{ {
return Info{}; return Info{};
} }
// From the OpenCL specification for info name CL_DEVICE_MAX_WORK_ITEM_SIZES: info.mVersionStr.assign(valString.data());
// "The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM." info.mVersion = ExtractCLVersion(info.mVersionStr);
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo if (info.mVersion == 0u)
// Custom devices are currently not supported by this back end.
if (info.mMaxWorkItemSizes.size() < 3u || info.mMaxWorkItemSizes[0] == 0u ||
info.mMaxWorkItemSizes[1] == 0u || info.mMaxWorkItemSizes[2] == 0u)
{ {
ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES";
return Info{}; return Info{};
} }
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
{
return Info{};
}
info.mExtensions.assign(valString.data());
RemoveUnsupportedCLExtensions(info.mExtensions);
if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0) && if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties, info.mPartitionProperties) || (!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties, info.mPartitionProperties) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.mPartitionType))) !GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.mPartitionType)))
...@@ -165,8 +184,8 @@ cl_int CLDeviceCL::createSubDevices(cl::Device &device, ...@@ -165,8 +184,8 @@ cl_int CLDeviceCL::createSubDevices(cl::Device &device,
return Ptr(new CLDeviceCL(device, nativeSubDevice)); return Ptr(new CLDeviceCL(device, nativeSubDevice));
}; };
subDeviceList.emplace_back(cl::Device::CreateDevice( subDeviceList.emplace_back(cl::Device::CreateDevice(
device.getPlatform(), cl::DeviceRefPtr(&device), device.getPlatform(), &device, device.getInfo().mType & ~CL_DEVICE_TYPE_DEFAULT,
(device.getInfo().mType & ~CL_DEVICE_TYPE_DEFAULT), createImplFunc)); createImplFunc));
if (!subDeviceList.back()) if (!subDeviceList.back())
{ {
subDeviceList.clear(); subDeviceList.clear();
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryCL.cpp: Implements the class methods for CLMemoryCL.
#include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/Debug.h"
namespace rx
{
CLMemoryCL::CLMemoryCL(const cl::Memory &memory, cl_mem native)
: CLMemoryImpl(memory), mNative(native)
{}
CLMemoryCL::~CLMemoryCL()
{
if (mNative->getDispatch().clReleaseMemObject(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL memory object";
}
}
size_t CLMemoryCL::getSize() const
{
size_t size = 0u;
if (mNative->getDispatch().clGetMemObjectInfo(mNative, CL_MEM_SIZE, sizeof(size), &size,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL memory object size";
return 0u;
}
return size;
}
CLMemoryImpl::Ptr CLMemoryCL::createSubBuffer(const cl::Buffer &buffer,
size_t size,
cl_int *errcodeRet)
{
const cl_buffer_region region = {buffer.getOffset(), size};
const cl_mem nativeBuffer = mNative->getDispatch().clCreateSubBuffer(
mNative, buffer.getFlags(), CL_BUFFER_CREATE_TYPE_REGION, &region, errcodeRet);
return CLMemoryImpl::Ptr(nativeBuffer != nullptr ? new CLMemoryCL(buffer, nativeBuffer)
: nullptr);
}
} // namespace rx
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryCL.h: Defines the class interface for CLMemoryCL, implementing CLMemoryImpl.
#ifndef LIBANGLE_RENDERER_CL_CLMEMORYCL_H_
#define LIBANGLE_RENDERER_CL_CLMEMORYCL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLMemoryImpl.h"
namespace rx
{
class CLMemoryCL : public CLMemoryImpl
{
public:
CLMemoryCL(const cl::Memory &memory, cl_mem native);
~CLMemoryCL() override;
size_t getSize() const override;
CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
size_t size,
cl_int *errcodeRet) override;
private:
const cl_mem mNative;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLMEMORYCL_H_
...@@ -378,10 +378,8 @@ CLContextImpl::Ptr CLPlatformCL::createContext(const cl::Context &context, ...@@ -378,10 +378,8 @@ CLContextImpl::Ptr CLPlatformCL::createContext(const cl::Context &context,
{ {
cl_context_properties properties[] = { cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative), CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative),
userSync && mPlatform.getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0) userSync && mPlatform.isVersionOrNewer(1u, 2u) ? CL_CONTEXT_INTEROP_USER_SYNC : 0, CL_TRUE,
? CL_CONTEXT_INTEROP_USER_SYNC 0};
: 0,
CL_TRUE, 0};
std::vector<cl_device_id> nativeDevices; std::vector<cl_device_id> nativeDevices;
for (const cl::DeviceRefPtr &device : devices) for (const cl::DeviceRefPtr &device : devices)
...@@ -406,10 +404,8 @@ CLContextImpl::Ptr CLPlatformCL::createContextFromType(const cl::Context &contex ...@@ -406,10 +404,8 @@ CLContextImpl::Ptr CLPlatformCL::createContextFromType(const cl::Context &contex
{ {
cl_context_properties properties[] = { cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative), CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative),
userSync && mPlatform.getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0) userSync && mPlatform.isVersionOrNewer(1u, 2u) ? CL_CONTEXT_INTEROP_USER_SYNC : 0, CL_TRUE,
? CL_CONTEXT_INTEROP_USER_SYNC 0};
: 0,
CL_TRUE, 0};
cl_context nativeContext = mNative->getDispatch().clCreateContextFromType( cl_context nativeContext = mNative->getDispatch().clCreateContextFromType(
properties, deviceType, notify, userData, errcodeRet); properties, deviceType, notify, userData, errcodeRet);
return CLContextImpl::Ptr(nativeContext != nullptr ? new CLContextCL(context, nativeContext) return CLContextImpl::Ptr(nativeContext != nullptr ? new CLContextCL(context, nativeContext)
......
...@@ -111,6 +111,8 @@ if (angle_enable_cl) { ...@@ -111,6 +111,8 @@ if (angle_enable_cl) {
"CLContextVk.h", "CLContextVk.h",
"CLDeviceVk.cpp", "CLDeviceVk.cpp",
"CLDeviceVk.h", "CLDeviceVk.h",
"CLMemoryVk.cpp",
"CLMemoryVk.h",
"CLPlatformVk.cpp", "CLPlatformVk.cpp",
"CLPlatformVk.h", "CLPlatformVk.h",
"cl_types.h", "cl_types.h",
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryVk.cpp: Implements the class methods for CLMemoryVk.
#include "libANGLE/renderer/vulkan/CLMemoryVk.h"
namespace rx
{
CLMemoryVk::CLMemoryVk(const cl::Memory &memory) : CLMemoryImpl(memory) {}
CLMemoryVk::~CLMemoryVk() = default;
} // namespace rx
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLMemoryVk.h: Defines the class interface for CLMemoryVk, implementing CLMemoryImpl.
#ifndef LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
#include "libANGLE/renderer/vulkan/cl_types.h"
#include "libANGLE/renderer/CLMemoryImpl.h"
namespace rx
{
class CLMemoryVk : public CLMemoryImpl
{
public:
CLMemoryVk(const cl::Memory &memory);
~CLMemoryVk() override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_VALIDATIONCL_H_ #ifndef LIBANGLE_VALIDATIONCL_H_
#define LIBANGLE_VALIDATIONCL_H_ #define LIBANGLE_VALIDATIONCL_H_
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
......
...@@ -453,6 +453,7 @@ cl_includes = [ ...@@ -453,6 +453,7 @@ cl_includes = [
] ]
libangle_cl_headers = [ libangle_cl_headers = [
"src/libANGLE/CLBuffer.h",
"src/libANGLE/CLCommandQueue.h", "src/libANGLE/CLCommandQueue.h",
"src/libANGLE/CLContext.h", "src/libANGLE/CLContext.h",
"src/libANGLE/CLDevice.h", "src/libANGLE/CLDevice.h",
...@@ -468,6 +469,7 @@ libangle_cl_headers = [ ...@@ -468,6 +469,7 @@ libangle_cl_headers = [
"src/libANGLE/renderer/CLCommandQueueImpl.h", "src/libANGLE/renderer/CLCommandQueueImpl.h",
"src/libANGLE/renderer/CLContextImpl.h", "src/libANGLE/renderer/CLContextImpl.h",
"src/libANGLE/renderer/CLDeviceImpl.h", "src/libANGLE/renderer/CLDeviceImpl.h",
"src/libANGLE/renderer/CLMemoryImpl.h",
"src/libANGLE/renderer/CLPlatformImpl.h", "src/libANGLE/renderer/CLPlatformImpl.h",
"src/libANGLE/renderer/CLtypes.h", "src/libANGLE/renderer/CLtypes.h",
"src/libANGLE/validationCL.h", "src/libANGLE/validationCL.h",
...@@ -475,18 +477,21 @@ libangle_cl_headers = [ ...@@ -475,18 +477,21 @@ libangle_cl_headers = [
] ]
libangle_cl_sources = [ libangle_cl_sources = [
"src/libANGLE/CLBuffer.cpp",
"src/libANGLE/CLCommandQueue.cpp", "src/libANGLE/CLCommandQueue.cpp",
"src/libANGLE/CLContext.cpp", "src/libANGLE/CLContext.cpp",
"src/libANGLE/CLDevice.cpp", "src/libANGLE/CLDevice.cpp",
"src/libANGLE/CLEvent.cpp", "src/libANGLE/CLEvent.cpp",
"src/libANGLE/CLKernel.cpp", "src/libANGLE/CLKernel.cpp",
"src/libANGLE/CLMemory.cpp", "src/libANGLE/CLMemory.cpp",
"src/libANGLE/CLObject.cpp",
"src/libANGLE/CLPlatform.cpp", "src/libANGLE/CLPlatform.cpp",
"src/libANGLE/CLProgram.cpp", "src/libANGLE/CLProgram.cpp",
"src/libANGLE/CLSampler.cpp", "src/libANGLE/CLSampler.cpp",
"src/libANGLE/renderer/CLCommandQueueImpl.cpp", "src/libANGLE/renderer/CLCommandQueueImpl.cpp",
"src/libANGLE/renderer/CLContextImpl.cpp", "src/libANGLE/renderer/CLContextImpl.cpp",
"src/libANGLE/renderer/CLDeviceImpl.cpp", "src/libANGLE/renderer/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLMemoryImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.cpp", "src/libANGLE/renderer/CLPlatformImpl.cpp",
"src/libANGLE/validationCL.cpp", "src/libANGLE/validationCL.cpp",
] ]
......
...@@ -9,7 +9,11 @@ ...@@ -9,7 +9,11 @@
#include "libGLESv2/proc_table_cl.h" #include "libGLESv2/proc_table_cl.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLMemory.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#define WARN_NOT_SUPPORTED(command) \ #define WARN_NOT_SUPPORTED(command) \
...@@ -195,8 +199,8 @@ cl_int GetCommandQueueInfo(cl_command_queue command_queue, ...@@ -195,8 +199,8 @@ cl_int GetCommandQueueInfo(cl_command_queue command_queue,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetCommandQueueInfo); return static_cast<CommandQueue *>(command_queue)
return 0; ->getInfo(param_name, param_value_size, param_value, param_value_size_ret);
} }
cl_mem CreateBuffer(cl_context context, cl_mem CreateBuffer(cl_context context,
...@@ -205,8 +209,8 @@ cl_mem CreateBuffer(cl_context context, ...@@ -205,8 +209,8 @@ cl_mem CreateBuffer(cl_context context,
void *host_ptr, void *host_ptr,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateBuffer); return static_cast<Context *>(context)->createBuffer(nullptr, flags, size, host_ptr,
return 0; errcode_ret);
} }
cl_mem CreateBufferWithProperties(cl_context context, cl_mem CreateBufferWithProperties(cl_context context,
...@@ -216,8 +220,8 @@ cl_mem CreateBufferWithProperties(cl_context context, ...@@ -216,8 +220,8 @@ cl_mem CreateBufferWithProperties(cl_context context,
void *host_ptr, void *host_ptr,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateBufferWithProperties); return static_cast<Context *>(context)->createBuffer(properties, flags, size, host_ptr,
return 0; errcode_ret);
} }
cl_mem CreateSubBuffer(cl_mem buffer, cl_mem CreateSubBuffer(cl_mem buffer,
...@@ -226,8 +230,8 @@ cl_mem CreateSubBuffer(cl_mem buffer, ...@@ -226,8 +230,8 @@ cl_mem CreateSubBuffer(cl_mem buffer,
const void *buffer_create_info, const void *buffer_create_info,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateSubBuffer); return static_cast<Buffer *>(buffer)->createSubBuffer(flags, buffer_create_type,
return 0; buffer_create_info, errcode_ret);
} }
cl_mem CreateImage(cl_context context, cl_mem CreateImage(cl_context context,
...@@ -266,14 +270,14 @@ cl_mem CreatePipe(cl_context context, ...@@ -266,14 +270,14 @@ cl_mem CreatePipe(cl_context context,
cl_int RetainMemObject(cl_mem memobj) cl_int RetainMemObject(cl_mem memobj)
{ {
WARN_NOT_SUPPORTED(RetainMemObject); static_cast<Memory *>(memobj)->retain();
return 0; return CL_SUCCESS;
} }
cl_int ReleaseMemObject(cl_mem memobj) cl_int ReleaseMemObject(cl_mem memobj)
{ {
WARN_NOT_SUPPORTED(ReleaseMemObject); static_cast<Memory *>(memobj)->release();
return 0; return CL_SUCCESS;
} }
cl_int GetSupportedImageFormats(cl_context context, cl_int GetSupportedImageFormats(cl_context context,
...@@ -293,8 +297,8 @@ cl_int GetMemObjectInfo(cl_mem memobj, ...@@ -293,8 +297,8 @@ cl_int GetMemObjectInfo(cl_mem memobj,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetMemObjectInfo); return static_cast<Memory *>(memobj)->getInfo(param_name, param_value_size, param_value,
return 0; param_value_size_ret);
} }
cl_int GetImageInfo(cl_mem image, cl_int GetImageInfo(cl_mem image,
......
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