CL: Add front end object references to back end objects

Add front end object references to back end objects, which requires
a significant amount of refactoring, because the back end objects
have to be constructed during the construction of the front end
objects, so that the references can be passed to the back end objects,
which then can be passed to the front end member initialization.
That would have been easier with inheritance than with PImpl.

Bug: angleproject:5904
Change-Id: Ib58e6a698e76987bdd63cd8088f923424d6c622b
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897249
Commit-Queue: John Plate <jplate@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
John Plate 2021-05-15 22:28:27 +01:00 коммит произвёл Commit Bot
Родитель a7ae63e479
Коммит c2fd338822
29 изменённых файлов: 588 добавлений и 741 удалений

Просмотреть файл

@ -42,9 +42,6 @@ struct Dispatch
constexpr const cl_icd_dispatch &getDispatch() { return *mDispatch; }
protected:
bool isCompatible(void *ptr) const { return ptr == &mDispatch; }
private:
// This has to be the first member to be OpenCL ICD compatible
const cl_icd_dispatch *const mDispatch;

Просмотреть файл

@ -78,21 +78,22 @@ cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t
bool Context::IsValid(const _cl_context *context)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const Platform::Ptr &platform) {
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->hasContext(context);
}) != platforms.cend();
}
Context::Context(Platform &platform,
PropArray &&properties,
Device::RefList &&devices,
DeviceRefList &&devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
: _cl_context(platform.getDispatch()),
mPlatform(platform),
mImpl(platform.createContext(devices, ErrorCallback, this, userSync, errcodeRet)),
mImpl(
platform.mImpl->createContext(*this, devices, ErrorCallback, this, userSync, errcodeRet)),
mProperties(std::move(properties)),
mDevices(std::move(devices)),
mNotify(notify),
@ -108,10 +109,14 @@ Context::Context(Platform &platform,
cl_int *errcodeRet)
: _cl_context(platform.getDispatch()),
mPlatform(platform),
mImpl(platform.mImpl
->createContextFromType(deviceType, ErrorCallback, this, userSync, errcodeRet)),
mImpl(platform.mImpl->createContextFromType(*this,
deviceType,
ErrorCallback,
this,
userSync,
errcodeRet)),
mProperties(std::move(properties)),
mDevices(mImpl ? platform.mapDevices(mImpl->getDevices()) : Device::RefList{}),
mDevices(mImpl ? mImpl->getDevices() : DeviceRefList{}),
mNotify(notify),
mUserData(userData)
{}

Просмотреть файл

@ -21,8 +21,7 @@ namespace cl
class Context final : public _cl_context, public Object
{
public:
using Ptr = std::unique_ptr<Context>;
using PtrList = std::list<Ptr>;
using PtrList = std::list<ContextPtr>;
using RefPtr = RefPointer<Context>;
using PropArray = std::vector<cl_context_properties>;
@ -40,7 +39,7 @@ class Context final : public _cl_context, public Object
private:
Context(Platform &platform,
PropArray &&properties,
Device::RefList &&devices,
DeviceRefList &&devices,
ContextErrorCB notify,
void *userData,
bool userSync,
@ -62,7 +61,7 @@ class Context final : public _cl_context, public Object
Platform &mPlatform;
const rx::CLContextImpl::Ptr mImpl;
const PropArray mProperties;
const Device::RefList mDevices;
const DeviceRefList mDevices;
const ContextErrorCB mNotify;
void *const mUserData;

Просмотреть файл

@ -273,7 +273,7 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
// Handle all mapped values
case DeviceInfo::Platform:
valPointer = &mPlatform;
valPointer = static_cast<cl_platform_id>(&mPlatform);
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
@ -282,8 +282,9 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
{
return CL_INVALID_VALUE;
}
copyValue = &mParent;
copySize = sizeof(mParent);
valPointer = static_cast<cl_device_id>(mParent.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case DeviceInfo::ReferenceCount:
if (mInfo.mVersion < CL_MAKE_VERSION(1, 2, 0))
@ -323,67 +324,49 @@ cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *v
cl_int Device::createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices,
cl_device_id *devices,
cl_device_id *subDevices,
cl_uint *numDevicesRet)
{
if (devices == nullptr)
if (subDevices == nullptr)
{
numDevices = 0u;
}
rx::CLDeviceImpl::PtrList ptrList;
const cl_int result = mImpl->createSubDevices(properties, numDevices, ptrList, numDevicesRet);
DevicePtrList subDeviceList;
const cl_int result =
mImpl->createSubDevices(*this, properties, numDevices, subDeviceList, numDevicesRet);
if (result == CL_SUCCESS)
{
while (!ptrList.empty())
for (const DevicePtr &subDevice : subDeviceList)
{
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();
*subDevices++ = subDevice.get();
}
mSubDevices.splice(mSubDevices.cend(), std::move(subDeviceList));
}
return result;
}
Device::PtrList Device::CreateDevices(Platform &platform, rx::CLDeviceImpl::PtrList &&implList)
DevicePtr Device::CreateDevice(Platform &platform,
DeviceRefPtr &&parent,
const CreateImplFunc &createImplFunc)
{
PtrList devices;
while (!implList.empty())
{
rx::CLDeviceImpl::Info info = implList.front()->createInfo();
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;
DevicePtr device(new Device(platform, std::move(parent), createImplFunc));
return device->mInfo.isValid() ? std::move(device) : DevicePtr{};
}
bool Device::IsValid(const _cl_device_id *device)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const Platform::Ptr &platform) {
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->hasDevice(device);
}) != platforms.cend();
}
Device::Device(Platform &platform,
Device *parent,
rx::CLDeviceImpl::Ptr &&impl,
rx::CLDeviceImpl::Info &&info)
Device::Device(Platform &platform, DeviceRefPtr &&parent, const CreateImplFunc &createImplFunc)
: _cl_device_id(platform.getDispatch()),
mPlatform(platform),
mParent(parent),
mImpl(std::move(impl)),
mInfo(std::move(info))
mParent(std::move(parent)),
mImpl(createImplFunc(*this)),
mInfo(mImpl->createInfo())
{}
void Device::destroySubDevice(Device *device)
@ -396,7 +379,6 @@ void Device::destroySubDevice(Device *device)
if (deviceIt != mSubDevices.cend())
{
mSubDevices.erase(deviceIt);
release();
}
else
{

Просмотреть файл

@ -10,24 +10,24 @@
#define LIBANGLE_CLDEVICE_H_
#include "libANGLE/CLObject.h"
#include "libANGLE/CLRefPointer.h"
#include "libANGLE/renderer/CLDeviceImpl.h"
#include <functional>
namespace cl
{
class Device final : public _cl_device_id, public Object
{
public:
using Ptr = std::unique_ptr<Device>;
using PtrList = std::list<Ptr>;
using RefPtr = RefPointer<Device>;
using RefList = std::vector<RefPtr>;
using CreateImplFunc = std::function<rx::CLDeviceImpl::Ptr(const cl::Device &)>;
~Device();
Platform &getPlatform() const noexcept;
bool isRoot() const noexcept;
rx::CLDeviceImpl &getImpl() const;
const rx::CLDeviceImpl::Info &getInfo() const;
bool hasSubDevice(const _cl_device_id *device) const;
void retain() noexcept;
@ -38,28 +38,27 @@ class Device final : public _cl_device_id, public Object
cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices,
cl_device_id *devices,
cl_device_id *subDevices,
cl_uint *numDevicesRet);
static PtrList CreateDevices(Platform &platform, rx::CLDeviceImpl::PtrList &&implList);
static DevicePtr CreateDevice(Platform &platform,
DeviceRefPtr &&parent,
const CreateImplFunc &createImplFunc);
static bool IsValid(const _cl_device_id *device);
static bool IsValidType(cl_device_type type);
private:
Device(Platform &platform,
Device *parent,
rx::CLDeviceImpl::Ptr &&impl,
rx::CLDeviceImpl::Info &&info);
Device(Platform &platform, DeviceRefPtr &&parent, const CreateImplFunc &createImplFunc);
void destroySubDevice(Device *device);
Platform &mPlatform;
Device *const mParent;
const DeviceRefPtr mParent;
const rx::CLDeviceImpl::Ptr mImpl;
const rx::CLDeviceImpl::Info mInfo;
PtrList mSubDevices;
DevicePtrList mSubDevices;
friend class Platform;
};
@ -71,12 +70,22 @@ inline Platform &Device::getPlatform() const noexcept
inline bool Device::isRoot() const noexcept
{
return mParent == nullptr;
return !mParent;
}
inline rx::CLDeviceImpl &Device::getImpl() const
{
return *mImpl;
}
inline const rx::CLDeviceImpl::Info &Device::getInfo() const
{
return mInfo;
}
inline bool Device::hasSubDevice(const _cl_device_id *device) const
{
return std::find_if(mSubDevices.cbegin(), mSubDevices.cend(), [=](const Device::Ptr &ptr) {
return std::find_if(mSubDevices.cbegin(), mSubDevices.cend(), [=](const DevicePtr &ptr) {
return ptr.get() == device || ptr->hasSubDevice(device);
}) != mSubDevices.cend();
}

Просмотреть файл

@ -18,7 +18,6 @@ namespace cl
class Object
{
public:
// This class cannot be virtual as its derived classes need to have standard layout
Object() = default;
~Object()

Просмотреть файл

@ -67,32 +67,6 @@ Platform::~Platform()
removeRef();
}
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;
@ -177,7 +151,7 @@ cl_int Platform::getDeviceIDs(cl_device_type deviceType,
cl_uint *numDevices) const
{
cl_uint found = 0u;
for (const Device::Ptr &device : mDevices)
for (const DevicePtr &device : mDevices)
{
cl_device_type type = 0u;
if (device->getInfoULong(DeviceInfo::Type, &type) == CL_SUCCESS &&
@ -197,6 +171,15 @@ cl_int Platform::getDeviceIDs(cl_device_type deviceType,
return found == 0u ? CL_DEVICE_NOT_FOUND : CL_SUCCESS;
}
void Platform::CreatePlatform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc)
{
PlatformPtr platform(new Platform(dispatch, createImplFunc));
if (platform->mInfo.isValid() && !platform->mDevices.empty())
{
GetList().emplace_back(std::move(platform));
}
}
cl_int Platform::GetPlatformIDs(cl_uint num_entries,
cl_platform_id *platforms,
cl_uint *num_platforms)
@ -229,7 +212,7 @@ cl_context Platform::CreateContext(const cl_context_properties *properties,
bool userSync = false;
Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
ASSERT(platform != nullptr);
Device::RefList refDevices;
DeviceRefList refDevices;
while (numDevices-- != 0u)
{
refDevices.emplace_back(static_cast<Device *>(*devices++));
@ -267,38 +250,12 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti
return platform->mContexts.back().get();
}
void Platform::CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData)
{
Ptr platform(new Platform(dispatch, initData));
if (!platform->mDevices.empty())
{
GetList().emplace_back(std::move(platform));
}
}
Platform::Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::InitData &initData)
Platform::Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc)
: _cl_platform_id(dispatch),
mImpl(std::move(std::get<0>(initData))),
mInfo(std::move(std::get<1>(initData))),
mDevices(Device::CreateDevices(*this, std::move(std::get<2>(initData))))
{
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);
}
mImpl(createImplFunc(*this)),
mInfo(mImpl->createInfo()),
mDevices(mImpl->createDevices(*this))
{}
void Platform::destroyContext(Context *context)
{

Просмотреть файл

@ -15,21 +15,22 @@
#include "anglebase/no_destructor.h"
#include <functional>
namespace cl
{
class Platform final : public _cl_platform_id, public Object
{
public:
using Ptr = std::unique_ptr<Platform>;
using PtrList = std::list<Ptr>;
using PtrList = std::list<PlatformPtr>;
using CreateImplFunc = std::function<rx::CLPlatformImpl::Ptr(const cl::Platform &)>;
~Platform();
const rx::CLPlatformImpl::Info &getInfo() const;
bool hasDevice(const _cl_device_id *device) const;
const Device::PtrList &getDevices() const;
Device::RefList mapDevices(const rx::CLDeviceImpl::List &deviceImplList) const;
const DevicePtrList &getDevices() const;
bool hasContext(const _cl_context *context) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
@ -39,6 +40,9 @@ class Platform final : public _cl_platform_id, public Object
cl_device_id *devices,
cl_uint *numDevices) const;
static void CreatePlatform(const cl_icd_dispatch &dispatch,
const CreateImplFunc &createImplFunc);
static cl_int GetPlatformIDs(cl_uint num_entries,
cl_platform_id *platforms,
cl_uint *num_platforms);
@ -56,26 +60,16 @@ class Platform final : public _cl_platform_id, public Object
void *userData,
cl_int *errcodeRet);
static void CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData);
static const PtrList &GetPlatforms();
static Platform *GetDefault();
static Platform *CastOrDefault(cl_platform_id platform);
static bool IsValid(const _cl_platform_id *platform);
static bool IsValidOrDefault(const _cl_platform_id *platform);
static constexpr const char *GetVendor();
private:
Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::InitData &initData);
rx::CLContextImpl::Ptr createContext(const Device::RefList &devices,
ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet);
Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc);
void destroyContext(Context *context);
@ -83,7 +77,7 @@ class Platform final : public _cl_platform_id, public Object
const rx::CLPlatformImpl::Ptr mImpl;
const rx::CLPlatformImpl::Info mInfo;
const Device::PtrList mDevices;
const DevicePtrList mDevices;
Context::PtrList mContexts;
@ -93,21 +87,26 @@ class Platform final : public _cl_platform_id, public Object
friend class Context;
};
inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
{
return mInfo;
}
inline bool Platform::hasDevice(const _cl_device_id *device) const
{
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const Device::Ptr &ptr) {
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const DevicePtr &ptr) {
return ptr.get() == device || ptr->hasSubDevice(device);
}) != mDevices.cend();
}
inline const Device::PtrList &Platform::getDevices() const
inline const DevicePtrList &Platform::getDevices() const
{
return mDevices;
}
inline bool Platform::hasContext(const _cl_context *context) const
{
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const Context::Ptr &ptr) {
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const ContextPtr &ptr) {
return ptr.get() == context;
}) != mContexts.cend();
}
@ -136,8 +135,9 @@ inline Platform *Platform::CastOrDefault(cl_platform_id platform)
inline bool Platform::IsValid(const _cl_platform_id *platform)
{
const PtrList &platforms = GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(),
[=](const Ptr &ptr) { return ptr.get() == platform; }) != platforms.cend();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &ptr) {
return ptr.get() == platform;
}) != platforms.cend();
}
// Our CL implementation defines that a nullptr value chooses the platform that we provide as

