Commit 48b835cf by John Plate Committed by Commit Bot

CL: Implement context for front end and passthrough

Bug: angleproject:5904 Change-Id: I23b764bba87be3a51a1b5b44b13968fc572efde9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2883773Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: John Plate <jplate@google.com>
parent 39ee3640
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
namespace cl namespace cl
{ {
using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo,
const void *private_info,
size_t cb,
void *user_data);
template <typename CLObjectType> template <typename CLObjectType>
struct Dispatch struct Dispatch
{ {
......
...@@ -7,9 +7,127 @@ ...@@ -7,9 +7,127 @@
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLPlatform.h"
#include <cstring>
namespace cl namespace cl
{ {
Context::Context(const cl_icd_dispatch &dispatch) : _cl_context(dispatch) {} Context::~Context() = default;
bool Context::release()
{
const bool released = removeRef();
if (released)
{
mPlatform.destroyContext(this);
}
return released;
}
cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet)
{
cl_uint numDevices = 0u;
const void *copyValue = nullptr;
size_t copySize = 0u;
switch (name)
{
case ContextInfo::ReferenceCount:
copyValue = getRefCountPtr();
copySize = sizeof(*getRefCountPtr());
break;
case ContextInfo::NumDevices:
numDevices = static_cast<decltype(numDevices)>(mDevices.size());
copyValue = &numDevices;
copySize = sizeof(numDevices);
break;
case ContextInfo::Devices:
static_assert(sizeof(decltype(mDevices)::value_type) == sizeof(Device *),
"Device::RefList has wrong element size");
copyValue = mDevices.data();
copySize = mDevices.size() * sizeof(decltype(mDevices)::value_type);
break;
case ContextInfo::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 Context::IsValid(const Context *context)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const Platform::Ptr &platform) {
return platform->hasContext(context);
}) != platforms.cend();
}
Context::Context(Platform &platform,
PropArray &&properties,
Device::RefList &&devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
: _cl_context(platform.getDispatch()),
mPlatform(platform),
mImpl(platform.createContext(devices, ErrorCallback, this, userSync, errcodeRet)),
mProperties(std::move(properties)),
mDevices(std::move(devices)),
mNotify(notify),
mUserData(userData)
{}
Context::Context(Platform &platform,
PropArray &&properties,
cl_device_type deviceType,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
: _cl_context(platform.getDispatch()),
mPlatform(platform),
mImpl(platform.mImpl
->createContextFromType(deviceType, ErrorCallback, this, userSync, errcodeRet)),
mProperties(std::move(properties)),
mDevices(mImpl ? platform.mapDevices(mImpl->getDevices()) : Device::RefList{}),
mNotify(notify),
mUserData(userData)
{}
void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData)
{
Context *const context = static_cast<Context *>(userData);
if (!Context::IsValid(context))
{
WARN() << "Context error for invalid context";
return;
}
if (context->mNotify != nullptr)
{
context->mNotify(errinfo, privateInfo, cb, context->mUserData);
}
}
} // namespace cl } // namespace cl
...@@ -9,7 +9,11 @@ ...@@ -9,7 +9,11 @@
#ifndef LIBANGLE_CLCONTEXT_H_ #ifndef LIBANGLE_CLCONTEXT_H_
#define LIBANGLE_CLCONTEXT_H_ #define LIBANGLE_CLCONTEXT_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLRefPointer.h"
#include "libANGLE/renderer/CLContextImpl.h"
#include <list>
namespace cl namespace cl
{ {
...@@ -17,10 +21,64 @@ namespace cl ...@@ -17,10 +21,64 @@ namespace cl
class Context final : public _cl_context, public Object class Context final : public _cl_context, public Object
{ {
public: public:
Context(const cl_icd_dispatch &dispatch); using Ptr = std::unique_ptr<Context>;
~Context() = default; using PtrList = std::list<Ptr>;
using RefPtr = RefPointer<Context>;
using PropArray = std::vector<cl_context_properties>;
~Context();
Platform &getPlatform() const noexcept;
void retain() noexcept;
bool release();
cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
static bool IsValid(const Context *context);
private:
Context(Platform &platform,
PropArray &&properties,
Device::RefList &&devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
Context(Platform &platform,
PropArray &&properties,
cl_device_type deviceType,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
static void CL_CALLBACK ErrorCallback(const char *errinfo,
const void *privateInfo,
size_t cb,
void *userData);
Platform &mPlatform;
const rx::CLContextImpl::Ptr mImpl;
const PropArray mProperties;
const Device::RefList mDevices;
const ContextErrorCB mNotify;
void *const mUserData;
friend class Platform;
}; };
inline Platform &Context::getPlatform() const noexcept
{
return mPlatform;
}
inline void Context::retain() noexcept
{
addRef();
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLCONTEXT_H_ #endif // LIBANGLE_CLCONTEXT_H_
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#include <cstring>
namespace cl namespace cl
{ {
...@@ -202,7 +204,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -202,7 +204,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
sizeof(decltype(mInfo.mMaxWorkItemSizes)::value_type); sizeof(decltype(mInfo.mMaxWorkItemSizes)::value_type);
break; break;
case DeviceInfo::ILsWithVersion: case DeviceInfo::ILsWithVersion:
if (!mInfo.mIsSupportedILsWithVersion) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -211,7 +213,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -211,7 +213,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
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.mIsSupportedBuiltInKernelsWithVersion) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -220,7 +222,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -220,7 +222,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
sizeof(decltype(mInfo.mBuiltInKernelsWithVersion)::value_type); sizeof(decltype(mInfo.mBuiltInKernelsWithVersion)::value_type);
break; break;
case DeviceInfo::OpenCL_C_AllVersions: case DeviceInfo::OpenCL_C_AllVersions:
if (!mInfo.mIsSupportedOpenCL_C_AllVersions) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -229,7 +231,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -229,7 +231,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
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.mIsSupportedOpenCL_C_Features) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -242,7 +244,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -242,7 +244,7 @@ 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.mIsSupportedExtensionsWithVersion) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -251,11 +253,19 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -251,11 +253,19 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
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);
...@@ -268,10 +278,18 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v ...@@ -268,10 +278,18 @@ 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;
}
copyValue = &mParent; copyValue = &mParent;
copySize = sizeof(mParent); copySize = sizeof(mParent);
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;
...@@ -312,27 +330,39 @@ cl_int Device::createSubDevices(const cl_device_partition_property *properties, ...@@ -312,27 +330,39 @@ cl_int Device::createSubDevices(const cl_device_partition_property *properties,
{ {
numDevices = 0u; numDevices = 0u;
} }
rx::CLDeviceImpl::InitList initList; rx::CLDeviceImpl::PtrList ptrList;
const cl_int result = mImpl->createSubDevices(properties, numDevices, initList, numDevicesRet); const cl_int result = mImpl->createSubDevices(properties, numDevices, ptrList, numDevicesRet);
if (result == CL_SUCCESS) if (result == CL_SUCCESS)
{ {
while (!initList.empty()) while (!ptrList.empty())
{ {
mSubDevices.emplace_back(new Device(mPlatform, this, initList.front())); rx::CLDeviceImpl::Info info = ptrList.front()->createInfo();
if (!info.isValid())
{
return CL_INVALID_VALUE;
}
mSubDevices.emplace_back(
new Device(mPlatform, this, std::move(ptrList.front()), std::move(info)));
ptrList.pop_front();
*devices++ = mSubDevices.back().get(); *devices++ = mSubDevices.back().get();
initList.pop_front();
} }
} }
return result; return result;
} }
Device::PtrList Device::CreateDevices(Platform &platform, rx::CLDeviceImpl::InitList &&initList) Device::PtrList Device::CreateDevices(Platform &platform, rx::CLDeviceImpl::PtrList &&implList)
{ {
PtrList devices; PtrList devices;
while (!initList.empty()) while (!implList.empty())
{ {
devices.emplace_back(new Device(platform, nullptr, initList.front())); rx::CLDeviceImpl::Info info = implList.front()->createInfo();
initList.pop_front(); if (!info.isValid())
{
return Device::PtrList{};
}
devices.emplace_back(
new Device(platform, nullptr, std::move(implList.front()), std::move(info)));
implList.pop_front();
} }
return devices; return devices;
} }
...@@ -345,12 +375,15 @@ bool Device::IsValid(const Device *device) ...@@ -345,12 +375,15 @@ bool Device::IsValid(const Device *device)
}) != platforms.cend(); }) != platforms.cend();
} }
Device::Device(Platform &platform, Device *parent, rx::CLDeviceImpl::InitData &initData) Device::Device(Platform &platform,
Device *parent,
rx::CLDeviceImpl::Ptr &&impl,
rx::CLDeviceImpl::Info &&info)
: _cl_device_id(platform.getDispatch()), : _cl_device_id(platform.getDispatch()),
mPlatform(platform), mPlatform(platform),
mParent(parent), mParent(parent),
mImpl(std::move(initData.first)), mImpl(std::move(impl)),
mInfo(std::move(initData.second)) mInfo(std::move(info))
{} {}
void Device::destroySubDevice(Device *device) void Device::destroySubDevice(Device *device)
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBANGLE_CLDEVICE_H_ #define LIBANGLE_CLDEVICE_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLObject.h"
#include "libANGLE/CLRefPointer.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
namespace cl namespace cl
...@@ -20,14 +21,16 @@ class Device final : public _cl_device_id, public Object ...@@ -20,14 +21,16 @@ class Device final : public _cl_device_id, public Object
public: public:
using Ptr = std::unique_ptr<Device>; using Ptr = std::unique_ptr<Device>;
using PtrList = std::list<Ptr>; using PtrList = std::list<Ptr>;
using RefPtr = RefPointer<Device>;
using RefList = std::vector<RefPtr>;
~Device(); ~Device();
Platform &getPlatform() const; Platform &getPlatform() const noexcept;
bool isRoot() const; bool isRoot() const noexcept;
bool hasSubDevice(const Device *device) const; bool hasSubDevice(const Device *device) const;
void retain(); void retain() noexcept;
bool release(); bool release();
cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const; cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const;
...@@ -38,13 +41,16 @@ class Device final : public _cl_device_id, public Object ...@@ -38,13 +41,16 @@ class Device final : public _cl_device_id, public Object
Device **devices, Device **devices,
cl_uint *numDevicesRet); cl_uint *numDevicesRet);
static PtrList CreateDevices(Platform &platform, rx::CLDeviceImpl::InitList &&initList); static PtrList CreateDevices(Platform &platform, rx::CLDeviceImpl::PtrList &&implList);
static bool IsValid(const Device *device); static bool IsValid(const Device *device);
static bool IsValidType(cl_device_type type); static bool IsValidType(cl_device_type type);
private: private:
Device(Platform &platform, Device *parent, rx::CLDeviceImpl::InitData &initData); Device(Platform &platform,
Device *parent,
rx::CLDeviceImpl::Ptr &&impl,
rx::CLDeviceImpl::Info &&info);
void destroySubDevice(Device *device); void destroySubDevice(Device *device);
...@@ -54,14 +60,16 @@ class Device final : public _cl_device_id, public Object ...@@ -54,14 +60,16 @@ class Device final : public _cl_device_id, public Object
const rx::CLDeviceImpl::Info mInfo; const rx::CLDeviceImpl::Info mInfo;
PtrList mSubDevices; PtrList mSubDevices;
friend class Platform;
}; };
inline Platform &Device::getPlatform() const inline Platform &Device::getPlatform() const noexcept
{ {
return mPlatform; return mPlatform;
} }
inline bool Device::isRoot() const inline bool Device::isRoot() const noexcept
{ {
return mParent == nullptr; return mParent == nullptr;
} }
...@@ -73,7 +81,7 @@ inline bool Device::hasSubDevice(const Device *device) const ...@@ -73,7 +81,7 @@ inline bool Device::hasSubDevice(const Device *device) const
}) != mSubDevices.cend(); }) != mSubDevices.cend();
} }
inline void Device::retain() inline void Device::retain() noexcept
{ {
if (!isRoot()) if (!isRoot())
{ {
......
...@@ -20,17 +20,28 @@ class Object ...@@ -20,17 +20,28 @@ class Object
public: public:
// This class cannot be virtual as its derived classes need to have standard layout // This class cannot be virtual as its derived classes need to have standard layout
Object() = default; Object() = default;
~Object() { ASSERT(mRefCount == 0u); }
~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:
void addRef() { ++mRefCount; } void addRef() noexcept { ++mRefCount; }
bool removeRef() bool removeRef()
{ {
ASSERT(mRefCount > 0u); if (mRefCount == 0u)
{
WARN() << "Unreferenced object without references";
return true;
}
return --mRefCount == 0u; return --mRefCount == 0u;
} }
......
...@@ -30,7 +30,33 @@ Platform::~Platform() ...@@ -30,7 +30,33 @@ Platform::~Platform()
removeRef(); removeRef();
} }
cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *sizeRet) Device::RefList Platform::mapDevices(const rx::CLDeviceImpl::List &deviceImplList) const
{
Device::RefList devices;
for (rx::CLDeviceImpl *impl : deviceImplList)
{
auto it = mDevices.cbegin();
while (it != mDevices.cend() && (*it)->mImpl.get() != impl)
{
++it;
}
if (it != mDevices.cend())
{
devices.emplace_back(it->get());
}
else
{
ERR() << "Device not found in platform list";
}
}
if (devices.size() != deviceImplList.size())
{
devices.clear();
}
return devices;
}
cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet)
{ {
const void *copyValue = nullptr; const void *copyValue = nullptr;
size_t copySize = 0u; size_t copySize = 0u;
...@@ -46,6 +72,10 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -46,6 +72,10 @@ 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;
...@@ -62,7 +92,7 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -62,7 +92,7 @@ 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.mExtensionsWithVersion.empty()) if (mInfo.mVersion < CL_MAKE_VERSION(3, 0, 0))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -71,6 +101,10 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -71,6 +101,10 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, 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;
...@@ -93,9 +127,9 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_ ...@@ -93,9 +127,9 @@ cl_int Platform::getInfo(PlatformInfo name, size_t valueSize, void *value, size_
std::memcpy(value, copyValue, copySize); std::memcpy(value, copyValue, copySize);
} }
} }
if (sizeRet != nullptr) if (valueSizeRet != nullptr)
{ {
*sizeRet = copySize; *valueSizeRet = copySize;
} }
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -126,27 +160,96 @@ cl_int Platform::getDeviceIDs(cl_device_type deviceType, ...@@ -126,27 +160,96 @@ cl_int Platform::getDeviceIDs(cl_device_type deviceType,
return found == 0u ? CL_DEVICE_NOT_FOUND : CL_SUCCESS; return found == 0u ? CL_DEVICE_NOT_FOUND : CL_SUCCESS;
} }
Context *Platform::createContext(Context::PropArray &&properties,
cl_uint numDevices,
Device *const *devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
Device::RefList refDevices;
while (numDevices-- != 0u)
{
refDevices.emplace_back(*devices++);
}
mContexts.emplace_back(new Context(*this, std::move(properties), std::move(refDevices), notify,
userData, userSync, errcodeRet));
if (!mContexts.back()->mImpl)
{
mContexts.back()->release();
return nullptr;
}
return mContexts.back().get();
}
Context *Platform::createContextFromType(Context::PropArray &&properties,
cl_device_type deviceType,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
mContexts.emplace_back(new Context(*this, std::move(properties), deviceType, notify, userData,
userSync, errcodeRet));
if (!mContexts.back()->mImpl || mContexts.back()->mDevices.empty())
{
mContexts.back()->release();
return nullptr;
}
return mContexts.back().get();
}
void Platform::CreatePlatform(const cl_icd_dispatch &dispatch, void Platform::CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData) rx::CLPlatformImpl::InitData &initData)
{ {
rx::CLDeviceImpl::InitList deviceInitList = initData.first->getDevices(); Ptr platform(new Platform(dispatch, initData));
if (!deviceInitList.empty()) if (!platform->mDevices.empty())
{ {
GetList().emplace_back(new Platform(dispatch, initData, std::move(deviceInitList))); GetList().emplace_back(std::move(platform));
} }
} }
Platform::Platform(const cl_icd_dispatch &dispatch, Platform::Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::InitData &initData)
rx::CLPlatformImpl::InitData &initData,
rx::CLDeviceImpl::InitList &&deviceInitList)
: _cl_platform_id(dispatch), : _cl_platform_id(dispatch),
mImpl(std::move(initData.first)), mImpl(std::move(std::get<0>(initData))),
mInfo(std::move(initData.second)), mInfo(std::move(std::get<1>(initData))),
mDevices(Device::CreateDevices(*this, std::move(deviceInitList))) mDevices(Device::CreateDevices(*this, std::move(std::get<2>(initData))))
{ {
ASSERT(isCompatible(this)); ASSERT(isCompatible(this));
} }
rx::CLContextImpl::Ptr Platform::createContext(const Device::RefList &devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
rx::CLDeviceImpl::List deviceImplList;
for (const Device::RefPtr &device : devices)
{
deviceImplList.emplace_back(device->mImpl.get());
}
return mImpl->createContext(std::move(deviceImplList), notify, userData, userSync, errcodeRet);
}
void Platform::destroyContext(Context *context)
{
auto contextIt = mContexts.cbegin();
while (contextIt != mContexts.cend() && contextIt->get() != context)
{
++contextIt;
}
if (contextIt != mContexts.cend())
{
mContexts.erase(contextIt);
}
else
{
ERR() << "Context not found";
}
}
constexpr char Platform::kVendor[]; constexpr char Platform::kVendor[];
constexpr char Platform::kIcdSuffix[]; constexpr char Platform::kIcdSuffix[];
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_CLPLATFORM_H_ #ifndef LIBANGLE_CLPLATFORM_H_
#define LIBANGLE_CLPLATFORM_H_ #define LIBANGLE_CLPLATFORM_H_
#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/renderer/CLPlatformImpl.h" #include "libANGLE/renderer/CLPlatformImpl.h"
...@@ -27,14 +28,32 @@ class Platform final : public _cl_platform_id, public Object ...@@ -27,14 +28,32 @@ class Platform final : public _cl_platform_id, public Object
bool hasDevice(const Device *device) const; bool hasDevice(const Device *device) const;
const Device::PtrList &getDevices() const; const Device::PtrList &getDevices() const;
Device::RefList mapDevices(const rx::CLDeviceImpl::List &deviceImplList) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *sizeRet); bool hasContext(const Context *context) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
cl_int getDeviceIDs(cl_device_type deviceType, cl_int getDeviceIDs(cl_device_type deviceType,
cl_uint numEntries, cl_uint numEntries,
Device **devices, Device **devices,
cl_uint *numDevices) const; cl_uint *numDevices) const;
Context *createContext(Context::PropArray &&properties,
cl_uint numDevices,
Device *const *devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
Context *createContextFromType(Context::PropArray &&properties,
cl_device_type deviceType,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
static void CreatePlatform(const cl_icd_dispatch &dispatch, static void CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData); rx::CLPlatformImpl::InitData &initData);
static const PtrList &GetPlatforms(); static const PtrList &GetPlatforms();
...@@ -45,9 +64,15 @@ class Platform final : public _cl_platform_id, public Object ...@@ -45,9 +64,15 @@ class Platform final : public _cl_platform_id, public Object
static constexpr const char *GetVendor(); static constexpr const char *GetVendor();
private: private:
Platform(const cl_icd_dispatch &dispatch, Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::InitData &initData);
rx::CLPlatformImpl::InitData &initData,
rx::CLDeviceImpl::InitList &&deviceInitList); rx::CLContextImpl::Ptr createContext(const Device::RefList &devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
void destroyContext(Context *context);
static PtrList &GetList(); static PtrList &GetList();
...@@ -55,8 +80,12 @@ class Platform final : public _cl_platform_id, public Object ...@@ -55,8 +80,12 @@ class Platform final : public _cl_platform_id, public Object
const rx::CLPlatformImpl::Info mInfo; const rx::CLPlatformImpl::Info mInfo;
const Device::PtrList mDevices; const Device::PtrList mDevices;
Context::PtrList mContexts;
static constexpr char kVendor[] = "ANGLE"; static constexpr char kVendor[] = "ANGLE";
static constexpr char kIcdSuffix[] = "ANGLE"; static constexpr char kIcdSuffix[] = "ANGLE";
friend class Context;
}; };
inline bool Platform::hasDevice(const Device *device) const inline bool Platform::hasDevice(const Device *device) const
...@@ -71,6 +100,13 @@ inline const Device::PtrList &Platform::getDevices() const ...@@ -71,6 +100,13 @@ inline const Device::PtrList &Platform::getDevices() const
return mDevices; return mDevices;
} }
inline bool Platform::hasContext(const Context *context) const
{
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const Context::Ptr &ptr) {
return ptr.get() == context;
}) != mContexts.cend();
}
inline Platform::PtrList &Platform::GetList() inline Platform::PtrList &Platform::GetList()
{ {
static angle::base::NoDestructor<PtrList> sList; static angle::base::NoDestructor<PtrList> sList;
......
//
// 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.
//
// CLRefPointer.h: A non-owning intrinsic reference counting smart pointer for CL objects.
#ifndef LIBANGLE_CLREFPOINTER_H_
#define LIBANGLE_CLREFPOINTER_H_
#include "libANGLE/CLtypes.h"
#include "libANGLE/Debug.h"
#include <algorithm>
namespace cl
{
template <typename T>
class RefPointer
{
public:
RefPointer() noexcept : mCLObject(nullptr) {}
explicit RefPointer(T *object) noexcept : mCLObject(object)
{
if (mCLObject != nullptr)
{
mCLObject->retain();
}
}
~RefPointer()
{
if (mCLObject != nullptr)
{
mCLObject->release();
}
}
RefPointer(std::nullptr_t) noexcept : mCLObject(nullptr) {}
RefPointer &operator=(std::nullptr_t)
{
reset();
return *this;
}
RefPointer(RefPointer &&other) noexcept : mCLObject(nullptr) { other.swap(*this); }
RefPointer &operator=(RefPointer &&other)
{
other.swap(this);
return *this;
}
RefPointer(const RefPointer<T> &other) : mCLObject(other.mCLObject)
{
if (mCLObject != nullptr)
{
mCLObject->retain();
}
}
RefPointer &operator=(const RefPointer<T> &other)
{
if (this != &other)
{
reset();
mCLObject = other.mCLObject;
if (mCLObject != nullptr)
{
mCLObject->retain();
}
}
return *this;
}
T *operator->() const { return mCLObject; }
T &operator*() const { return *mCLObject; }
T *get() const { return mCLObject; }
explicit operator bool() const { return mCLObject != nullptr; }
T *release() noexcept
{
T *const object = mCLObject;
mCLObject = nullptr;
return object;
}
void swap(RefPointer &other) noexcept { std::swap(mCLObject, other.mCLObject); }
void reset()
{
if (mCLObject != nullptr)
{
T *const object = release();
object->release();
}
}
private:
T *mCLObject;
};
template <typename T>
void swap(RefPointer<T> &left, RefPointer<T> &right)
{
left.swap(right);
}
} // namespace cl
#endif // LIBANGLE_CLREFPOINTER_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.
//
// CLContextImpl.cpp: Implements the class methods for CLContextImpl.
#include "libANGLE/renderer/CLContextImpl.h"
#include "libANGLE/renderer/CLPlatformImpl.h"
#include "libANGLE/Debug.h"
namespace rx
{
CLContextImpl::CLContextImpl(CLPlatformImpl &platform, CLDeviceImpl::List &&devices)
: mPlatform(platform), mDevices(std::move(devices))
{}
CLContextImpl::~CLContextImpl()
{
auto it = std::find(mPlatform.mContexts.cbegin(), mPlatform.mContexts.cend(), this);
if (it != mPlatform.mContexts.cend())
{
mPlatform.mContexts.erase(it);
}
else
{
ERR() << "Context not in platform's list";
}
}
} // namespace rx
...@@ -3,13 +3,12 @@ ...@@ -3,13 +3,12 @@
// 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.
// //
// CLContextImpl.h: Defines the abstract rx::CLContextImpl class. // CLContextImpl.h: Defines the abstract rx::CLContextImpl class.
#ifndef LIBANGLE_RENDERER_CLCONTEXTIMPL_H_ #ifndef LIBANGLE_RENDERER_CLCONTEXTIMPL_H_
#define LIBANGLE_RENDERER_CLCONTEXTIMPL_H_ #define LIBANGLE_RENDERER_CLCONTEXTIMPL_H_
#include "libANGLE/renderer/CLtypes.h" #include "libANGLE/renderer/CLDeviceImpl.h"
namespace rx namespace rx
{ {
...@@ -17,10 +16,30 @@ namespace rx ...@@ -17,10 +16,30 @@ namespace rx
class CLContextImpl : angle::NonCopyable class CLContextImpl : angle::NonCopyable
{ {
public: public:
CLContextImpl() {} using Ptr = std::unique_ptr<CLContextImpl>;
virtual ~CLContextImpl() {} using List = std::list<CLContextImpl *>;
CLContextImpl(CLPlatformImpl &platform, CLDeviceImpl::List &&devices);
virtual ~CLContextImpl();
template <typename T>
T &getPlatform() const
{
return static_cast<T &>(mPlatform);
}
const CLDeviceImpl::List &getDevices() const;
protected:
CLPlatformImpl &mPlatform;
const CLDeviceImpl::List mDevices;
}; };
inline const CLDeviceImpl::List &CLContextImpl::getDevices() const
{
return mDevices;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CLCONTEXTIMPL_H_ #endif // LIBANGLE_RENDERER_CLCONTEXTIMPL_H_
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include "libANGLE/Debug.h"
namespace rx namespace rx
{ {
...@@ -18,14 +20,24 @@ CLDeviceImpl::Info::Info(Info &&) = default; ...@@ -18,14 +20,24 @@ CLDeviceImpl::Info::Info(Info &&) = default;
CLDeviceImpl::Info &CLDeviceImpl::Info::operator=(Info &&) = default; CLDeviceImpl::Info &CLDeviceImpl::Info::operator=(Info &&) = default;
bool CLDeviceImpl::Info::isValid() const CLDeviceImpl::CLDeviceImpl(CLPlatformImpl &platform, CLDeviceImpl *parent)
: mPlatform(platform), mParent(parent)
{}
CLDeviceImpl::~CLDeviceImpl()
{ {
// From the OpenCL specification for info name CL_DEVICE_MAX_WORK_ITEM_SIZES: if (mParent != nullptr)
// "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 auto it = std::find(mParent->mSubDevices.cbegin(), mParent->mSubDevices.cend(), this);
// Custom devices are currently not supported by ANGLE back ends. if (it != mParent->mSubDevices.cend())
return mMaxWorkItemSizes.size() >= 3u && mMaxWorkItemSizes[0] >= 1u && {
mMaxWorkItemSizes[1] >= 1u && mMaxWorkItemSizes[2] >= 1u; mParent->mSubDevices.erase(it);
}
else
{
ERR() << "Sub-device not in parent's list";
}
}
} }
} // namespace rx } // namespace rx
...@@ -27,8 +27,9 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -27,8 +27,9 @@ class CLDeviceImpl : angle::NonCopyable
Info(Info &&); Info(Info &&);
Info &operator=(Info &&); Info &operator=(Info &&);
bool isValid() const; bool isValid() const { return mVersion != 0u; }
cl_version mVersion = 0u;
std::vector<size_t> mMaxWorkItemSizes; std::vector<size_t> mMaxWorkItemSizes;
NameVersionVector mILsWithVersion; NameVersionVector mILsWithVersion;
NameVersionVector mBuiltInKernelsWithVersion; NameVersionVector mBuiltInKernelsWithVersion;
...@@ -38,20 +39,22 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -38,20 +39,22 @@ class CLDeviceImpl : angle::NonCopyable
NameVersionVector mExtensionsWithVersion; NameVersionVector mExtensionsWithVersion;
std::vector<cl_device_partition_property> mPartitionProperties; std::vector<cl_device_partition_property> mPartitionProperties;
std::vector<cl_device_partition_property> mPartitionType; std::vector<cl_device_partition_property> mPartitionType;
bool mIsSupportedILsWithVersion = false;
bool mIsSupportedBuiltInKernelsWithVersion = false;
bool mIsSupportedOpenCL_C_AllVersions = false;
bool mIsSupportedOpenCL_C_Features = false;
bool mIsSupportedExtensionsWithVersion = false;
}; };
using Ptr = std::unique_ptr<CLDeviceImpl>; using Ptr = std::unique_ptr<CLDeviceImpl>;
using InitData = std::pair<Ptr, Info>; using PtrList = std::list<Ptr>;
using InitList = std::list<InitData>; using List = std::list<CLDeviceImpl *>;
CLDeviceImpl(CLPlatformImpl &platform, CLDeviceImpl *parent);
virtual ~CLDeviceImpl();
template <typename T>
T &getPlatform() const
{
return static_cast<T &>(mPlatform);
}
CLDeviceImpl() = default; virtual Info createInfo() const = 0;
virtual ~CLDeviceImpl() = default;
virtual cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const = 0; virtual cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const = 0;
virtual cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const = 0; virtual cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const = 0;
...@@ -61,8 +64,14 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -61,8 +64,14 @@ class CLDeviceImpl : angle::NonCopyable
virtual cl_int createSubDevices(const cl_device_partition_property *properties, virtual cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices, cl_uint numDevices,
InitList &deviceInitList, PtrList &implList,
cl_uint *numDevicesRet) = 0; cl_uint *numDevicesRet) = 0;
protected:
CLPlatformImpl &mPlatform;
CLDeviceImpl *const mParent;
List mSubDevices;
}; };
} // namespace rx } // namespace rx
......
...@@ -18,9 +18,8 @@ CLPlatformImpl::Info::Info(Info &&) = default; ...@@ -18,9 +18,8 @@ CLPlatformImpl::Info::Info(Info &&) = default;
CLPlatformImpl::Info &CLPlatformImpl::Info::operator=(Info &&) = default; CLPlatformImpl::Info &CLPlatformImpl::Info::operator=(Info &&) = default;
bool CLPlatformImpl::Info::isValid() const CLPlatformImpl::CLPlatformImpl(CLDeviceImpl::List &&devices) : mDevices(std::move(devices)) {}
{
return !mProfile.empty(); CLPlatformImpl::~CLPlatformImpl() = default;
}
} // namespace rx } // namespace rx
...@@ -8,8 +8,11 @@ ...@@ -8,8 +8,11 @@
#ifndef LIBANGLE_RENDERER_CLPLATFORMIMPL_H_ #ifndef LIBANGLE_RENDERER_CLPLATFORMIMPL_H_
#define LIBANGLE_RENDERER_CLPLATFORMIMPL_H_ #define LIBANGLE_RENDERER_CLPLATFORMIMPL_H_
#include "libANGLE/renderer/CLContextImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include <tuple>
namespace rx namespace rx
{ {
...@@ -27,27 +30,51 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -27,27 +30,51 @@ class CLPlatformImpl : angle::NonCopyable
Info(Info &&); Info(Info &&);
Info &operator=(Info &&); Info &operator=(Info &&);
bool isValid() const; bool isValid() const { return mVersion != 0u; }
std::string mProfile; std::string mProfile;
std::string mVersionStr; std::string mVersionStr;
cl_version mVersion; cl_version mVersion = 0u;
std::string mName; std::string mName;
std::string mExtensions; std::string mExtensions;
NameVersionVector mExtensionsWithVersion; NameVersionVector mExtensionsWithVersion;
cl_ulong mHostTimerRes; cl_ulong mHostTimerRes = 0u;
}; };
using Ptr = std::unique_ptr<CLPlatformImpl>; using Ptr = std::unique_ptr<CLPlatformImpl>;
using InitData = std::pair<Ptr, Info>; using InitData = std::tuple<Ptr, Info, CLDeviceImpl::PtrList>;
using InitList = std::list<InitData>; using InitList = std::list<InitData>;
CLPlatformImpl() = default; explicit CLPlatformImpl(CLDeviceImpl::List &&devices);
virtual ~CLPlatformImpl() = default; virtual ~CLPlatformImpl();
const CLDeviceImpl::List &getDevices() const;
virtual CLContextImpl::Ptr createContext(CLDeviceImpl::List &&devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) = 0;
virtual CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) = 0;
virtual CLDeviceImpl::InitList getDevices() = 0; protected:
const CLDeviceImpl::List mDevices;
CLContextImpl::List mContexts;
friend class CLContextImpl;
}; };
inline const CLDeviceImpl::List &CLPlatformImpl::getDevices() const
{
return mDevices;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CLPLATFORMIMPL_H_ #endif // LIBANGLE_RENDERER_CLPLATFORMIMPL_H_
...@@ -15,6 +15,7 @@ _cl_backend_sources = [ ...@@ -15,6 +15,7 @@ _cl_backend_sources = [
"CLDeviceCL.h", "CLDeviceCL.h",
"CLPlatformCL.cpp", "CLPlatformCL.cpp",
"CLPlatformCL.h", "CLPlatformCL.h",
"cl_types.h",
"cl_util.cpp", "cl_util.cpp",
"cl_util.h", "cl_util.h",
] ]
......
...@@ -3,17 +3,27 @@ ...@@ -3,17 +3,27 @@
// 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.
// //
// CLContextCL.cpp: // CLContextCL.cpp: Implements the class methods for CLContextCL.
// Implements the class methods for CLContextCL.
//
#include "libANGLE/renderer/cl/CLContextCL.h" #include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/renderer/cl/CLPlatformCL.h"
#include "libANGLE/Debug.h"
namespace rx namespace rx
{ {
CLContextCL::CLContextCL() {} CLContextCL::CLContextCL(CLPlatformCL &platform, CLDeviceImpl::List &&devices, cl_context context)
: CLContextImpl(platform, std::move(devices)), mContext(context)
{}
CLContextCL::~CLContextCL() {} CLContextCL::~CLContextCL()
{
if (mContext->getDispatch().clReleaseContext(mContext) != CL_SUCCESS)
{
ERR() << "Error while releasing CL context";
}
}
} // namespace rx } // namespace rx
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
// 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.
// //
// CLContextCL.h: // CLContextCL.h: Defines the class interface for CLContextCL, implementing CLContextImpl.
// Defines the class interface for CLContextCL, implementing CLContextImpl.
//
#ifndef LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_ #ifndef LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_
#define LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_ #define LIBANGLE_RENDERER_CL_CLCONTEXTCL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLContextImpl.h"
namespace rx namespace rx
...@@ -18,8 +18,11 @@ namespace rx ...@@ -18,8 +18,11 @@ namespace rx
class CLContextCL : public CLContextImpl class CLContextCL : public CLContextImpl
{ {
public: public:
CLContextCL(); CLContextCL(CLPlatformCL &platform, CLDeviceImpl::List &&devices, cl_context context);
~CLContextCL() override; ~CLContextCL() override;
private:
const cl_context mContext;
}; };
} // namespace rx } // namespace rx
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#ifndef LIBANGLE_RENDERER_CL_CLDEVICECL_H_ #ifndef LIBANGLE_RENDERER_CL_CLDEVICECL_H_
#define LIBANGLE_RENDERER_CL_CLDEVICECL_H_ #define LIBANGLE_RENDERER_CL_CLDEVICECL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
namespace rx namespace rx
...@@ -20,6 +22,8 @@ class CLDeviceCL : public CLDeviceImpl ...@@ -20,6 +22,8 @@ class CLDeviceCL : public CLDeviceImpl
cl_device_id getNative(); cl_device_id getNative();
Info createInfo() const override;
cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const override; cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const override;
cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const override; cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const override;
cl_int getInfoSizeT(cl::DeviceInfo name, size_t *value) const override; cl_int getInfoSizeT(cl::DeviceInfo name, size_t *value) const override;
...@@ -28,14 +32,13 @@ class CLDeviceCL : public CLDeviceImpl ...@@ -28,14 +32,13 @@ class CLDeviceCL : public CLDeviceImpl
cl_int createSubDevices(const cl_device_partition_property *properties, cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices, cl_uint numDevices,
InitList &deviceInitList, PtrList &implList,
cl_uint *numDevicesRet) override; cl_uint *numDevicesRet) override;
static CLDeviceCL *Create(cl_device_id device); static CLDeviceCL *Create(CLPlatformCL &platform, CLDeviceCL *parent, cl_device_id device);
static Info GetInfo(cl_device_id device);
private: private:
CLDeviceCL(cl_device_id device, cl_version version); CLDeviceCL(CLPlatformCL &platform, CLDeviceCL *parent, cl_device_id device, cl_version version);
const cl_device_id mDevice; const cl_device_id mDevice;
const cl_version mVersion; const cl_version mVersion;
......
...@@ -20,16 +20,29 @@ class CLPlatformCL : public CLPlatformImpl ...@@ -20,16 +20,29 @@ class CLPlatformCL : public CLPlatformImpl
cl_platform_id getNative(); cl_platform_id getNative();
CLDeviceImpl::InitList getDevices() override; CLContextImpl::Ptr createContext(CLDeviceImpl::List &&deviceImplList,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
static InitList GetPlatforms(bool isIcd); static InitList GetPlatforms(bool isIcd);
private: private:
explicit CLPlatformCL(cl_platform_id platform); CLPlatformCL(cl_platform_id platform, cl_version version, CLDeviceImpl::PtrList &devices);
static Info GetInfo(cl_platform_id platform); static Info GetInfo(cl_platform_id platform);
const cl_platform_id mPlatform; const cl_platform_id mPlatform;
const cl_version mVersion;
friend class CLContextCL;
}; };
inline cl_platform_id CLPlatformCL::getNative() inline cl_platform_id CLPlatformCL::getNative()
......
//
// 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.
//
// cl_types.h: Defines common types for the OpenCL pass-through back end.
#ifndef LIBANGLE_RENDERER_CL_CL_TYPES_H_
#define LIBANGLE_RENDERER_CL_CL_TYPES_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
class CLContextCL;
class CLDeviceCL;
class CLPlatformCL;
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CL_TYPES_H_
...@@ -111,6 +111,7 @@ if (angle_enable_cl) { ...@@ -111,6 +111,7 @@ if (angle_enable_cl) {
"CLDeviceVk.h", "CLDeviceVk.h",
"CLPlatformVk.cpp", "CLPlatformVk.cpp",
"CLPlatformVk.h", "CLPlatformVk.h",
"cl_types.h",
] ]
} }
......
...@@ -3,16 +3,18 @@ ...@@ -3,16 +3,18 @@
// 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.
// //
// CLContextVk.cpp: // CLContextVk.cpp: Implements the class methods for CLContextVk.
// Implements the class methods for CLContextVk.
//
#include "libANGLE/renderer/vulkan/CLContextVk.h" #include "libANGLE/renderer/vulkan/CLContextVk.h"
#include "libANGLE/renderer/vulkan/CLPlatformVk.h"
namespace rx namespace rx
{ {
CLContextVk::CLContextVk() {} CLContextVk::CLContextVk(CLPlatformVk &platform, CLDeviceImpl::List &&devices)
: CLContextImpl(platform, std::move(devices))
{}
CLContextVk::~CLContextVk() = default; CLContextVk::~CLContextVk() = default;
......
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
// 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.
// //
// CLContextVk.h: // CLContextVk.h: Defines the class interface for CLContextVk, implementing CLContextImpl.
// Defines the class interface for CLContextVk, implementing CLContextImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_CLCONTEXTVK_H_ #ifndef LIBANGLE_RENDERER_VULKAN_CLCONTEXTVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLCONTEXTVK_H_ #define LIBANGLE_RENDERER_VULKAN_CLCONTEXTVK_H_
#include "libANGLE/renderer/vulkan/cl_types.h"
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLContextImpl.h"
namespace rx namespace rx
...@@ -18,7 +18,7 @@ namespace rx ...@@ -18,7 +18,7 @@ namespace rx
class CLContextVk : public CLContextImpl class CLContextVk : public CLContextImpl
{ {
public: public:
CLContextVk(); CLContextVk(CLPlatformVk &platform, CLDeviceImpl::List &&devices);
~CLContextVk() override; ~CLContextVk() override;
}; };
......
...@@ -7,13 +7,22 @@ ...@@ -7,13 +7,22 @@
#include "libANGLE/renderer/vulkan/CLDeviceVk.h" #include "libANGLE/renderer/vulkan/CLDeviceVk.h"
#include "libANGLE/renderer/vulkan/CLPlatformVk.h"
namespace rx namespace rx
{ {
CLDeviceVk::CLDeviceVk() = default; CLDeviceVk::CLDeviceVk(CLPlatformVk &platform, CLDeviceVk *parent) : CLDeviceImpl(platform, parent)
{}
CLDeviceVk::~CLDeviceVk() = default; CLDeviceVk::~CLDeviceVk() = default;
CLDeviceImpl::Info CLDeviceVk::createInfo() const
{
CLDeviceImpl::Info info;
return info;
}
cl_int CLDeviceVk::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const cl_int CLDeviceVk::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
...@@ -41,16 +50,10 @@ cl_int CLDeviceVk::getInfoString(cl::DeviceInfo name, size_t size, char *value) ...@@ -41,16 +50,10 @@ cl_int CLDeviceVk::getInfoString(cl::DeviceInfo name, size_t size, char *value)
cl_int CLDeviceVk::createSubDevices(const cl_device_partition_property *properties, cl_int CLDeviceVk::createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices, cl_uint numDevices,
InitList &deviceInitList, PtrList &deviceImplList,
cl_uint *numDevicesRet) cl_uint *numDevicesRet)
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
CLDeviceImpl::Info CLDeviceVk::GetInfo()
{
CLDeviceImpl::Info info;
return info;
}
} // namespace rx } // namespace rx
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#ifndef LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_ #ifndef LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_ #define LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_
#include "libANGLE/renderer/vulkan/cl_types.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
namespace rx namespace rx
...@@ -16,9 +18,11 @@ namespace rx ...@@ -16,9 +18,11 @@ namespace rx
class CLDeviceVk : public CLDeviceImpl class CLDeviceVk : public CLDeviceImpl
{ {
public: public:
CLDeviceVk(); CLDeviceVk(CLPlatformVk &platform, CLDeviceVk *parent);
~CLDeviceVk() override; ~CLDeviceVk() override;
Info createInfo() const override;
cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const override; cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const override;
cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const override; cl_int getInfoULong(cl::DeviceInfo name, cl_ulong *value) const override;
cl_int getInfoSizeT(cl::DeviceInfo name, size_t *value) const override; cl_int getInfoSizeT(cl::DeviceInfo name, size_t *value) const override;
...@@ -27,10 +31,8 @@ class CLDeviceVk : public CLDeviceImpl ...@@ -27,10 +31,8 @@ class CLDeviceVk : public CLDeviceImpl
cl_int createSubDevices(const cl_device_partition_property *properties, cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices, cl_uint numDevices,
InitList &deviceInitList, PtrList &deviceImplList,
cl_uint *numDevicesRet) override; cl_uint *numDevicesRet) override;
static Info GetInfo();
}; };
} // namespace rx } // namespace rx
......
...@@ -31,19 +31,35 @@ std::string CreateExtensionString(const NameVersionVector &extList) ...@@ -31,19 +31,35 @@ std::string CreateExtensionString(const NameVersionVector &extList)
} }
return extensions; return extensions;
} }
} // anonymous namespace
CLDeviceImpl::List CreateDevices(CLPlatformVk &platform, CLDeviceImpl::PtrList &implList)
{
implList.emplace_back(new CLDeviceVk(platform, nullptr));
return CLDeviceImpl::List(1u, implList.back().get());
}
} // namespace
CLPlatformVk::~CLPlatformVk() = default; CLPlatformVk::~CLPlatformVk() = default;
CLDeviceImpl::InitList CLPlatformVk::getDevices() CLContextImpl::Ptr CLPlatformVk::createContext(CLDeviceImpl::List &&deviceImplList,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{ {
CLDeviceImpl::InitList initList; CLContextImpl::Ptr contextImpl;
CLDeviceImpl::Info info = CLDeviceVk::GetInfo(); return contextImpl;
if (info.isValid()) }
{
initList.emplace_back(new CLDeviceVk(), std::move(info)); CLContextImpl::Ptr CLPlatformVk::createContextFromType(cl_device_type deviceType,
} cl::ContextErrorCB notify,
return initList; void *userData,
bool userSync,
cl_int *errcodeRet)
{
CLContextImpl::Ptr contextImpl;
return contextImpl;
} }
CLPlatformVk::InitList CLPlatformVk::GetPlatforms() CLPlatformVk::InitList CLPlatformVk::GetPlatforms()
...@@ -62,7 +78,15 @@ CLPlatformVk::InitList CLPlatformVk::GetPlatforms() ...@@ -62,7 +78,15 @@ CLPlatformVk::InitList CLPlatformVk::GetPlatforms()
info.mHostTimerRes = 0u; info.mHostTimerRes = 0u;
InitList initList; InitList initList;
initList.emplace_back(new CLPlatformVk, std::move(info)); if (info.isValid())
{
CLDeviceImpl::PtrList devices;
Ptr platform(new CLPlatformVk(devices));
if (!devices.empty())
{
initList.emplace_back(std::move(platform), std::move(info), std::move(devices));
}
}
return initList; return initList;
} }
...@@ -74,6 +98,8 @@ const std::string &CLPlatformVk::GetVersionString() ...@@ -74,6 +98,8 @@ const std::string &CLPlatformVk::GetVersionString()
return *sVersion; return *sVersion;
} }
CLPlatformVk::CLPlatformVk() = default; CLPlatformVk::CLPlatformVk(CLDeviceImpl::PtrList &devices)
: CLPlatformImpl(CreateDevices(*this, devices))
{}
} // namespace rx } // namespace rx
...@@ -20,14 +20,24 @@ class CLPlatformVk : public CLPlatformImpl ...@@ -20,14 +20,24 @@ class CLPlatformVk : public CLPlatformImpl
public: public:
~CLPlatformVk() override; ~CLPlatformVk() override;
CLDeviceImpl::InitList getDevices() override; CLContextImpl::Ptr createContext(CLDeviceImpl::List &&deviceImplList,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
static InitList GetPlatforms(); static InitList GetPlatforms();
static constexpr cl_version GetVersion(); static constexpr cl_version GetVersion();
static const std::string &GetVersionString(); static const std::string &GetVersionString();
private: private:
CLPlatformVk(); explicit CLPlatformVk(CLDeviceImpl::PtrList &devices);
}; };
constexpr cl_version CLPlatformVk::GetVersion() constexpr cl_version CLPlatformVk::GetVersion()
......
//
// 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.
//
// cl_types.h: Defines common types for the OpenCL Vulkan back end.
#ifndef LIBANGLE_RENDERER_VULKAN_CL_TYPES_H_
#define LIBANGLE_RENDERER_VULKAN_CL_TYPES_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
class CLContextVk;
class CLDeviceVk;
class CLPlatformVk;
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_CL_TYPES_H_
...@@ -7,8 +7,66 @@ ...@@ -7,8 +7,66 @@
#include "libANGLE/validationCL_autogen.h" #include "libANGLE/validationCL_autogen.h"
#define ANGLE_ERROR_RETURN(error, ret) \
if (errcode_ret != nullptr) \
{ \
*errcode_ret = error; \
} \
return ret
namespace cl namespace cl
{ {
namespace
{
Platform *ValidateContextProperties(const cl_context_properties *properties, cl_int *errcode_ret)
{
Platform *platform = nullptr;
bool hasUserSync = false;
if (properties != nullptr)
{
while (*properties != 0)
{
switch (*properties++)
{
case CL_CONTEXT_PLATFORM:
if (platform != nullptr)
{
ANGLE_ERROR_RETURN(CL_INVALID_PROPERTY, nullptr);
}
platform = reinterpret_cast<Platform *>(*properties++);
if (!Platform::IsValid(platform))
{
ANGLE_ERROR_RETURN(CL_INVALID_PLATFORM, nullptr);
}
break;
case CL_CONTEXT_INTEROP_USER_SYNC:
if (hasUserSync || (*properties != CL_FALSE && *properties != CL_TRUE))
{
ANGLE_ERROR_RETURN(CL_INVALID_PROPERTY, nullptr);
}
++properties;
hasUserSync = true;
break;
default:
ANGLE_ERROR_RETURN(CL_INVALID_PROPERTY, nullptr);
}
}
}
if (platform == nullptr)
{
platform = Platform::GetDefault();
if (platform == nullptr)
{
ANGLE_ERROR_RETURN(CL_INVALID_PLATFORM, nullptr);
}
}
return platform;
}
} // namespace
// CL 1.0 // CL 1.0
cl_int ValidateGetPlatformIDs(cl_uint num_entries, cl_int ValidateGetPlatformIDs(cl_uint num_entries,
Platform *const *platforms, Platform *const *platforms,
...@@ -80,7 +138,7 @@ cl_int ValidateGetDeviceInfo(const Device *device, ...@@ -80,7 +138,7 @@ cl_int ValidateGetDeviceInfo(const Device *device,
bool ValidateCreateContext(const cl_context_properties *properties, bool ValidateCreateContext(const cl_context_properties *properties,
cl_uint num_devices, cl_uint num_devices,
Device *const *devicesPacked, Device *const *devices,
void(CL_CALLBACK *pfn_notify)(const char *errinfo, void(CL_CALLBACK *pfn_notify)(const char *errinfo,
const void *private_info, const void *private_info,
size_t cb, size_t cb,
...@@ -88,6 +146,23 @@ bool ValidateCreateContext(const cl_context_properties *properties, ...@@ -88,6 +146,23 @@ bool ValidateCreateContext(const cl_context_properties *properties,
const void *user_data, const void *user_data,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
Platform *platform = ValidateContextProperties(properties, errcode_ret);
if (platform == nullptr)
{
return false;
}
if (num_devices == 0u || devices == nullptr || (pfn_notify == nullptr && user_data != nullptr))
{
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
while (num_devices-- > 0u)
{
if (!platform->hasDevice(*devices++))
{
ANGLE_ERROR_RETURN(CL_INVALID_DEVICE, false);
}
}
return true; return true;
} }
...@@ -100,25 +175,47 @@ bool ValidateCreateContextFromType(const cl_context_properties *properties, ...@@ -100,25 +175,47 @@ bool ValidateCreateContextFromType(const cl_context_properties *properties,
const void *user_data, const void *user_data,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
Platform *platform = ValidateContextProperties(properties, errcode_ret);
if (platform == nullptr)
{
return false;
}
if (!Device::IsValidType(device_type))
{
ANGLE_ERROR_RETURN(CL_INVALID_DEVICE_TYPE, false);
}
if (pfn_notify == nullptr && user_data != nullptr)
{
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
return true; return true;
} }
cl_int ValidateRetainContext(const Context *contextPacked) cl_int ValidateRetainContext(const Context *context)
{ {
return CL_SUCCESS; return Context::IsValid(context) ? CL_SUCCESS : CL_INVALID_CONTEXT;
} }
cl_int ValidateReleaseContext(const Context *contextPacked) cl_int ValidateReleaseContext(const Context *context)
{ {
return CL_SUCCESS; return Context::IsValid(context) ? CL_SUCCESS : CL_INVALID_CONTEXT;
} }
cl_int ValidateGetContextInfo(const Context *contextPacked, cl_int ValidateGetContextInfo(const Context *context,
ContextInfo param_namePacked, ContextInfo param_name,
size_t param_value_size, size_t param_value_size,
const void *param_value, const void *param_value,
const size_t *param_value_size_ret) const size_t *param_value_size_ret)
{ {
if (!Context::IsValid(context))
{
return CL_INVALID_CONTEXT;
}
if (param_name == ContextInfo::InvalidEnum ||
(param_value_size == 0u && param_value != nullptr))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
......
...@@ -462,6 +462,7 @@ libangle_cl_headers = [ ...@@ -462,6 +462,7 @@ libangle_cl_headers = [
"src/libANGLE/CLObject.h", "src/libANGLE/CLObject.h",
"src/libANGLE/CLPlatform.h", "src/libANGLE/CLPlatform.h",
"src/libANGLE/CLProgram.h", "src/libANGLE/CLProgram.h",
"src/libANGLE/CLRefPointer.h",
"src/libANGLE/CLSampler.h", "src/libANGLE/CLSampler.h",
"src/libANGLE/CLtypes.h", "src/libANGLE/CLtypes.h",
"src/libANGLE/renderer/CLContextImpl.h", "src/libANGLE/renderer/CLContextImpl.h",
...@@ -482,6 +483,7 @@ libangle_cl_sources = [ ...@@ -482,6 +483,7 @@ libangle_cl_sources = [
"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/CLContextImpl.cpp",
"src/libANGLE/renderer/CLDeviceImpl.cpp", "src/libANGLE/renderer/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.cpp", "src/libANGLE/renderer/CLPlatformImpl.cpp",
"src/libANGLE/validationCL.cpp", "src/libANGLE/validationCL.cpp",
......
...@@ -85,6 +85,41 @@ cl_int GetPlatforms(cl_uint num_entries, Platform **platforms, cl_uint *num_plat ...@@ -85,6 +85,41 @@ cl_int GetPlatforms(cl_uint num_entries, Platform **platforms, cl_uint *num_plat
return CL_SUCCESS; return CL_SUCCESS;
} }
Context::PropArray ParseContextProperties(const cl_context_properties *properties,
Platform *&platform,
bool &userSync)
{
Context::PropArray propArray;
if (properties != nullptr)
{
// Count the trailing zero
size_t propSize = 1u;
const cl_context_properties *propIt = properties;
while (*propIt != 0)
{
++propSize;
switch (*propIt++)
{
case CL_CONTEXT_PLATFORM:
platform = reinterpret_cast<Platform *>(*propIt++);
++propSize;
break;
case CL_CONTEXT_INTEROP_USER_SYNC:
userSync = *propIt++ != CL_FALSE;
++propSize;
break;
}
}
propArray.reserve(propSize);
propArray.insert(propArray.cend(), properties, properties + propSize);
}
if (platform == nullptr)
{
platform = Platform::GetDefault();
}
return propArray;
}
} // anonymous namespace } // anonymous namespace
cl_int IcdGetPlatformIDsKHR(cl_uint num_entries, Platform **platforms, cl_uint *num_platforms) cl_int IcdGetPlatformIDsKHR(cl_uint num_entries, Platform **platforms, cl_uint *num_platforms)
...@@ -175,8 +210,15 @@ Context *CreateContext(const cl_context_properties *properties, ...@@ -175,8 +210,15 @@ Context *CreateContext(const cl_context_properties *properties,
void *user_data, void *user_data,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateContext); Platform *platform = nullptr;
return 0; bool userSync = false;
Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
if (platform == nullptr)
{
return nullptr;
}
return platform->createContext(std::move(propArray), num_devices, devices, pfn_notify,
user_data, userSync, errcode_ret);
} }
Context *CreateContextFromType(const cl_context_properties *properties, Context *CreateContextFromType(const cl_context_properties *properties,
...@@ -188,20 +230,27 @@ Context *CreateContextFromType(const cl_context_properties *properties, ...@@ -188,20 +230,27 @@ Context *CreateContextFromType(const cl_context_properties *properties,
void *user_data, void *user_data,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateContextFromType); Platform *platform = nullptr;
return 0; bool userSync = false;
Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
if (platform == nullptr)
{
return nullptr;
}
return platform->createContextFromType(std::move(propArray), device_type, pfn_notify, user_data,
userSync, errcode_ret);
} }
cl_int RetainContext(Context *context) cl_int RetainContext(Context *context)
{ {
WARN_NOT_SUPPORTED(RetainContext); context->retain();
return 0; return CL_SUCCESS;
} }
cl_int ReleaseContext(Context *context) cl_int ReleaseContext(Context *context)
{ {
WARN_NOT_SUPPORTED(ReleaseContext); context->release();
return 0; return CL_SUCCESS;
} }
cl_int GetContextInfo(Context *context, cl_int GetContextInfo(Context *context,
...@@ -210,8 +259,7 @@ cl_int GetContextInfo(Context *context, ...@@ -210,8 +259,7 @@ cl_int GetContextInfo(Context *context,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetContextInfo); return context->getInfo(param_name, param_value_size, param_value, param_value_size_ret);
return 0;
} }
cl_int SetContextDestructorCallback(Context *context, cl_int SetContextDestructorCallback(Context *context,
......
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