Просмотреть файл

@ -8,9 +8,6 @@
#ifndef LIBANGLE_CLREFPOINTER_H_
#define LIBANGLE_CLREFPOINTER_H_
#include "libANGLE/CLtypes.h"
#include "libANGLE/Debug.h"
#include <algorithm>
namespace cl

Просмотреть файл

@ -8,7 +8,7 @@
#ifndef LIBANGLE_CLTYPES_H_
#define LIBANGLE_CLTYPES_H_
#include "angle_cl.h"
#include "libANGLE/CLRefPointer.h"
#include "common/PackedCLEnums_autogen.h"
@ -22,6 +22,7 @@
namespace cl
{
class CommandQueue;
class Context;
class Device;
@ -32,6 +33,22 @@ class Object;
class Platform;
class Program;
class Sampler;
using CommandQueuePtr = std::unique_ptr<CommandQueue>;
using ContextPtr = std::unique_ptr<Context>;
using DevicePtr = std::unique_ptr<Device>;
using EventPtr = std::unique_ptr<Event>;
using KernelPtr = std::unique_ptr<Kernel>;
using MemoryPtr = std::unique_ptr<Memory>;
using ObjectPtr = std::unique_ptr<Object>;
using PlatformPtr = std::unique_ptr<Platform>;
using ProgramPtr = std::unique_ptr<Program>;
using SamplerPtr = std::unique_ptr<Sampler>;
using DevicePtrList = std::list<DevicePtr>;
using DeviceRefPtr = RefPointer<Device>;
using DeviceRefList = std::vector<DeviceRefPtr>;
} // namespace cl
#endif // LIBANGLE_CLTYPES_H_

Просмотреть файл

@ -7,28 +7,11 @@
#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(const cl::Context &context) : mContext(context) {}
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";
}
}
CLContextImpl::~CLContextImpl() = default;
} // namespace rx

Просмотреть файл

@ -16,30 +16,17 @@ namespace rx
class CLContextImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLContextImpl>;
using List = std::list<CLContextImpl *>;
using Ptr = std::unique_ptr<CLContextImpl>;
CLContextImpl(CLPlatformImpl &platform, CLDeviceImpl::List &&devices);
CLContextImpl(const cl::Context &context);
virtual ~CLContextImpl();
template <typename T>
T &getPlatform() const
{
return static_cast<T &>(mPlatform);
}
const CLDeviceImpl::List &getDevices() const;
virtual cl::DeviceRefList getDevices() const = 0;
protected:
CLPlatformImpl &mPlatform;
const CLDeviceImpl::List mDevices;
const cl::Context &mContext;
};
inline const CLDeviceImpl::List &CLContextImpl::getDevices() const
{
return mDevices;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CLCONTEXTIMPL_H_

Просмотреть файл

@ -20,24 +20,8 @@ CLDeviceImpl::Info::Info(Info &&) = default;
CLDeviceImpl::Info &CLDeviceImpl::Info::operator=(Info &&) = default;
CLDeviceImpl::CLDeviceImpl(CLPlatformImpl &platform, CLDeviceImpl *parent)
: mPlatform(platform), mParent(parent)
{}
CLDeviceImpl::CLDeviceImpl(const cl::Device &device) : mDevice(device) {}
CLDeviceImpl::~CLDeviceImpl()
{
if (mParent != nullptr)
{
auto it = std::find(mParent->mSubDevices.cbegin(), mParent->mSubDevices.cend(), this);
if (it != mParent->mSubDevices.cend())
{
mParent->mSubDevices.erase(it);
}
else
{
ERR() << "Sub-device not in parent's list";
}
}
}
CLDeviceImpl::~CLDeviceImpl() = default;
} // namespace rx

Просмотреть файл

@ -16,6 +16,8 @@ namespace rx
class CLDeviceImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLDeviceImpl>;
struct Info
{
Info();
@ -41,19 +43,9 @@ class CLDeviceImpl : angle::NonCopyable
std::vector<cl_device_partition_property> mPartitionType;
};
using Ptr = std::unique_ptr<CLDeviceImpl>;
using PtrList = std::list<Ptr>;
using List = std::list<CLDeviceImpl *>;
CLDeviceImpl(CLPlatformImpl &platform, CLDeviceImpl *parent);
CLDeviceImpl(const cl::Device &device);
virtual ~CLDeviceImpl();
template <typename T>
T &getPlatform() const
{
return static_cast<T &>(mPlatform);
}
virtual Info createInfo() const = 0;
virtual cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *value) const = 0;
@ -62,16 +54,14 @@ class CLDeviceImpl : angle::NonCopyable
virtual cl_int getInfoStringLength(cl::DeviceInfo name, size_t *value) const = 0;
virtual cl_int getInfoString(cl::DeviceInfo name, size_t size, char *value) const = 0;
virtual cl_int createSubDevices(const cl_device_partition_property *properties,
virtual cl_int createSubDevices(cl::Device &device,
const cl_device_partition_property *properties,
cl_uint numDevices,
PtrList &implList,
cl::DevicePtrList &subDeviceList,
cl_uint *numDevicesRet) = 0;
protected:
CLPlatformImpl &mPlatform;
CLDeviceImpl *const mParent;
List mSubDevices;
const cl::Device &mDevice;
};
} // namespace rx

Просмотреть файл

@ -18,7 +18,7 @@ CLPlatformImpl::Info::Info(Info &&) = default;
CLPlatformImpl::Info &CLPlatformImpl::Info::operator=(Info &&) = default;
CLPlatformImpl::CLPlatformImpl(CLDeviceImpl::List &&devices) : mDevices(std::move(devices)) {}
CLPlatformImpl::CLPlatformImpl(const cl::Platform &platform) : mPlatform(platform) {}
CLPlatformImpl::~CLPlatformImpl() = default;

Просмотреть файл

@ -19,6 +19,8 @@ namespace rx
class CLPlatformImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLPlatformImpl>;
struct Info
{
Info();
@ -41,40 +43,31 @@ class CLPlatformImpl : angle::NonCopyable
cl_ulong mHostTimerRes = 0u;
};
using Ptr = std::unique_ptr<CLPlatformImpl>;
using InitData = std::tuple<Ptr, Info, CLDeviceImpl::PtrList>;
using InitList = std::list<InitData>;
explicit CLPlatformImpl(CLDeviceImpl::List &&devices);
explicit CLPlatformImpl(const cl::Platform &platform);
virtual ~CLPlatformImpl();
const CLDeviceImpl::List &getDevices() const;
// For initialization only
virtual Info createInfo() const = 0;
virtual cl::DevicePtrList createDevices(cl::Platform &platform) const = 0;
virtual CLContextImpl::Ptr createContext(CLDeviceImpl::List &&devices,
virtual CLContextImpl::Ptr createContext(const cl::Context &context,
const cl::DeviceRefList &devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) = 0;
virtual CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
virtual CLContextImpl::Ptr createContextFromType(const cl::Context &context,
cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) = 0;
protected:
const CLDeviceImpl::List mDevices;
CLContextImpl::List mContexts;
friend class CLContextImpl;
const cl::Platform &mPlatform;
};
inline const CLDeviceImpl::List &CLPlatformImpl::getDevices() const
{
return mDevices;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CLPLATFORMIMPL_H_

Просмотреть файл

@ -7,23 +7,66 @@
#include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/renderer/cl/CLPlatformCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLPlatform.h"
#include "libANGLE/Debug.h"
namespace rx
{
CLContextCL::CLContextCL(CLPlatformCL &platform, CLDeviceImpl::List &&devices, cl_context context)
: CLContextImpl(platform, std::move(devices)), mContext(context)
CLContextCL::CLContextCL(const cl::Context &context, cl_context native)
: CLContextImpl(context), mNative(native)
{}
CLContextCL::~CLContextCL()
{
if (mContext->getDispatch().clReleaseContext(mContext) != CL_SUCCESS)
if (mNative->getDispatch().clReleaseContext(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL context";
}
}
cl::DeviceRefList CLContextCL::getDevices() const
{
size_t valueSize = 0u;
cl_int result = mNative->getDispatch().clGetContextInfo(mNative, CL_CONTEXT_DEVICES, 0u,
nullptr, &valueSize);
if (result == CL_SUCCESS && (valueSize % sizeof(cl_device_id)) == 0u)
{
std::vector<cl_device_id> nativeDevices(valueSize / sizeof(cl_device_id), nullptr);
result = mNative->getDispatch().clGetContextInfo(mNative, CL_CONTEXT_DEVICES, valueSize,
nativeDevices.data(), nullptr);
if (result == CL_SUCCESS)
{
const cl::DevicePtrList &platformDevices = mContext.getPlatform().getDevices();
cl::DeviceRefList devices;
for (cl_device_id nativeDevice : nativeDevices)
{
auto it = platformDevices.cbegin();
while (it != platformDevices.cend() &&
static_cast<CLDeviceCL &>((*it)->getImpl()).getNative() != nativeDevice)
{
++it;
}
if (it != platformDevices.cend())
{
devices.emplace_back(it->get());
}
else
{
ERR() << "Device not found in platform list";
return cl::DeviceRefList{};
}
}
return devices;
}
}
ERR() << "Error fetching devices from CL context, code: " << result;
return cl::DeviceRefList{};
}
} // namespace rx

Просмотреть файл

@ -18,11 +18,13 @@ namespace rx
class CLContextCL : public CLContextImpl
{
public:
CLContextCL(CLPlatformCL &platform, CLDeviceImpl::List &&devices, cl_context context);
CLContextCL(const cl::Context &context, cl_context native);
~CLContextCL() override;
cl::DeviceRefList getDevices() const override;
private:
const cl_context mContext;
const cl_context mNative;
};
} // namespace rx

Просмотреть файл

@ -10,6 +10,7 @@
#include "libANGLE/renderer/cl/CLPlatformCL.h"
#include "libANGLE/renderer/cl/cl_util.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/Debug.h"
namespace rx
@ -45,8 +46,7 @@ bool GetDeviceInfo(cl_device_id device, cl::DeviceInfo name, std::vector<T> &vec
CLDeviceCL::~CLDeviceCL()
{
if (mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
mDevice->getDispatch().clReleaseDevice(mDevice) != CL_SUCCESS)
if (!mDevice.isRoot() && mNative->getDispatch().clReleaseDevice(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL device";
}
@ -55,17 +55,26 @@ CLDeviceCL::~CLDeviceCL()
CLDeviceImpl::Info CLDeviceCL::createInfo() const
{
Info info;
info.mVersion = mVersion;
std::vector<char> valString;
if (!GetDeviceInfo(mDevice, cl::DeviceInfo::Extensions, valString))
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Version, valString))
{
return Info{};
}
info.mVersion = ExtractCLVersion(valString.data());
if (info.mVersion == 0u)
{
return Info{};
}
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
{
return Info{};
}
info.mExtensions.assign(valString.data());
RemoveUnsupportedCLExtensions(info.mExtensions);
if (!GetDeviceInfo(mDevice, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes))
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes))
{
return Info{};
}
@ -80,21 +89,21 @@ CLDeviceImpl::Info CLDeviceCL::createInfo() const
return Info{};
}
if (mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
(!GetDeviceInfo(mDevice, cl::DeviceInfo::PartitionProperties, info.mPartitionProperties) ||
!GetDeviceInfo(mDevice, cl::DeviceInfo::PartitionType, info.mPartitionType)))
if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties, info.mPartitionProperties) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.mPartitionType)))
{
return Info{};
}
if (mVersion >= CL_MAKE_VERSION(3, 0, 0) &&
(!GetDeviceInfo(mDevice, cl::DeviceInfo::ILsWithVersion, info.mILsWithVersion) ||
!GetDeviceInfo(mDevice, cl::DeviceInfo::BuiltInKernelsWithVersion,
if (info.mVersion >= CL_MAKE_VERSION(3, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.mILsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernelsWithVersion,
info.mBuiltInKernelsWithVersion) ||
!GetDeviceInfo(mDevice, cl::DeviceInfo::OpenCL_C_AllVersions,
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions,
info.mOpenCL_C_AllVersions) ||
!GetDeviceInfo(mDevice, cl::DeviceInfo::OpenCL_C_Features, info.mOpenCL_C_Features) ||
!GetDeviceInfo(mDevice, cl::DeviceInfo::ExtensionsWithVersion,
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.mOpenCL_C_Features) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExtensionsWithVersion,
info.mExtensionsWithVersion)))
{
return Info{};
@ -106,93 +115,69 @@ CLDeviceImpl::Info CLDeviceCL::createInfo() const
cl_int CLDeviceCL::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), sizeof(*value),
return mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
value, nullptr);
}
cl_int CLDeviceCL::getInfoULong(cl::DeviceInfo name, cl_ulong *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), sizeof(*value),
return mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
value, nullptr);
}
cl_int CLDeviceCL::getInfoSizeT(cl::DeviceInfo name, size_t *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), sizeof(*value),
return mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), sizeof(*value),
value, nullptr);
}
cl_int CLDeviceCL::getInfoStringLength(cl::DeviceInfo name, size_t *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), 0u, nullptr, value);
return mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), 0u, nullptr, value);
}
cl_int CLDeviceCL::getInfoString(cl::DeviceInfo name, size_t size, char *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), size, value,
return mNative->getDispatch().clGetDeviceInfo(mNative, cl::ToCLenum(name), size, value,
nullptr);
}
cl_int CLDeviceCL::createSubDevices(const cl_device_partition_property *properties,
cl_int CLDeviceCL::createSubDevices(cl::Device &device,
const cl_device_partition_property *properties,
cl_uint numDevices,
PtrList &implList,
cl::DevicePtrList &subDeviceList,
cl_uint *numDevicesRet)
{
if (mVersion < CL_MAKE_VERSION(1, 2, 0))
{
return CL_INVALID_VALUE;
}
if (numDevices == 0u)
{
return mDevice->getDispatch().clCreateSubDevices(mDevice, properties, 0u, nullptr,
return mNative->getDispatch().clCreateSubDevices(mNative, properties, 0u, nullptr,
numDevicesRet);
}
std::vector<cl_device_id> devices(numDevices, nullptr);
const cl_int result = mDevice->getDispatch().clCreateSubDevices(mDevice, properties, numDevices,
devices.data(), nullptr);
std::vector<cl_device_id> nativeSubDevices(numDevices, nullptr);
const cl_int result = mNative->getDispatch().clCreateSubDevices(
mNative, properties, numDevices, nativeSubDevices.data(), nullptr);
if (result == CL_SUCCESS)
{
for (cl_device_id device : devices)
for (cl_device_id nativeSubDevice : nativeSubDevices)
{
implList.emplace_back(CLDeviceCL::Create(getPlatform<CLPlatformCL>(), this, device));
if (!implList.back())
const cl::Device::CreateImplFunc createImplFunc = [&](const cl::Device &device) {
return Ptr(new CLDeviceCL(device, nativeSubDevice));
};
subDeviceList.emplace_back(cl::Device::CreateDevice(
device.getPlatform(), cl::DeviceRefPtr(&device), createImplFunc));
if (!subDeviceList.back())
{
implList.clear();
subDeviceList.clear();
return CL_INVALID_VALUE;
}
mSubDevices.emplace_back(implList.back().get());
}
}
return result;
}
CLDeviceCL *CLDeviceCL::Create(CLPlatformCL &platform, CLDeviceCL *parent, cl_device_id device)
{
size_t valueSize = 0u;
if (device->getDispatch().clGetDeviceInfo(device, CL_DEVICE_VERSION, 0u, nullptr, &valueSize) ==
CL_SUCCESS)
{
std::vector<char> valString(valueSize, '\0');
if (device->getDispatch().clGetDeviceInfo(device, CL_DEVICE_VERSION, valueSize,
valString.data(), nullptr) == CL_SUCCESS)
{
const cl_version version = ExtractCLVersion(valString.data());
if (version != 0u)
{
return new CLDeviceCL(platform, parent, device, version);
}
}
}
ERR() << "Failed to query version for device";
return nullptr;
}
CLDeviceCL::CLDeviceCL(CLPlatformCL &platform,
CLDeviceCL *parent,
cl_device_id device,
cl_version version)
: CLDeviceImpl(platform, parent), mDevice(device), mVersion(version)
CLDeviceCL::CLDeviceCL(const cl::Device &device, cl_device_id native)
: CLDeviceImpl(device), mNative(native)
{}
} // namespace rx

Просмотреть файл

@ -30,23 +30,23 @@ class CLDeviceCL : public CLDeviceImpl
cl_int getInfoStringLength(cl::DeviceInfo name, size_t *value) const override;
cl_int getInfoString(cl::DeviceInfo name, size_t size, char *value) const override;
cl_int createSubDevices(const cl_device_partition_property *properties,
cl_int createSubDevices(cl::Device &device,
const cl_device_partition_property *properties,
cl_uint numDevices,
PtrList &implList,
cl::DevicePtrList &subDeviceList,
cl_uint *numDevicesRet) override;
static CLDeviceCL *Create(CLPlatformCL &platform, CLDeviceCL *parent, cl_device_id device);
private:
CLDeviceCL(CLPlatformCL &platform, CLDeviceCL *parent, cl_device_id device, cl_version version);
CLDeviceCL(const cl::Device &device, cl_device_id native);
const cl_device_id mDevice;
const cl_version mVersion;
const cl_device_id mNative;
friend class CLPlatformCL;
};
inline cl_device_id CLDeviceCL::getNative()
{
return mDevice;
return mNative;
}
} // namespace rx

Просмотреть файл

@ -27,45 +27,6 @@ namespace rx
namespace
{
CLDeviceImpl::List CreateDevices(CLPlatformCL &platform,
cl_platform_id native,
CLDeviceImpl::PtrList &implPtrList)
{
CLDeviceImpl::List implList;
// Fetch all regular devices. This does not include CL_DEVICE_TYPE_CUSTOM, which are not
// supported by the CL pass-through back end because they have no standard feature set.
// This makes them unreliable for the purpose of this back end.
cl_uint numDevices = 0u;
if (native->getDispatch().clGetDeviceIDs(native, CL_DEVICE_TYPE_ALL, 0u, nullptr,
&numDevices) == CL_SUCCESS)
{
std::vector<cl_device_id> devices(numDevices, nullptr);
if (native->getDispatch().clGetDeviceIDs(native, CL_DEVICE_TYPE_ALL, numDevices,
devices.data(), nullptr) == CL_SUCCESS)
{
for (cl_device_id device : devices)
{
CLDeviceImpl::Ptr impl(CLDeviceCL::Create(platform, nullptr, device));
if (!impl)
{
implList.clear();
implPtrList.clear();
break;
}
implList.emplace_back(impl.get());
implPtrList.emplace_back(std::move(impl));
}
}
}
if (implList.empty())
{
ERR() << "Failed to query CL devices";
}
return implList;
}
std::string GetPlatformString(cl_platform_id platform, cl::PlatformInfo name)
{
size_t size = 0u;
@ -87,247 +48,74 @@ std::string GetPlatformString(cl_platform_id platform, cl::PlatformInfo name)
CLPlatformCL::~CLPlatformCL() = default;
CLContextImpl::Ptr CLPlatformCL::createContext(CLDeviceImpl::List &&deviceImplList,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mPlatform),
userSync && mVersion >= CL_MAKE_VERSION(1, 2, 0) ? CL_CONTEXT_INTEROP_USER_SYNC : 0,
CL_TRUE, 0};
std::vector<cl_device_id> devices;
for (CLDeviceImpl *deviceImpl : deviceImplList)
{
devices.emplace_back(static_cast<CLDeviceCL *>(deviceImpl)->getNative());
}
CLContextImpl::Ptr contextImpl;
cl_context context =
mPlatform->getDispatch().clCreateContext(properties, static_cast<cl_uint>(devices.size()),
devices.data(), notify, userData, errcodeRet);
if (context != nullptr)
{
contextImpl.reset(new CLContextCL(*this, std::move(deviceImplList), context));
mContexts.emplace_back(contextImpl.get());
}
return contextImpl;
}
CLContextImpl::Ptr CLPlatformCL::createContextFromType(cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mPlatform),
userSync && mVersion >= CL_MAKE_VERSION(1, 2, 0) ? CL_CONTEXT_INTEROP_USER_SYNC : 0,
CL_TRUE, 0};
cl_context context = mPlatform->getDispatch().clCreateContextFromType(
properties, deviceType, notify, userData, errcodeRet);
if (context == nullptr)
{
return CLContextImpl::Ptr{};
}
size_t valueSize = 0u;
cl_int result = context->getDispatch().clGetContextInfo(context, CL_CONTEXT_DEVICES, 0u,
nullptr, &valueSize);
if (result == CL_SUCCESS && (valueSize % sizeof(cl_device_id)) == 0u)
{
std::vector<cl_device_id> devices(valueSize / sizeof(cl_device_id), nullptr);
result = context->getDispatch().clGetContextInfo(context, CL_CONTEXT_DEVICES, valueSize,
devices.data(), nullptr);
if (result == CL_SUCCESS)
{
CLDeviceImpl::List deviceImplList;
for (cl_device_id device : devices)
{
auto it = mDevices.cbegin();
while (it != mDevices.cend() &&
static_cast<CLDeviceCL *>(*it)->getNative() != device)
{
++it;
}
if (it != mDevices.cend())
{
deviceImplList.emplace_back(*it);
}
else
{
ERR() << "Device not found in platform list";
}
}
if (deviceImplList.size() == devices.size())
{
CLContextImpl::Ptr contextImpl(
new CLContextCL(*this, std::move(deviceImplList), context));
mContexts.emplace_back(contextImpl.get());
return contextImpl;
}
result = CL_INVALID_VALUE;
}
}
context->getDispatch().clReleaseContext(context);
if (errcodeRet != nullptr)
{
*errcodeRet = result;
}
return CLContextImpl::Ptr{};
}
CLPlatformCL::InitList CLPlatformCL::GetPlatforms(bool isIcd)
{
// Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to enumerate the
// available OpenCL implementations on the system. They will be stored in the singly linked
// list khrIcdVendors of the C struct KHRicdVendor.
if (khrIcdVendors == nullptr)
{
// Our OpenCL entry points are not reentrant, so we have to prevent khrIcdInitialize()
// from querying ANGLE's OpenCL library. We store a dummy entry with the library in the
// khrIcdVendors list, because the ICD Loader skips the libraries which are already in
// the list as it assumes they were already enumerated.
static angle::base::NoDestructor<KHRicdVendor> sVendorAngle({});
sVendorAngle->library = khrIcdOsLibraryLoad(ANGLE_OPENCL_LIB_NAME);
khrIcdVendors = sVendorAngle.get();
if (khrIcdVendors->library != nullptr)
{
khrIcdInitialize();
// After the enumeration we don't need ANGLE's OpenCL library any more,
// but we keep the dummy entry int the list to prevent another enumeration.
khrIcdOsLibraryUnload(khrIcdVendors->library);
khrIcdVendors->library = nullptr;
}
}
// Iterating through the singly linked list khrIcdVendors to create an ANGLE CL pass-through
// platform for each found ICD platform. Skipping our dummy entry that has an invalid platform.
InitList initList;
for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next)
{
if (vendorIt->platform != nullptr)
{
Info info = GetInfo(vendorIt->platform);
if (info.isValid())
{
CLDeviceImpl::PtrList devices;
Ptr platform(new CLPlatformCL(vendorIt->platform, info.mVersion, devices));
if (!devices.empty())
{
initList.emplace_back(std::move(platform), std::move(info), std::move(devices));
}
}
}
}
return initList;
}
CLPlatformCL::CLPlatformCL(cl_platform_id platform,
cl_version version,
CLDeviceImpl::PtrList &devices)
: CLPlatformImpl(CreateDevices(*this, platform, devices)),
mPlatform(platform),
mVersion(version)
{}
#define ANGLE_GET_INFO_SIZE(name, size_ret) \
platform->getDispatch().clGetPlatformInfo(platform, name, 0u, nullptr, size_ret)
#define ANGLE_GET_INFO_SIZE_RET(name, size_ret) \
do \
{ \
if (ANGLE_GET_INFO_SIZE(name, size_ret) != CL_SUCCESS) \
{ \
ERR() << "Failed to query CL platform info for " << name; \
return info; \
} \
} while (0)
#define ANGLE_GET_INFO(name, size, param) \
platform->getDispatch().clGetPlatformInfo(platform, name, size, param, nullptr)
#define ANGLE_GET_INFO_RET(name, size, param) \
do \
{ \
if (ANGLE_GET_INFO(name, size, param) != CL_SUCCESS) \
{ \
ERR() << "Failed to query CL platform info for " << name; \
return info; \
} \
} while (0)
CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
CLPlatformImpl::Info CLPlatformCL::createInfo() const
{
// Verify that the platform is valid
if (platform == nullptr || platform->getDispatch().clGetPlatformIDs == nullptr ||
platform->getDispatch().clGetPlatformInfo == nullptr ||
platform->getDispatch().clGetDeviceIDs == nullptr ||
platform->getDispatch().clGetDeviceInfo == nullptr ||
platform->getDispatch().clCreateContext == nullptr ||
platform->getDispatch().clCreateContextFromType == nullptr ||
platform->getDispatch().clRetainContext == nullptr ||
platform->getDispatch().clReleaseContext == nullptr ||
platform->getDispatch().clGetContextInfo == nullptr ||
platform->getDispatch().clCreateCommandQueue == nullptr ||
platform->getDispatch().clRetainCommandQueue == nullptr ||
platform->getDispatch().clReleaseCommandQueue == nullptr ||
platform->getDispatch().clGetCommandQueueInfo == nullptr ||
platform->getDispatch().clSetCommandQueueProperty == nullptr ||
platform->getDispatch().clCreateBuffer == nullptr ||
platform->getDispatch().clCreateImage2D == nullptr ||
platform->getDispatch().clCreateImage3D == nullptr ||
platform->getDispatch().clRetainMemObject == nullptr ||
platform->getDispatch().clReleaseMemObject == nullptr ||
platform->getDispatch().clGetSupportedImageFormats == nullptr ||
platform->getDispatch().clGetMemObjectInfo == nullptr ||
platform->getDispatch().clGetImageInfo == nullptr ||
platform->getDispatch().clCreateSampler == nullptr ||
platform->getDispatch().clRetainSampler == nullptr ||
platform->getDispatch().clReleaseSampler == nullptr ||
platform->getDispatch().clGetSamplerInfo == nullptr ||
platform->getDispatch().clCreateProgramWithSource == nullptr ||
platform->getDispatch().clCreateProgramWithBinary == nullptr ||
platform->getDispatch().clRetainProgram == nullptr ||
platform->getDispatch().clReleaseProgram == nullptr ||
platform->getDispatch().clBuildProgram == nullptr ||
platform->getDispatch().clUnloadCompiler == nullptr ||
platform->getDispatch().clGetProgramInfo == nullptr ||
platform->getDispatch().clGetProgramBuildInfo == nullptr ||
platform->getDispatch().clCreateKernel == nullptr ||
platform->getDispatch().clCreateKernelsInProgram == nullptr ||
platform->getDispatch().clRetainKernel == nullptr ||
platform->getDispatch().clReleaseKernel == nullptr ||
platform->getDispatch().clSetKernelArg == nullptr ||
platform->getDispatch().clGetKernelInfo == nullptr ||
platform->getDispatch().clGetKernelWorkGroupInfo == nullptr ||
platform->getDispatch().clWaitForEvents == nullptr ||
platform->getDispatch().clGetEventInfo == nullptr ||
platform->getDispatch().clRetainEvent == nullptr ||
platform->getDispatch().clReleaseEvent == nullptr ||
platform->getDispatch().clGetEventProfilingInfo == nullptr ||
platform->getDispatch().clFlush == nullptr || platform->getDispatch().clFinish == nullptr ||
platform->getDispatch().clEnqueueReadBuffer == nullptr ||
platform->getDispatch().clEnqueueWriteBuffer == nullptr ||
platform->getDispatch().clEnqueueCopyBuffer == nullptr ||
platform->getDispatch().clEnqueueReadImage == nullptr ||
platform->getDispatch().clEnqueueWriteImage == nullptr ||
platform->getDispatch().clEnqueueCopyImage == nullptr ||
platform->getDispatch().clEnqueueCopyImageToBuffer == nullptr ||
platform->getDispatch().clEnqueueCopyBufferToImage == nullptr ||
platform->getDispatch().clEnqueueMapBuffer == nullptr ||
platform->getDispatch().clEnqueueMapImage == nullptr ||
platform->getDispatch().clEnqueueUnmapMemObject == nullptr ||
platform->getDispatch().clEnqueueNDRangeKernel == nullptr ||
platform->getDispatch().clEnqueueTask == nullptr ||
platform->getDispatch().clEnqueueNativeKernel == nullptr ||
platform->getDispatch().clEnqueueMarker == nullptr ||
platform->getDispatch().clEnqueueWaitForEvents == nullptr ||
platform->getDispatch().clEnqueueBarrier == nullptr ||
platform->getDispatch().clGetExtensionFunctionAddress == nullptr)
if (mNative == nullptr || mNative->getDispatch().clGetPlatformIDs == nullptr ||
mNative->getDispatch().clGetPlatformInfo == nullptr ||
mNative->getDispatch().clGetDeviceIDs == nullptr ||
mNative->getDispatch().clGetDeviceInfo == nullptr ||
mNative->getDispatch().clCreateContext == nullptr ||
mNative->getDispatch().clCreateContextFromType == nullptr ||
mNative->getDispatch().clRetainContext == nullptr ||
mNative->getDispatch().clReleaseContext == nullptr ||
mNative->getDispatch().clGetContextInfo == nullptr ||
mNative->getDispatch().clCreateCommandQueue == nullptr ||
mNative->getDispatch().clRetainCommandQueue == nullptr ||
mNative->getDispatch().clReleaseCommandQueue == nullptr ||
mNative->getDispatch().clGetCommandQueueInfo == nullptr ||
mNative->getDispatch().clSetCommandQueueProperty == nullptr ||
mNative->getDispatch().clCreateBuffer == nullptr ||
mNative->getDispatch().clCreateImage2D == nullptr ||
mNative->getDispatch().clCreateImage3D == nullptr ||
mNative->getDispatch().clRetainMemObject == nullptr ||
mNative->getDispatch().clReleaseMemObject == nullptr ||
mNative->getDispatch().clGetSupportedImageFormats == nullptr ||
mNative->getDispatch().clGetMemObjectInfo == nullptr ||
mNative->getDispatch().clGetImageInfo == nullptr ||
mNative->getDispatch().clCreateSampler == nullptr ||
mNative->getDispatch().clRetainSampler == nullptr ||
mNative->getDispatch().clReleaseSampler == nullptr ||
mNative->getDispatch().clGetSamplerInfo == nullptr ||
mNative->getDispatch().clCreateProgramWithSource == nullptr ||
mNative->getDispatch().clCreateProgramWithBinary == nullptr ||
mNative->getDispatch().clRetainProgram == nullptr ||
mNative->getDispatch().clReleaseProgram == nullptr ||
mNative->getDispatch().clBuildProgram == nullptr ||
mNative->getDispatch().clUnloadCompiler == nullptr ||
mNative->getDispatch().clGetProgramInfo == nullptr ||
mNative->getDispatch().clGetProgramBuildInfo == nullptr ||
mNative->getDispatch().clCreateKernel == nullptr ||
mNative->getDispatch().clCreateKernelsInProgram == nullptr ||
mNative->getDispatch().clRetainKernel == nullptr ||
mNative->getDispatch().clReleaseKernel == nullptr ||
mNative->getDispatch().clSetKernelArg == nullptr ||
mNative->getDispatch().clGetKernelInfo == nullptr ||
mNative->getDispatch().clGetKernelWorkGroupInfo == nullptr ||
mNative->getDispatch().clWaitForEvents == nullptr ||
mNative->getDispatch().clGetEventInfo == nullptr ||
mNative->getDispatch().clRetainEvent == nullptr ||
mNative->getDispatch().clReleaseEvent == nullptr ||
mNative->getDispatch().clGetEventProfilingInfo == nullptr ||
mNative->getDispatch().clFlush == nullptr || mNative->getDispatch().clFinish == nullptr ||
mNative->getDispatch().clEnqueueReadBuffer == nullptr ||
mNative->getDispatch().clEnqueueWriteBuffer == nullptr ||
mNative->getDispatch().clEnqueueCopyBuffer == nullptr ||
mNative->getDispatch().clEnqueueReadImage == nullptr ||
mNative->getDispatch().clEnqueueWriteImage == nullptr ||
mNative->getDispatch().clEnqueueCopyImage == nullptr ||
mNative->getDispatch().clEnqueueCopyImageToBuffer == nullptr ||
mNative->getDispatch().clEnqueueCopyBufferToImage == nullptr ||
mNative->getDispatch().clEnqueueMapBuffer == nullptr ||
mNative->getDispatch().clEnqueueMapImage == nullptr ||
mNative->getDispatch().clEnqueueUnmapMemObject == nullptr ||
mNative->getDispatch().clEnqueueNDRangeKernel == nullptr ||
mNative->getDispatch().clEnqueueTask == nullptr ||
mNative->getDispatch().clEnqueueNativeKernel == nullptr ||
mNative->getDispatch().clEnqueueMarker == nullptr ||
mNative->getDispatch().clEnqueueWaitForEvents == nullptr ||
mNative->getDispatch().clEnqueueBarrier == nullptr ||
mNative->getDispatch().clGetExtensionFunctionAddress == nullptr)
{
ERR() << "Missing entry points for OpenCL 1.0";
return Info{};
@ -335,11 +123,11 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
// Fetch common platform info
Info info;
const std::string vendor = GetPlatformString(platform, cl::PlatformInfo::Vendor);
info.mProfile = GetPlatformString(platform, cl::PlatformInfo::Profile);
info.mVersionStr = GetPlatformString(platform, cl::PlatformInfo::Version);
info.mName = GetPlatformString(platform, cl::PlatformInfo::Name);
info.mExtensions = GetPlatformString(platform, cl::PlatformInfo::Extensions);
const std::string vendor = GetPlatformString(mNative, cl::PlatformInfo::Vendor);
info.mProfile = GetPlatformString(mNative, cl::PlatformInfo::Profile);
info.mVersionStr = GetPlatformString(mNative, cl::PlatformInfo::Version);
info.mName = GetPlatformString(mNative, cl::PlatformInfo::Name);
info.mExtensions = GetPlatformString(mNative, cl::PlatformInfo::Extensions);
if (vendor.empty() || info.mProfile.empty() || info.mVersionStr.empty() || info.mName.empty() ||
info.mExtensions.empty())
@ -373,9 +161,9 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
RemoveUnsupportedCLExtensions(info.mExtensions);
if (version >= CL_MAKE_VERSION(2, 1, 0) &&
platform->getDispatch().clGetPlatformInfo(platform, CL_PLATFORM_HOST_TIMER_RESOLUTION,
sizeof(info.mHostTimerRes), &info.mHostTimerRes,
nullptr) != CL_SUCCESS)
mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_HOST_TIMER_RESOLUTION,
sizeof(info.mHostTimerRes), &info.mHostTimerRes,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_HOST_TIMER_RESOLUTION";
return Info{};
@ -387,9 +175,9 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
}
else
{
if (platform->getDispatch().clGetPlatformInfo(platform, CL_PLATFORM_NUMERIC_VERSION,
sizeof(info.mVersion), &info.mVersion,
nullptr) != CL_SUCCESS)
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_NUMERIC_VERSION,
sizeof(info.mVersion), &info.mVersion,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_NUMERIC_VERSION";
return Info{};
@ -403,8 +191,8 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
}
size_t valueSize = 0u;
if (platform->getDispatch().clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
0u, nullptr, &valueSize) != CL_SUCCESS ||
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
0u, nullptr, &valueSize) != CL_SUCCESS ||
(valueSize % sizeof(decltype(info.mExtensionsWithVersion)::value_type)) != 0u)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
@ -412,9 +200,9 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
}
info.mExtensionsWithVersion.resize(
valueSize / sizeof(decltype(info.mExtensionsWithVersion)::value_type));
if (platform->getDispatch().clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
valueSize, info.mExtensionsWithVersion.data(),
nullptr) != CL_SUCCESS)
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
valueSize, info.mExtensionsWithVersion.data(),
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
return Info{};
@ -423,84 +211,84 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
}
if (info.mVersion >= CL_MAKE_VERSION(1, 1, 0) &&
(platform->getDispatch().clSetEventCallback == nullptr ||
platform->getDispatch().clCreateSubBuffer == nullptr ||
platform->getDispatch().clSetMemObjectDestructorCallback == nullptr ||
platform->getDispatch().clCreateUserEvent == nullptr ||
platform->getDispatch().clSetUserEventStatus == nullptr ||
platform->getDispatch().clEnqueueReadBufferRect == nullptr ||
platform->getDispatch().clEnqueueWriteBufferRect == nullptr ||
platform->getDispatch().clEnqueueCopyBufferRect == nullptr))
(mNative->getDispatch().clSetEventCallback == nullptr ||
mNative->getDispatch().clCreateSubBuffer == nullptr ||
mNative->getDispatch().clSetMemObjectDestructorCallback == nullptr ||
mNative->getDispatch().clCreateUserEvent == nullptr ||
mNative->getDispatch().clSetUserEventStatus == nullptr ||
mNative->getDispatch().clEnqueueReadBufferRect == nullptr ||
mNative->getDispatch().clEnqueueWriteBufferRect == nullptr ||
mNative->getDispatch().clEnqueueCopyBufferRect == nullptr))
{
ERR() << "Missing entry points for OpenCL 1.1";
return info;
}
if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
(platform->getDispatch().clCreateSubDevices == nullptr ||
platform->getDispatch().clRetainDevice == nullptr ||
platform->getDispatch().clReleaseDevice == nullptr ||
platform->getDispatch().clCreateImage == nullptr ||
platform->getDispatch().clCreateProgramWithBuiltInKernels == nullptr ||
platform->getDispatch().clCompileProgram == nullptr ||
platform->getDispatch().clLinkProgram == nullptr ||
platform->getDispatch().clUnloadPlatformCompiler == nullptr ||
platform->getDispatch().clGetKernelArgInfo == nullptr ||
platform->getDispatch().clEnqueueFillBuffer == nullptr ||
platform->getDispatch().clEnqueueFillImage == nullptr ||
platform->getDispatch().clEnqueueMigrateMemObjects == nullptr ||
platform->getDispatch().clEnqueueMarkerWithWaitList == nullptr ||
platform->getDispatch().clEnqueueBarrierWithWaitList == nullptr ||
platform->getDispatch().clGetExtensionFunctionAddressForPlatform == nullptr))
(mNative->getDispatch().clCreateSubDevices == nullptr ||
mNative->getDispatch().clRetainDevice == nullptr ||
mNative->getDispatch().clReleaseDevice == nullptr ||
mNative->getDispatch().clCreateImage == nullptr ||
mNative->getDispatch().clCreateProgramWithBuiltInKernels == nullptr ||
mNative->getDispatch().clCompileProgram == nullptr ||
mNative->getDispatch().clLinkProgram == nullptr ||
mNative->getDispatch().clUnloadPlatformCompiler == nullptr ||
mNative->getDispatch().clGetKernelArgInfo == nullptr ||
mNative->getDispatch().clEnqueueFillBuffer == nullptr ||
mNative->getDispatch().clEnqueueFillImage == nullptr ||
mNative->getDispatch().clEnqueueMigrateMemObjects == nullptr ||
mNative->getDispatch().clEnqueueMarkerWithWaitList == nullptr ||
mNative->getDispatch().clEnqueueBarrierWithWaitList == nullptr ||
mNative->getDispatch().clGetExtensionFunctionAddressForPlatform == nullptr))
{
ERR() << "Missing entry points for OpenCL 1.2";
return info;
}
if (info.mVersion >= CL_MAKE_VERSION(2, 0, 0) &&
(platform->getDispatch().clCreateCommandQueueWithProperties == nullptr ||
platform->getDispatch().clCreatePipe == nullptr ||
platform->getDispatch().clGetPipeInfo == nullptr ||
platform->getDispatch().clSVMAlloc == nullptr ||
platform->getDispatch().clSVMFree == nullptr ||
platform->getDispatch().clEnqueueSVMFree == nullptr ||
platform->getDispatch().clEnqueueSVMMemcpy == nullptr ||
platform->getDispatch().clEnqueueSVMMemFill == nullptr ||
platform->getDispatch().clEnqueueSVMMap == nullptr ||
platform->getDispatch().clEnqueueSVMUnmap == nullptr ||
platform->getDispatch().clCreateSamplerWithProperties == nullptr ||
platform->getDispatch().clSetKernelArgSVMPointer == nullptr ||
platform->getDispatch().clSetKernelExecInfo == nullptr))
(mNative->getDispatch().clCreateCommandQueueWithProperties == nullptr ||
mNative->getDispatch().clCreatePipe == nullptr ||
mNative->getDispatch().clGetPipeInfo == nullptr ||
mNative->getDispatch().clSVMAlloc == nullptr ||
mNative->getDispatch().clSVMFree == nullptr ||
mNative->getDispatch().clEnqueueSVMFree == nullptr ||
mNative->getDispatch().clEnqueueSVMMemcpy == nullptr ||
mNative->getDispatch().clEnqueueSVMMemFill == nullptr ||
mNative->getDispatch().clEnqueueSVMMap == nullptr ||
mNative->getDispatch().clEnqueueSVMUnmap == nullptr ||
mNative->getDispatch().clCreateSamplerWithProperties == nullptr ||
mNative->getDispatch().clSetKernelArgSVMPointer == nullptr ||
mNative->getDispatch().clSetKernelExecInfo == nullptr))
{
ERR() << "Missing entry points for OpenCL 2.0";
return info;
}
if (info.mVersion >= CL_MAKE_VERSION(2, 1, 0) &&
(platform->getDispatch().clCloneKernel == nullptr ||
platform->getDispatch().clCreateProgramWithIL == nullptr ||
platform->getDispatch().clEnqueueSVMMigrateMem == nullptr ||
platform->getDispatch().clGetDeviceAndHostTimer == nullptr ||
platform->getDispatch().clGetHostTimer == nullptr ||
platform->getDispatch().clGetKernelSubGroupInfo == nullptr ||
platform->getDispatch().clSetDefaultDeviceCommandQueue == nullptr))
(mNative->getDispatch().clCloneKernel == nullptr ||
mNative->getDispatch().clCreateProgramWithIL == nullptr ||
mNative->getDispatch().clEnqueueSVMMigrateMem == nullptr ||
mNative->getDispatch().clGetDeviceAndHostTimer == nullptr ||
mNative->getDispatch().clGetHostTimer == nullptr ||
mNative->getDispatch().clGetKernelSubGroupInfo == nullptr ||
mNative->getDispatch().clSetDefaultDeviceCommandQueue == nullptr))
{
ERR() << "Missing entry points for OpenCL 2.1";
return info;
}
if (info.mVersion >= CL_MAKE_VERSION(2, 2, 0) &&
(platform->getDispatch().clSetProgramReleaseCallback == nullptr ||
platform->getDispatch().clSetProgramSpecializationConstant == nullptr))
(mNative->getDispatch().clSetProgramReleaseCallback == nullptr ||
mNative->getDispatch().clSetProgramSpecializationConstant == nullptr))
{
ERR() << "Missing entry points for OpenCL 2.2";
return info;
}
if (info.mVersion >= CL_MAKE_VERSION(3, 0, 0) &&
(platform->getDispatch().clCreateBufferWithProperties == nullptr ||
platform->getDispatch().clCreateImageWithProperties == nullptr ||
platform->getDispatch().clSetContextDestructorCallback == nullptr))
(mNative->getDispatch().clCreateBufferWithProperties == nullptr ||
mNative->getDispatch().clCreateImageWithProperties == nullptr ||
mNative->getDispatch().clSetContextDestructorCallback == nullptr))
{
ERR() << "Missing entry points for OpenCL 3.0";
return info;
@ -509,4 +297,135 @@ CLPlatformImpl::Info CLPlatformCL::GetInfo(cl_platform_id platform)
return info;
}
cl::DevicePtrList CLPlatformCL::createDevices(cl::Platform &platform) const
{
cl::DevicePtrList devices;
// Fetch all regular devices. This does not include CL_DEVICE_TYPE_CUSTOM, which are not
// supported by the CL pass-through back end because they have no standard feature set.
// This makes them unreliable for the purpose of this back end.
cl_uint numDevices = 0u;
if (mNative->getDispatch().clGetDeviceIDs(mNative, CL_DEVICE_TYPE_ALL, 0u, nullptr,
&numDevices) == CL_SUCCESS)
{
std::vector<cl_device_id> nativeDevices(numDevices, nullptr);
if (mNative->getDispatch().clGetDeviceIDs(mNative, CL_DEVICE_TYPE_ALL, numDevices,
nativeDevices.data(), nullptr) == CL_SUCCESS)
{
for (cl_device_id nativeDevice : nativeDevices)
{
const cl::Device::CreateImplFunc createImplFunc = [&](const cl::Device &device) {
return CLDeviceCL::Ptr(new CLDeviceCL(device, nativeDevice));
};
devices.emplace_back(cl::Device::CreateDevice(platform, nullptr, createImplFunc));
if (!devices.back())
{
devices.clear();
break;
}
}
}
}
if (devices.empty())
{
ERR() << "Failed to query CL devices";
}
return devices;
}
CLContextImpl::Ptr CLPlatformCL::createContext(const cl::Context &context,
const cl::DeviceRefList &devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative),
userSync && mPlatform.getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0)
? CL_CONTEXT_INTEROP_USER_SYNC
: 0,
CL_TRUE, 0};
std::vector<cl_device_id> nativeDevices;
for (const cl::DeviceRefPtr &device : devices)
{
nativeDevices.emplace_back(static_cast<CLDeviceCL &>(device->getImpl()).getNative());
}
CLContextImpl::Ptr contextImpl;
cl_context nativeContext = mNative->getDispatch().clCreateContext(
properties, static_cast<cl_uint>(nativeDevices.size()), nativeDevices.data(), notify,
userData, errcodeRet);
return CLContextImpl::Ptr(nativeContext != nullptr ? new CLContextCL(context, nativeContext)
: nullptr);
}
CLContextImpl::Ptr CLPlatformCL::createContextFromType(const cl::Context &context,
cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(mNative),
userSync && mPlatform.getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0)
? CL_CONTEXT_INTEROP_USER_SYNC
: 0,
CL_TRUE, 0};
cl_context nativeContext = mNative->getDispatch().clCreateContextFromType(
properties, deviceType, notify, userData, errcodeRet);
return CLContextImpl::Ptr(nativeContext != nullptr ? new CLContextCL(context, nativeContext)
: nullptr);
}
void CLPlatformCL::Initialize(const cl_icd_dispatch &dispatch, bool isIcd)
{
// Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to enumerate the
// available OpenCL implementations on the system. They will be stored in the singly linked
// list khrIcdVendors of the C struct KHRicdVendor.
if (khrIcdVendors != nullptr)
{
return;
}
// Our OpenCL entry points are not reentrant, so we have to prevent khrIcdInitialize()
// from querying ANGLE's OpenCL library. We store a dummy entry with the library in the
// khrIcdVendors list, because the ICD Loader skips the libraries which are already in
// the list as it assumes they were already enumerated.
static angle::base::NoDestructor<KHRicdVendor> sVendorAngle({});
sVendorAngle->library = khrIcdOsLibraryLoad(ANGLE_OPENCL_LIB_NAME);
khrIcdVendors = sVendorAngle.get();
if (khrIcdVendors->library == nullptr)
{
WARN() << "Unable to load library \"" ANGLE_OPENCL_LIB_NAME "\"";
return;
}
khrIcdInitialize();
// After the enumeration we don't need ANGLE's OpenCL library any more,
// but we keep the dummy entry int the list to prevent another enumeration.
khrIcdOsLibraryUnload(khrIcdVendors->library);
khrIcdVendors->library = nullptr;
// Iterating through the singly linked list khrIcdVendors to create an ANGLE CL pass-through
// platform for each found ICD platform. Skipping our dummy entry that has an invalid platform.
for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next)
{
if (vendorIt->platform != nullptr)
{
const cl::Platform::CreateImplFunc createImplFunc = [&](const cl::Platform &platform) {
return Ptr(new CLPlatformCL(platform, vendorIt->platform));
};
cl::Platform::CreatePlatform(dispatch, createImplFunc);
}
}
}
CLPlatformCL::CLPlatformCL(const cl::Platform &platform, cl_platform_id native)
: CLPlatformImpl(platform), mNative(native)
{}
} // namespace rx

Просмотреть файл

@ -20,34 +20,36 @@ class CLPlatformCL : public CLPlatformImpl
cl_platform_id getNative();
CLContextImpl::Ptr createContext(CLDeviceImpl::List &&deviceImplList,
Info createInfo() const override;
cl::DevicePtrList createDevices(cl::Platform &platform) const override;
CLContextImpl::Ptr createContext(const cl::Context &context,
const cl::DeviceRefList &devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
CLContextImpl::Ptr createContextFromType(const cl::Context &context,
cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
static InitList GetPlatforms(bool isIcd);
static void Initialize(const cl_icd_dispatch &dispatch, bool isIcd);
private:
CLPlatformCL(cl_platform_id platform, cl_version version, CLDeviceImpl::PtrList &devices);
CLPlatformCL(const cl::Platform &platform, cl_platform_id native);
static Info GetInfo(cl_platform_id platform);
const cl_platform_id mPlatform;
const cl_version mVersion;
const cl_platform_id mNative;
friend class CLContextCL;
};
inline cl_platform_id CLPlatformCL::getNative()
{
return mPlatform;
return mNative;
}
} // namespace rx

Просмотреть файл

@ -7,14 +7,10 @@
#include "libANGLE/renderer/vulkan/CLContextVk.h"
#include "libANGLE/renderer/vulkan/CLPlatformVk.h"
namespace rx
{
CLContextVk::CLContextVk(CLPlatformVk &platform, CLDeviceImpl::List &&devices)
: CLContextImpl(platform, std::move(devices))
{}
CLContextVk::CLContextVk(const cl::Context &context) : CLContextImpl(context) {}
CLContextVk::~CLContextVk() = default;

Просмотреть файл

@ -18,7 +18,7 @@ namespace rx
class CLContextVk : public CLContextImpl
{
public:
CLContextVk(CLPlatformVk &platform, CLDeviceImpl::List &&devices);
CLContextVk(const cl::Context &context);
~CLContextVk() override;
};

Просмотреть файл

@ -12,8 +12,7 @@
namespace rx
{
CLDeviceVk::CLDeviceVk(CLPlatformVk &platform, CLDeviceVk *parent) : CLDeviceImpl(platform, parent)
{}
CLDeviceVk::CLDeviceVk(const cl::Device &device) : CLDeviceImpl(device) {}
CLDeviceVk::~CLDeviceVk() = default;
@ -48,9 +47,10 @@ cl_int CLDeviceVk::getInfoString(cl::DeviceInfo name, size_t size, char *value)
return CL_INVALID_VALUE;
}
cl_int CLDeviceVk::createSubDevices(const cl_device_partition_property *properties,
cl_int CLDeviceVk::createSubDevices(cl::Device &device,
const cl_device_partition_property *properties,
cl_uint numDevices,
PtrList &deviceImplList,
cl::DevicePtrList &subDeviceList,
cl_uint *numDevicesRet)
{
return CL_INVALID_VALUE;

Просмотреть файл

@ -18,7 +18,7 @@ namespace rx
class CLDeviceVk : public CLDeviceImpl
{
public:
CLDeviceVk(CLPlatformVk &platform, CLDeviceVk *parent);
explicit CLDeviceVk(const cl::Device &device);
~CLDeviceVk() override;
Info createInfo() const override;
@ -29,9 +29,10 @@ class CLDeviceVk : public CLDeviceImpl
cl_int getInfoStringLength(cl::DeviceInfo name, size_t *value) const override;
cl_int getInfoString(cl::DeviceInfo name, size_t size, char *value) const override;
cl_int createSubDevices(const cl_device_partition_property *properties,
cl_int createSubDevices(cl::Device &device,
const cl_device_partition_property *properties,
cl_uint numDevices,
PtrList &deviceImplList,
cl::DevicePtrList &subDeviceList,
cl_uint *numDevicesRet) override;
};

Просмотреть файл

@ -9,6 +9,8 @@
#include "libANGLE/renderer/vulkan/CLDeviceVk.h"
#include "libANGLE/CLPlatform.h"
#include "anglebase/no_destructor.h"
#include "common/angle_version.h"
@ -17,6 +19,7 @@ namespace rx
namespace
{
std::string CreateExtensionString(const NameVersionVector &extList)
{
std::string extensions;
@ -32,37 +35,11 @@ std::string CreateExtensionString(const NameVersionVector &extList)
return extensions;
}
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;
CLContextImpl::Ptr CLPlatformVk::createContext(CLDeviceImpl::List &&deviceImplList,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
CLContextImpl::Ptr contextImpl;
return contextImpl;
}
CLContextImpl::Ptr CLPlatformVk::createContextFromType(cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
CLContextImpl::Ptr contextImpl;
return contextImpl;
}
CLPlatformVk::InitList CLPlatformVk::GetPlatforms()
CLPlatformImpl::Info CLPlatformVk::createInfo() const
{
NameVersionVector extList = {
cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_icd"},
@ -76,18 +53,51 @@ CLPlatformVk::InitList CLPlatformVk::GetPlatforms()
info.mExtensions.assign(CreateExtensionString(extList));
info.mExtensionsWithVersion = std::move(extList);
info.mHostTimerRes = 0u;
return info;
}
InitList initList;
if (info.isValid())
cl::DevicePtrList CLPlatformVk::createDevices(cl::Platform &platform) const
{
cl::DevicePtrList devices;
const cl::Device::CreateImplFunc createImplFunc = [](const cl::Device &device) {
return CLDeviceVk::Ptr(new CLDeviceVk(device));
};
devices.emplace_back(cl::Device::CreateDevice(platform, nullptr, createImplFunc));
if (!devices.back())
{
CLDeviceImpl::PtrList devices;
Ptr platform(new CLPlatformVk(devices));
if (!devices.empty())
{
initList.emplace_back(std::move(platform), std::move(info), std::move(devices));
}
devices.clear();
}
return initList;
return devices;
}
CLContextImpl::Ptr CLPlatformVk::createContext(const cl::Context &context,
const cl::DeviceRefList &devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
CLContextImpl::Ptr contextImpl;
return contextImpl;
}
CLContextImpl::Ptr CLPlatformVk::createContextFromType(const cl::Context &context,
cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet)
{
CLContextImpl::Ptr contextImpl;
return contextImpl;
}
void CLPlatformVk::Initialize(const cl_icd_dispatch &dispatch)
{
const cl::Platform::CreateImplFunc createImplFunc = [](const cl::Platform &platform) {
return Ptr(new CLPlatformVk(platform));
};
cl::Platform::CreatePlatform(dispatch, createImplFunc);
}
const std::string &CLPlatformVk::GetVersionString()
@ -98,8 +108,6 @@ const std::string &CLPlatformVk::GetVersionString()
return *sVersion;
}
CLPlatformVk::CLPlatformVk(CLDeviceImpl::PtrList &devices)
: CLPlatformImpl(CreateDevices(*this, devices))
{}
CLPlatformVk::CLPlatformVk(const cl::Platform &platform) : CLPlatformImpl(platform) {}
} // namespace rx

Просмотреть файл

@ -10,8 +10,6 @@
#include "libANGLE/renderer/CLPlatformImpl.h"
#include <string>
namespace rx
{
@ -20,24 +18,30 @@ class CLPlatformVk : public CLPlatformImpl
public:
~CLPlatformVk() override;
CLContextImpl::Ptr createContext(CLDeviceImpl::List &&deviceImplList,
Info createInfo() const override;
cl::DevicePtrList createDevices(cl::Platform &platform) const override;
CLContextImpl::Ptr createContext(const cl::Context &context,
const cl::DeviceRefList &devices,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
CLContextImpl::Ptr createContextFromType(cl_device_type deviceType,
CLContextImpl::Ptr createContextFromType(const cl::Context &context,
cl_device_type deviceType,
cl::ContextErrorCB notify,
void *userData,
bool userSync,
cl_int *errcodeRet) override;
static InitList GetPlatforms();
static void Initialize(const cl_icd_dispatch &dispatch);
static constexpr cl_version GetVersion();
static const std::string &GetVersionString();
private:
explicit CLPlatformVk(CLDeviceImpl::PtrList &devices);
explicit CLPlatformVk(const cl::Platform &platform);
};
constexpr cl_version CLPlatformVk::GetVersion()

Просмотреть файл

@ -9,8 +9,6 @@
#include "libGLESv2/cl_dispatch_table.h"
#include "libANGLE/CLPlatform.h"
#ifdef ANGLE_ENABLE_CL_PASSTHROUGH
# include "libANGLE/renderer/cl/CLPlatformCL.h"
#endif
@ -31,21 +29,11 @@ void InitBackEnds(bool isIcd)
initialized = true;
#ifdef ANGLE_ENABLE_CL_PASSTHROUGH
rx::CLPlatformImpl::InitList initListCL = rx::CLPlatformCL::GetPlatforms(isIcd);
while (!initListCL.empty())
{
Platform::CreatePlatform(gCLIcdDispatchTable, initListCL.front());
initListCL.pop_front();
}
rx::CLPlatformCL::Initialize(gCLIcdDispatchTable, isIcd);
#endif
#ifdef ANGLE_ENABLE_VULKAN
rx::CLPlatformImpl::InitList initListVk = rx::CLPlatformVk::GetPlatforms();
while (!initListVk.empty())
{
Platform::CreatePlatform(gCLIcdDispatchTable, initListVk.front());
initListVk.pop_front();
}
rx::CLPlatformVk::Initialize(gCLIcdDispatchTable);
#endif
}