Commit e369a282 by John Plate Committed by Commit Bot

Implement CL device object for front end and passthrough

Bug: angleproject:5904 Change-Id: I17f6d10ed59c62fe9126d29b7de2c127c5d0039a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2880662Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: John Plate <jplate@google.com>
parent d52ed4bd
...@@ -7,9 +7,302 @@ ...@@ -7,9 +7,302 @@
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLPlatform.h"
#include "libANGLE/Debug.h"
namespace cl namespace cl
{ {
Device::Device(const cl_icd_dispatch &dispatch) : _cl_device_id(dispatch) {} Device::~Device() = default;
cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet)
{
static_assert(std::is_same<cl_uint, cl_bool>::value &&
std::is_same<cl_uint, cl_device_mem_cache_type>::value &&
std::is_same<cl_uint, cl_device_local_mem_type>::value &&
std::is_same<cl_uint, cl_version>::value &&
std::is_same<cl_ulong, cl_device_type>::value &&
std::is_same<cl_ulong, cl_device_fp_config>::value &&
std::is_same<cl_ulong, cl_device_exec_capabilities>::value &&
std::is_same<cl_ulong, cl_command_queue_properties>::value &&
std::is_same<cl_ulong, cl_device_affinity_domain>::value &&
std::is_same<cl_ulong, cl_device_svm_capabilities>::value &&
std::is_same<cl_ulong, cl_device_atomic_capabilities>::value &&
std::is_same<cl_ulong, cl_device_device_enqueue_capabilities>::value,
"OpenCL type mismatch");
cl_uint valUInt = 0u;
cl_ulong valULong = 0u;
size_t valSizeT = 0u;
void *valPointer = nullptr;
std::vector<char> valString;
const void *copyValue = nullptr;
size_t copySize = 0u;
cl_int result = CL_SUCCESS;
// The info names are sorted within their type group in the order they appear in the OpenCL
// specification, so it is easier to compare them side-by-side when looking for changes.
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo
switch (name)
{
// Handle all cl_uint and aliased types
case DeviceInfo::VendorID:
case DeviceInfo::MaxComputeUnits:
case DeviceInfo::PreferredVectorWidthChar:
case DeviceInfo::PreferredVectorWidthShort:
case DeviceInfo::PreferredVectorWidthInt:
case DeviceInfo::PreferredVectorWidthLong:
case DeviceInfo::PreferredVectorWidthFloat:
case DeviceInfo::PreferredVectorWidthDouble:
case DeviceInfo::PreferredVectorWidthHalf:
case DeviceInfo::NativeVectorWidthChar:
case DeviceInfo::NativeVectorWidthShort:
case DeviceInfo::NativeVectorWidthInt:
case DeviceInfo::NativeVectorWidthLong:
case DeviceInfo::NativeVectorWidthFloat:
case DeviceInfo::NativeVectorWidthDouble:
case DeviceInfo::NativeVectorWidthHalf:
case DeviceInfo::MaxClockFrequency:
case DeviceInfo::AddressBits:
case DeviceInfo::ImageSupport:
case DeviceInfo::MaxReadImageArgs:
case DeviceInfo::MaxWriteImageArgs:
case DeviceInfo::MaxReadWriteImageArgs:
case DeviceInfo::MaxSamplers:
case DeviceInfo::ImagePitchAlignment:
case DeviceInfo::ImageBaseAddressAlignment:
case DeviceInfo::MaxPipeArgs:
case DeviceInfo::PipeMaxActiveReservations:
case DeviceInfo::PipeMaxPacketSize:
case DeviceInfo::MemBaseAddrAlign:
case DeviceInfo::MinDataTypeAlignSize:
case DeviceInfo::GlobalMemCacheType:
case DeviceInfo::GlobalMemCachelineSize:
case DeviceInfo::MaxConstantArgs:
case DeviceInfo::LocalMemType:
case DeviceInfo::ErrorCorrectionSupport:
case DeviceInfo::HostUnifiedMemory:
case DeviceInfo::EndianLittle:
case DeviceInfo::Available:
case DeviceInfo::CompilerAvailable:
case DeviceInfo::LinkerAvailable:
case DeviceInfo::QueueOnDevicePreferredSize:
case DeviceInfo::QueueOnDeviceMaxSize:
case DeviceInfo::MaxOnDeviceQueues:
case DeviceInfo::MaxOnDeviceEvents:
case DeviceInfo::NumericVersion:
case DeviceInfo::PreferredInteropUserSync:
case DeviceInfo::PartitionMaxSubDevices:
case DeviceInfo::ReferenceCount:
case DeviceInfo::PreferredPlatformAtomicAlignment:
case DeviceInfo::PreferredGlobalAtomicAlignment:
case DeviceInfo::PreferredLocalAtomicAlignment:
case DeviceInfo::MaxNumSubGroups:
case DeviceInfo::SubGroupIndependentForwardProgress:
case DeviceInfo::NonUniformWorkGroupSupport:
case DeviceInfo::WorkGroupCollectiveFunctionsSupport:
case DeviceInfo::GenericAddressSpaceSupport:
case DeviceInfo::PipeSupport:
result = mImpl->getInfoUInt(name, &valUInt);
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
// Handle all cl_ulong and aliased types
case DeviceInfo::Type:
case DeviceInfo::MaxMemAllocSize:
case DeviceInfo::SingleFpConfig:
case DeviceInfo::DoubleFpConfig:
case DeviceInfo::GlobalMemCacheSize:
case DeviceInfo::GlobalMemSize:
case DeviceInfo::MaxConstantBufferSize:
case DeviceInfo::LocalMemSize:
case DeviceInfo::ExecutionCapabilities:
case DeviceInfo::QueueOnHostProperties:
case DeviceInfo::QueueOnDeviceProperties:
case DeviceInfo::PartitionAffinityDomain:
case DeviceInfo::SVM_Capabilities:
case DeviceInfo::AtomicMemoryCapabilities:
case DeviceInfo::AtomicFenceCapabilities:
case DeviceInfo::DeviceEnqueueCapabilities:
case DeviceInfo::HalfFpConfig:
result = mImpl->getInfoULong(name, &valULong);
copyValue = &valULong;
copySize = sizeof(valULong);
break;
// Handle all size_t and aliased types
case DeviceInfo::MaxWorkGroupSize:
case DeviceInfo::Image2D_MaxWidth:
case DeviceInfo::Image2D_MaxHeight:
case DeviceInfo::Image3D_MaxWidth:
case DeviceInfo::Image3D_MaxHeight:
case DeviceInfo::Image3D_MaxDepth:
case DeviceInfo::ImageMaxBufferSize:
case DeviceInfo::ImageMaxArraySize:
case DeviceInfo::MaxParameterSize:
case DeviceInfo::MaxGlobalVariableSize:
case DeviceInfo::GlobalVariablePreferredTotalSize:
case DeviceInfo::ProfilingTimerResolution:
case DeviceInfo::PrintfBufferSize:
case DeviceInfo::PreferredWorkGroupSizeMultiple:
result = mImpl->getInfoSizeT(name, &valSizeT);
copyValue = &valSizeT;
copySize = sizeof(valSizeT);
break;
// Handle all string types
case DeviceInfo::IL_Version:
case DeviceInfo::BuiltInKernels:
case DeviceInfo::Name:
case DeviceInfo::Vendor:
case DeviceInfo::DriverVersion:
case DeviceInfo::Profile:
case DeviceInfo::Version:
case DeviceInfo::OpenCL_C_Version:
case DeviceInfo::Extensions:
case DeviceInfo::LatestConformanceVersionPassed:
result = mImpl->getInfoStringLength(name, &copySize);
if (result != CL_SUCCESS)
{
return result;
}
valString.resize(copySize, '\0');
result = mImpl->getInfoString(name, copySize, valString.data());
copyValue = valString.data();
break;
// Handle all array types
case DeviceInfo::MaxWorkItemDimensions:
valUInt = static_cast<cl_uint>(mInfo.mMaxWorkItemSizes.size());
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
case DeviceInfo::MaxWorkItemSizes:
copyValue = mInfo.mMaxWorkItemSizes.data();
copySize = mInfo.mMaxWorkItemSizes.size() *
sizeof(decltype(mInfo.mMaxWorkItemSizes)::value_type);
break;
case DeviceInfo::ILsWithVersion:
if (!mInfo.mIsSupportedILsWithVersion)
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mILsWithVersion.data();
copySize =
mInfo.mILsWithVersion.size() * sizeof(decltype(mInfo.mILsWithVersion)::value_type);
break;
case DeviceInfo::BuiltInKernelsWithVersion:
if (!mInfo.mIsSupportedBuiltInKernelsWithVersion)
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mBuiltInKernelsWithVersion.data();
copySize = mInfo.mBuiltInKernelsWithVersion.size() *
sizeof(decltype(mInfo.mBuiltInKernelsWithVersion)::value_type);
break;
case DeviceInfo::OpenCL_C_AllVersions:
if (!mInfo.mIsSupportedOpenCL_C_AllVersions)
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mOpenCL_C_AllVersions.data();
copySize = mInfo.mOpenCL_C_AllVersions.size() *
sizeof(decltype(mInfo.mOpenCL_C_AllVersions)::value_type);
break;
case DeviceInfo::OpenCL_C_Features:
if (!mInfo.mIsSupportedOpenCL_C_Features)
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mOpenCL_C_Features.data();
copySize = mInfo.mOpenCL_C_Features.size() *
sizeof(decltype(mInfo.mOpenCL_C_Features)::value_type);
break;
case DeviceInfo::ExtensionsWithVersion:
if (!mInfo.mIsSupportedExtensionsWithVersion)
{
return CL_INVALID_VALUE;
}
copyValue = mInfo.mExtensionsWithVersion.data();
copySize = mInfo.mExtensionsWithVersion.size() *
sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type);
break;
case DeviceInfo::PartitionProperties:
copyValue = mInfo.mPartitionProperties.data();
copySize = mInfo.mPartitionProperties.size() *
sizeof(decltype(mInfo.mPartitionProperties)::value_type);
break;
case DeviceInfo::PartitionType:
copyValue = mInfo.mPartitionType.data();
copySize =
mInfo.mPartitionType.size() * sizeof(decltype(mInfo.mPartitionType)::value_type);
break;
// Handle all special types
case DeviceInfo::Platform:
valPointer = &mPlatform;
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case DeviceInfo::ParentDevice:
copyValue = &mParent;
copySize = sizeof(mParent);
break;
default:
WARN() << "CL device info " << name << " is not (yet) supported";
return CL_INVALID_VALUE;
}
if (result != CL_SUCCESS)
{
return result;
}
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;
}
Device::PtrList Device::CreateDevices(Platform &platform, rx::CLDeviceImpl::InitList &&initList)
{
PtrList devices;
while (!initList.empty())
{
devices.emplace_back(new Device(platform, nullptr, initList.front()));
initList.pop_front();
}
return devices;
}
bool Device::IsValid(const Device *device)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const Platform::Ptr &platform) {
return platform->hasDevice(device);
}) != platforms.cend();
}
Device::Device(Platform &platform, Device *parent, rx::CLDeviceImpl::InitData &initData)
: _cl_device_id(platform.getDispatch()),
mPlatform(platform),
mParent(parent),
mImpl(std::move(initData.first)),
mInfo(std::move(initData.second))
{}
} // namespace cl } // namespace cl
...@@ -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/renderer/CLDeviceImpl.h"
namespace cl namespace cl
{ {
...@@ -17,10 +18,46 @@ namespace cl ...@@ -17,10 +18,46 @@ namespace cl
class Device final : public _cl_device_id, public Object class Device final : public _cl_device_id, public Object
{ {
public: public:
Device(const cl_icd_dispatch &dispatch); using Ptr = std::unique_ptr<Device>;
~Device() = default; using PtrList = std::list<Ptr>;
~Device();
Platform &getPlatform() const;
cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const;
cl_int getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
static PtrList CreateDevices(Platform &platform, rx::CLDeviceImpl::InitList &&initList);
static bool IsValid(const Device *device);
static bool IsValidType(cl_device_type type);
private:
Device(Platform &platform, Device *parent, rx::CLDeviceImpl::InitData &initData);
Platform &mPlatform;
Device *const mParent;
const rx::CLDeviceImpl::Ptr mImpl;
const rx::CLDeviceImpl::Info mInfo;
}; };
inline Platform &Device::getPlatform() const
{
return mPlatform;
}
inline cl_int Device::getInfoULong(DeviceInfo name, cl_ulong *value) const
{
return mImpl->getInfoULong(name, value);
}
inline bool Device::IsValidType(cl_device_type type)
{
return type <= CL_DEVICE_TYPE_CUSTOM || type == CL_DEVICE_TYPE_ALL;
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLDEVICE_H_ #endif // LIBANGLE_CLDEVICE_H_
...@@ -10,15 +10,62 @@ ...@@ -10,15 +10,62 @@
namespace cl namespace cl
{ {
namespace
{
bool IsDeviceTypeMatch(cl_device_type select, cl_device_type type)
{
// The type 'cl_device_type' is a bitfield, so masking out the selected bits indicates
// if a given type is a match. A custom device is an exception, which only matches
// if it was explicitely selected, as defined here:
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceIDs
return type == CL_DEVICE_TYPE_CUSTOM ? select == CL_DEVICE_TYPE_CUSTOM : (type & select) != 0u;
}
} // namespace
Platform::~Platform() = default; Platform::~Platform() = default;
void Platform::CreatePlatform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::Ptr &&impl) void Platform::CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData)
{
rx::CLDeviceImpl::InitList deviceInitList = initData->getDevices();
if (!deviceInitList.empty())
{
GetList().emplace_back(new Platform(dispatch, initData, std::move(deviceInitList)));
}
}
cl_int Platform::getDeviceIDs(cl_device_type deviceType,
cl_uint numEntries,
Device **devices,
cl_uint *numDevices) const
{ {
GetList().emplace_back(new Platform(dispatch, std::move(impl))); cl_uint found = 0u;
for (const Device::Ptr &device : mDevices)
{
cl_device_type type = 0u;
if (device->getInfoULong(DeviceInfo::Type, &type) == CL_SUCCESS &&
IsDeviceTypeMatch(deviceType, type))
{
if (devices != nullptr && found < numEntries)
{
devices[found] = device.get();
}
++found;
}
}
if (numDevices != nullptr)
{
*numDevices = found;
}
return found == 0u ? CL_DEVICE_NOT_FOUND : CL_SUCCESS;
} }
Platform::Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::Ptr &&impl) Platform::Platform(const cl_icd_dispatch &dispatch,
: _cl_platform_id(dispatch), mImpl(std::move(impl)) rx::CLPlatformImpl::InitData &initData,
rx::CLDeviceImpl::InitList &&deviceInitList)
: _cl_platform_id(dispatch),
mImpl(std::move(initData)),
mDevices(Device::CreateDevices(*this, std::move(deviceInitList)))
{} {}
constexpr char Platform::kVendor[]; constexpr char Platform::kVendor[];
......
...@@ -9,22 +9,19 @@ ...@@ -9,22 +9,19 @@
#ifndef LIBANGLE_CLPLATFORM_H_ #ifndef LIBANGLE_CLPLATFORM_H_
#define LIBANGLE_CLPLATFORM_H_ #define LIBANGLE_CLPLATFORM_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/renderer/CLPlatformImpl.h" #include "libANGLE/renderer/CLPlatformImpl.h"
#include "anglebase/no_destructor.h" #include "anglebase/no_destructor.h"
#include <algorithm>
#include <string>
namespace cl namespace cl
{ {
class Platform final : public _cl_platform_id, public Object class Platform final : public _cl_platform_id, public Object
{ {
public: public:
using Ptr = std::unique_ptr<Platform>; using Ptr = std::unique_ptr<Platform>;
using List = std::vector<Ptr>; using PtrList = std::list<Ptr>;
~Platform(); ~Platform();
...@@ -33,21 +30,36 @@ class Platform final : public _cl_platform_id, public Object ...@@ -33,21 +30,36 @@ class Platform final : public _cl_platform_id, public Object
cl_version getVersion() const; cl_version getVersion() const;
const char *getName() const; const char *getName() const;
const char *getExtensions() const; const char *getExtensions() const;
const rx::CLPlatformImpl::ExtensionList &getExtensionsWithVersion() const; const rx::NameVersionVector &getExtensionsWithVersion() const;
cl_ulong getHostTimerResolution() const; cl_ulong getHostTimerResolution() const;
static void CreatePlatform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::Ptr &&impl); bool hasDevice(const Device *device) const;
static const List &GetPlatforms(); const Device::PtrList &getDevices() const;
cl_int getDeviceIDs(cl_device_type deviceType,
cl_uint numEntries,
Device **devices,
cl_uint *numDevices) const;
static void CreatePlatform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData);
static const PtrList &GetPlatforms();
static Platform *GetDefault();
static bool IsValid(const Platform *platform); static bool IsValid(const Platform *platform);
static bool IsValidOrDefault(const Platform *platform);
static constexpr const char *GetVendor(); static constexpr const char *GetVendor();
static constexpr const char *GetIcdSuffix(); static constexpr const char *GetIcdSuffix();
private: private:
Platform(const cl_icd_dispatch &dispatch, rx::CLPlatformImpl::Ptr &&impl); Platform(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::InitData &initData,
rx::CLDeviceImpl::InitList &&deviceInitList);
static List &GetList(); static PtrList &GetList();
const rx::CLPlatformImpl::Ptr mImpl; const rx::CLPlatformImpl::Ptr mImpl;
const Device::PtrList mDevices;
static constexpr char kVendor[] = "ANGLE"; static constexpr char kVendor[] = "ANGLE";
static constexpr char kIcdSuffix[] = "ANGLE"; static constexpr char kIcdSuffix[] = "ANGLE";
...@@ -78,7 +90,7 @@ inline const char *Platform::getExtensions() const ...@@ -78,7 +90,7 @@ inline const char *Platform::getExtensions() const
return mImpl->getInfo().mExtensions.c_str(); return mImpl->getInfo().mExtensions.c_str();
} }
inline const rx::CLPlatformImpl::ExtensionList &Platform::getExtensionsWithVersion() const inline const rx::NameVersionVector &Platform::getExtensionsWithVersion() const
{ {
return mImpl->getInfo().mExtensionList; return mImpl->getInfo().mExtensionList;
} }
...@@ -88,24 +100,48 @@ inline cl_ulong Platform::getHostTimerResolution() const ...@@ -88,24 +100,48 @@ inline cl_ulong Platform::getHostTimerResolution() const
return mImpl->getInfo().mHostTimerRes; return mImpl->getInfo().mHostTimerRes;
} }
inline Platform::List &Platform::GetList() inline bool Platform::hasDevice(const Device *device) const
{
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const Device::Ptr &ptr) {
return ptr.get() == device;
}) != mDevices.cend();
}
inline const Device::PtrList &Platform::getDevices() const
{
return mDevices;
}
inline Platform::PtrList &Platform::GetList()
{ {
static angle::base::NoDestructor<List> sList; static angle::base::NoDestructor<PtrList> sList;
return *sList; return *sList;
} }
inline const Platform::List &Platform::GetPlatforms() inline const Platform::PtrList &Platform::GetPlatforms()
{ {
return GetList(); return GetList();
} }
inline Platform *Platform::GetDefault()
{
return GetList().empty() ? nullptr : GetList().front().get();
}
inline bool Platform::IsValid(const Platform *platform) inline bool Platform::IsValid(const Platform *platform)
{ {
const List &platforms = GetPlatforms(); const PtrList &platforms = GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), return std::find_if(platforms.cbegin(), platforms.cend(),
[=](const Ptr &ptr) { return ptr.get() == platform; }) != platforms.cend(); [=](const Ptr &ptr) { return ptr.get() == platform; }) != platforms.cend();
} }
// Our CL implementation defines that a nullptr value chooses the platform that we provide as
// default, so this function returns true for a nullptr value if a default platform exists.
inline bool Platform::IsValidOrDefault(const Platform *platform)
{
return platform != nullptr ? IsValid(platform) : GetDefault() != nullptr;
}
constexpr const char *Platform::GetVendor() constexpr const char *Platform::GetVendor()
{ {
return kVendor; return kVendor;
......
...@@ -12,8 +12,13 @@ ...@@ -12,8 +12,13 @@
#include "common/PackedCLEnums_autogen.h" #include "common/PackedCLEnums_autogen.h"
// Include frequently used standard headers
#include <algorithm>
#include <list>
#include <memory> #include <memory>
#include <string>
#include <utility> #include <utility>
#include <vector>
namespace cl namespace cl
{ {
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLDeviceImpl.cpp: Implements the class methods for CLDeviceImpl.
#include "libANGLE/renderer/CLDeviceImpl.h"
namespace rx
{
CLDeviceImpl::Info::Info() = default;
CLDeviceImpl::Info::~Info() = default;
CLDeviceImpl::Info::Info(Info &&) = default;
CLDeviceImpl::Info &CLDeviceImpl::Info::operator=(Info &&) = default;
bool CLDeviceImpl::Info::isValid() const
{
// From the OpenCL specification for info name CL_DEVICE_MAX_WORK_ITEM_SIZES:
// "The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM."
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo
// Custom devices are currently not supported by ANGLE back ends.
return mMaxWorkItemSizes.size() >= 3u && mMaxWorkItemSizes[0] >= 1u &&
mMaxWorkItemSizes[1] >= 1u && mMaxWorkItemSizes[2] >= 1u;
}
} // namespace rx
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// 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.
// //
// CLDeviceImpl.h: Defines the abstract rx::CLDeviceImpl class. // CLDeviceImpl.h: Defines the abstract rx::CLDeviceImpl class.
#ifndef LIBANGLE_RENDERER_CLDEVICEIMPL_H_ #ifndef LIBANGLE_RENDERER_CLDEVICEIMPL_H_
...@@ -17,8 +16,47 @@ namespace rx ...@@ -17,8 +16,47 @@ namespace rx
class CLDeviceImpl : angle::NonCopyable class CLDeviceImpl : angle::NonCopyable
{ {
public: public:
CLDeviceImpl() {} struct Info
virtual ~CLDeviceImpl() {} {
Info();
~Info();
Info(const Info &) = delete;
Info &operator=(const Info &) = delete;
Info(Info &&);
Info &operator=(Info &&);
bool isValid() const;
std::vector<size_t> mMaxWorkItemSizes;
NameVersionVector mILsWithVersion;
NameVersionVector mBuiltInKernelsWithVersion;
NameVersionVector mOpenCL_C_AllVersions;
NameVersionVector mOpenCL_C_Features;
NameVersionVector mExtensionsWithVersion;
std::vector<cl_device_partition_property> mPartitionProperties;
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 InitData = std::pair<Ptr, Info>;
using InitList = std::list<InitData>;
CLDeviceImpl() = default;
virtual ~CLDeviceImpl() = default;
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 getInfoSizeT(cl::DeviceInfo name, size_t *value) const = 0;
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;
}; };
} // namespace rx } // namespace rx
......
...@@ -23,7 +23,7 @@ CLPlatformImpl::Info::Info(std::string &&profile, ...@@ -23,7 +23,7 @@ CLPlatformImpl::Info::Info(std::string &&profile,
cl_version version, cl_version version,
std::string &&name, std::string &&name,
std::string &&extensions, std::string &&extensions,
rx::CLPlatformImpl::ExtensionList &&extensionList, NameVersionVector &&extensionList,
cl_ulong hostTimerRes) cl_ulong hostTimerRes)
: mProfile(std::move(profile)), : mProfile(std::move(profile)),
mVersionStr(std::move(versionStr)), mVersionStr(std::move(versionStr)),
......
...@@ -3,16 +3,12 @@ ...@@ -3,16 +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.
// //
// CLPlatformImpl.h: Defines the abstract rx::CLPlatformImpl class. // CLPlatformImpl.h: Defines the abstract rx::CLPlatformImpl class.
#ifndef LIBANGLE_RENDERER_CLPLATFORMIMPL_H_ #ifndef LIBANGLE_RENDERER_CLPLATFORMIMPL_H_
#define LIBANGLE_RENDERER_CLPLATFORMIMPL_H_ #define LIBANGLE_RENDERER_CLPLATFORMIMPL_H_
#include "libANGLE/renderer/CLtypes.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include <list>
#include <vector>
namespace rx namespace rx
{ {
...@@ -20,9 +16,9 @@ namespace rx ...@@ -20,9 +16,9 @@ namespace rx
class CLPlatformImpl : angle::NonCopyable class CLPlatformImpl : angle::NonCopyable
{ {
public: public:
using Ptr = std::unique_ptr<CLPlatformImpl>; using Ptr = std::unique_ptr<CLPlatformImpl>;
using ImplList = std::list<Ptr>; using InitData = Ptr;
using ExtensionList = std::vector<cl_name_version>; using InitList = std::list<InitData>;
struct Info struct Info
{ {
...@@ -40,7 +36,7 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -40,7 +36,7 @@ class CLPlatformImpl : angle::NonCopyable
cl_version version, cl_version version,
std::string &&name, std::string &&name,
std::string &&extensions, std::string &&extensions,
rx::CLPlatformImpl::ExtensionList &&extensionList, NameVersionVector &&extensionList,
cl_ulong hostTimerRes); cl_ulong hostTimerRes);
std::string mProfile; std::string mProfile;
...@@ -48,7 +44,7 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -48,7 +44,7 @@ class CLPlatformImpl : angle::NonCopyable
cl_version mVersion; cl_version mVersion;
std::string mName; std::string mName;
std::string mExtensions; std::string mExtensions;
rx::CLPlatformImpl::ExtensionList mExtensionList; NameVersionVector mExtensionList;
cl_ulong mHostTimerRes; cl_ulong mHostTimerRes;
}; };
...@@ -57,6 +53,8 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -57,6 +53,8 @@ class CLPlatformImpl : angle::NonCopyable
const Info &getInfo(); const Info &getInfo();
virtual CLDeviceImpl::InitList getDevices() = 0;
protected: protected:
const Info mInfo; const Info mInfo;
}; };
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// 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.
// //
// CLtypes.h: Defines common types for the OpenCL support in ANGLE. // CLtypes.h: Defines common types for the OpenCL support in ANGLE.
#ifndef LIBANGLE_RENDERER_CLTYPES_H_ #ifndef LIBANGLE_RENDERER_CLTYPES_H_
...@@ -15,9 +14,13 @@ ...@@ -15,9 +14,13 @@
namespace rx namespace rx
{ {
class CLContextImpl; class CLContextImpl;
class CLDeviceImpl; class CLDeviceImpl;
class CLPlatformImpl; class CLPlatformImpl;
using NameVersionVector = std::vector<cl_name_version>;
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CLTYPES_H_ #endif // LIBANGLE_RENDERER_CLTYPES_H_
...@@ -3,17 +3,142 @@ ...@@ -3,17 +3,142 @@
// 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.
// //
// CLDeviceCL.cpp: // CLDeviceCL.cpp: Implements the class methods for CLDeviceCL.
// Implements the class methods for CLDeviceCL.
//
#include "libANGLE/renderer/cl/CLDeviceCL.h" #include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/Debug.h"
namespace rx namespace rx
{ {
CLDeviceCL::CLDeviceCL() {} CLDeviceCL::CLDeviceCL(cl_device_id device) : mDevice(device) {}
CLDeviceCL::~CLDeviceCL() = default;
cl_int CLDeviceCL::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, 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),
value, nullptr);
}
cl_int CLDeviceCL::getInfoSizeT(cl::DeviceInfo name, size_t *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, 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);
}
cl_int CLDeviceCL::getInfoString(cl::DeviceInfo name, size_t size, char *value) const
{
return mDevice->getDispatch().clGetDeviceInfo(mDevice, cl::ToCLenum(name), size, value,
nullptr);
}
#define ANGLE_GET_INFO_SIZE(name, size_ret) \
device->getDispatch().clGetDeviceInfo(device, name, 0u, nullptr, size_ret)
#define ANGLE_GET_INFO(name, size, param) \
device->getDispatch().clGetDeviceInfo(device, 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 device info for " << name; \
return Info{}; \
} \
} while (0)
CLDeviceImpl::Info CLDeviceCL::GetInfo(cl_device_id device)
{
Info info;
size_t valueSize = 0u;
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_ILS_WITH_VERSION, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mILsWithVersion)::value_type)) == 0u)
{
info.mILsWithVersion.resize(valueSize / sizeof(decltype(info.mILsWithVersion)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_ILS_WITH_VERSION, valueSize, info.mILsWithVersion.data());
info.mIsSupportedILsWithVersion = true;
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mBuiltInKernelsWithVersion)::value_type)) == 0u)
{
info.mBuiltInKernelsWithVersion.resize(
valueSize / sizeof(decltype(info.mBuiltInKernelsWithVersion)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, valueSize,
info.mBuiltInKernelsWithVersion.data());
info.mIsSupportedBuiltInKernelsWithVersion = true;
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_OPENCL_C_ALL_VERSIONS, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mOpenCL_C_AllVersions)::value_type)) == 0u)
{
info.mOpenCL_C_AllVersions.resize(valueSize /
sizeof(decltype(info.mOpenCL_C_AllVersions)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_OPENCL_C_ALL_VERSIONS, valueSize,
info.mOpenCL_C_AllVersions.data());
info.mIsSupportedOpenCL_C_AllVersions = true;
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_OPENCL_C_FEATURES, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mOpenCL_C_Features)::value_type)) == 0u)
{
info.mOpenCL_C_Features.resize(valueSize /
sizeof(decltype(info.mOpenCL_C_Features)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_OPENCL_C_FEATURES, valueSize, info.mOpenCL_C_Features.data());
info.mIsSupportedOpenCL_C_Features = true;
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_EXTENSIONS_WITH_VERSION, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mExtensionsWithVersion)::value_type)) == 0u)
{
info.mExtensionsWithVersion.resize(
valueSize / sizeof(decltype(info.mExtensionsWithVersion)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_EXTENSIONS_WITH_VERSION, valueSize,
info.mExtensionsWithVersion.data());
info.mIsSupportedExtensionsWithVersion = true;
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_PARTITION_PROPERTIES, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mPartitionProperties)::value_type)) == 0u)
{
info.mPartitionProperties.resize(valueSize /
sizeof(decltype(info.mPartitionProperties)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_PARTITION_PROPERTIES, valueSize,
info.mPartitionProperties.data());
}
if (ANGLE_GET_INFO_SIZE(CL_DEVICE_PARTITION_TYPE, &valueSize) == CL_SUCCESS &&
(valueSize % sizeof(decltype(info.mPartitionType)::value_type)) == 0u)
{
info.mPartitionType.resize(valueSize / sizeof(decltype(info.mPartitionType)::value_type));
ANGLE_GET_INFO_RET(CL_DEVICE_PARTITION_TYPE, valueSize, info.mPartitionType.data());
}
// Get this last, so the info is invalid if anything before fails
cl_uint maxWorkItemDims = 0u;
ANGLE_GET_INFO_RET(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(maxWorkItemDims),
&maxWorkItemDims);
info.mMaxWorkItemSizes.resize(maxWorkItemDims, 0u);
ANGLE_GET_INFO_RET(CL_DEVICE_MAX_WORK_ITEM_SIZES,
maxWorkItemDims * sizeof(decltype(info.mMaxWorkItemSizes)::value_type),
info.mMaxWorkItemSizes.data());
CLDeviceCL::~CLDeviceCL() {} return info;
}
} // namespace rx } // namespace rx
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
// 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.
// //
// CLDeviceCL.h: // CLDeviceCL.h: Defines the class interface for CLDeviceCL, implementing CLDeviceImpl.
// Defines the class interface for CLDeviceCL, implementing CLDeviceImpl.
//
#ifndef LIBANGLE_RENDERER_CL_CLDEVICECL_H_ #ifndef LIBANGLE_RENDERER_CL_CLDEVICECL_H_
#define LIBANGLE_RENDERER_CL_CLDEVICECL_H_ #define LIBANGLE_RENDERER_CL_CLDEVICECL_H_
...@@ -18,10 +16,28 @@ namespace rx ...@@ -18,10 +16,28 @@ namespace rx
class CLDeviceCL : public CLDeviceImpl class CLDeviceCL : public CLDeviceImpl
{ {
public: public:
CLDeviceCL(); explicit CLDeviceCL(cl_device_id device);
~CLDeviceCL() override; ~CLDeviceCL() override;
cl_device_id getNative();
cl_int getInfoUInt(cl::DeviceInfo name, cl_uint *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 getInfoStringLength(cl::DeviceInfo name, size_t *value) const override;
cl_int getInfoString(cl::DeviceInfo name, size_t size, char *value) const override;
static Info GetInfo(cl_device_id device);
private:
const cl_device_id mDevice;
}; };
inline cl_device_id CLDeviceCL::getNative()
{
return mDevice;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLDEVICECL_H_ #endif // LIBANGLE_RENDERER_CL_CLDEVICECL_H_
...@@ -3,12 +3,12 @@ ...@@ -3,12 +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.
// //
// CLPlatformCL.cpp: // CLPlatformCL.cpp: Implements the class methods for CLPlatformCL.
// Implements the class methods for CLPlatformCL.
//
#include "libANGLE/renderer/cl/CLPlatformCL.h" #include "libANGLE/renderer/cl/CLPlatformCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#include "libANGLE/Debug.h" #include "libANGLE/Debug.h"
...@@ -21,7 +21,6 @@ extern "C" { ...@@ -21,7 +21,6 @@ extern "C" {
#include <cstdlib> #include <cstdlib>
#include <unordered_set> #include <unordered_set>
#include <vector>
namespace rx namespace rx
{ {
...@@ -40,7 +39,44 @@ const ExtensionSet &GetSupportedExtensions() ...@@ -40,7 +39,44 @@ const ExtensionSet &GetSupportedExtensions()
CLPlatformCL::~CLPlatformCL() = default; CLPlatformCL::~CLPlatformCL() = default;
CLPlatformCL::ImplList CLPlatformCL::GetPlatforms(bool isIcd) CLDeviceImpl::InitList CLPlatformCL::getDevices()
{
CLDeviceImpl::InitList initList;
// 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 (mPlatform->getDispatch().clGetDeviceIDs(mPlatform, CL_DEVICE_TYPE_ALL, 0u, nullptr,
&numDevices) == CL_SUCCESS)
{
std::vector<cl_device_id> devices(numDevices, nullptr);
if (mPlatform->getDispatch().clGetDeviceIDs(mPlatform, CL_DEVICE_TYPE_ALL, numDevices,
devices.data(), nullptr) == CL_SUCCESS)
{
for (cl_device_id device : devices)
{
CLDeviceImpl::Info info = CLDeviceCL::GetInfo(device);
if (info.isValid())
{
initList.emplace_back(new CLDeviceCL(device), std::move(info));
}
}
}
else
{
ERR() << "Failed to query CL devices";
}
}
else
{
ERR() << "Failed to query CL devices";
}
return initList;
}
CLPlatformCL::InitList CLPlatformCL::GetPlatforms(bool isIcd)
{ {
// Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to enumerate the // 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 // available OpenCL implementations on the system. They will be stored in the singly linked
...@@ -66,7 +102,7 @@ CLPlatformCL::ImplList CLPlatformCL::GetPlatforms(bool isIcd) ...@@ -66,7 +102,7 @@ CLPlatformCL::ImplList CLPlatformCL::GetPlatforms(bool isIcd)
// Iterating through the singly linked list khrIcdVendors to create an ANGLE CL pass-through // 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. // platform for each found ICD platform. Skipping our dummy entry that has an invalid platform.
ImplList implList; InitList initList;
for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next) for (KHRicdVendor *vendorIt = khrIcdVendors; vendorIt != nullptr; vendorIt = vendorIt->next)
{ {
if (vendorIt->platform != nullptr) if (vendorIt->platform != nullptr)
...@@ -74,11 +110,11 @@ CLPlatformCL::ImplList CLPlatformCL::GetPlatforms(bool isIcd) ...@@ -74,11 +110,11 @@ CLPlatformCL::ImplList CLPlatformCL::GetPlatforms(bool isIcd)
rx::CLPlatformImpl::Ptr impl = Create(vendorIt->platform); rx::CLPlatformImpl::Ptr impl = Create(vendorIt->platform);
if (impl) if (impl)
{ {
implList.emplace_back(std::move(impl)); initList.emplace_back(std::move(impl));
} }
} }
} }
return implList; return initList;
} }
CLPlatformCL::CLPlatformCL(cl_platform_id platform, Info &&info) CLPlatformCL::CLPlatformCL(cl_platform_id platform, Info &&info)
...@@ -106,6 +142,12 @@ std::unique_ptr<CLPlatformCL> CLPlatformCL::Create(cl_platform_id platform) ...@@ -106,6 +142,12 @@ std::unique_ptr<CLPlatformCL> CLPlatformCL::Create(cl_platform_id platform)
std::vector<std::string::value_type> param; std::vector<std::string::value_type> param;
CLPlatformImpl::Info info; CLPlatformImpl::Info info;
// Verify that the platform is valid
ASSERT(platform != nullptr);
ASSERT(platform->getDispatch().clGetPlatformInfo != nullptr);
ASSERT(platform->getDispatch().clGetDeviceIDs != nullptr);
ASSERT(platform->getDispatch().clGetDeviceInfo != nullptr);
// Skip ANGLE CL implementation to prevent passthrough loop // Skip ANGLE CL implementation to prevent passthrough loop
ANGLE_TRY_GET_INFO(CL_PLATFORM_VENDOR, 0u, nullptr, &paramSize); ANGLE_TRY_GET_INFO(CL_PLATFORM_VENDOR, 0u, nullptr, &paramSize);
param.resize(paramSize, '\0'); param.resize(paramSize, '\0');
...@@ -214,8 +256,8 @@ std::unique_ptr<CLPlatformCL> CLPlatformCL::Create(cl_platform_id platform) ...@@ -214,8 +256,8 @@ std::unique_ptr<CLPlatformCL> CLPlatformCL::Create(cl_platform_id platform)
info.mExtensionList.data(), nullptr); info.mExtensionList.data(), nullptr);
// Filter out extensions which are not (yet) supported to be passed through // Filter out extensions which are not (yet) supported to be passed through
const ExtensionSet &supported = GetSupportedExtensions(); const ExtensionSet &supported = GetSupportedExtensions();
ExtensionList::const_iterator extIt = info.mExtensionList.cbegin(); NameVersionVector::const_iterator extIt = info.mExtensionList.cbegin();
while (extIt != info.mExtensionList.cend()) while (extIt != info.mExtensionList.cend())
{ {
if (supported.find(extIt->name) != supported.cend()) if (supported.find(extIt->name) != supported.cend())
......
...@@ -3,17 +3,13 @@ ...@@ -3,17 +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.
// //
// CLPlatformCL.h: // CLPlatformCL.h: Defines the class interface for CLPlatformCL, implementing CLPlatformImpl.
// Defines the class interface for CLPlatformCL, implementing CLPlatformImpl.
//
#ifndef LIBANGLE_RENDERER_CL_CLPLATFORMCL_H_ #ifndef LIBANGLE_RENDERER_CL_CLPLATFORMCL_H_
#define LIBANGLE_RENDERER_CL_CLPLATFORMCL_H_ #define LIBANGLE_RENDERER_CL_CLPLATFORMCL_H_
#include "libANGLE/renderer/CLPlatformImpl.h" #include "libANGLE/renderer/CLPlatformImpl.h"
#include <string>
namespace rx namespace rx
{ {
...@@ -24,7 +20,9 @@ class CLPlatformCL : public CLPlatformImpl ...@@ -24,7 +20,9 @@ class CLPlatformCL : public CLPlatformImpl
cl_platform_id getNative(); cl_platform_id getNative();
static ImplList GetPlatforms(bool isIcd); CLDeviceImpl::InitList getDevices() override;
static InitList GetPlatforms(bool isIcd);
private: private:
CLPlatformCL(cl_platform_id platform, Info &&info); CLPlatformCL(cl_platform_id platform, Info &&info);
......
...@@ -3,17 +3,46 @@ ...@@ -3,17 +3,46 @@
// 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.
// //
// CLDeviceVk.cpp: // CLDeviceVk.cpp: Implements the class methods for CLDeviceVk.
// Implements the class methods for CLDeviceVk.
//
#include "libANGLE/renderer/vulkan/CLDeviceVk.h" #include "libANGLE/renderer/vulkan/CLDeviceVk.h"
namespace rx namespace rx
{ {
CLDeviceVk::CLDeviceVk() {} CLDeviceVk::CLDeviceVk() = default;
CLDeviceVk::~CLDeviceVk() = default; CLDeviceVk::~CLDeviceVk() = default;
cl_int CLDeviceVk::getInfoUInt(cl::DeviceInfo name, cl_uint *value) const
{
return CL_INVALID_VALUE;
}
cl_int CLDeviceVk::getInfoULong(cl::DeviceInfo name, cl_ulong *value) const
{
return CL_INVALID_VALUE;
}
cl_int CLDeviceVk::getInfoSizeT(cl::DeviceInfo name, size_t *value) const
{
return CL_INVALID_VALUE;
}
cl_int CLDeviceVk::getInfoStringLength(cl::DeviceInfo name, size_t *value) const
{
return CL_INVALID_VALUE;
}
cl_int CLDeviceVk::getInfoString(cl::DeviceInfo name, size_t size, char *value) const
{
return CL_INVALID_VALUE;
}
CLDeviceImpl::Info CLDeviceVk::GetInfo()
{
CLDeviceImpl::Info info;
return info;
}
} // namespace rx } // namespace rx
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
// 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.
// //
// CLDeviceVk.h: // CLDeviceVk.h: Defines the class interface for CLDeviceVk, implementing CLDeviceImpl.
// Defines the class interface for CLDeviceVk, implementing CLDeviceImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_ #ifndef LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_ #define LIBANGLE_RENDERER_VULKAN_CLDEVICEVK_H_
...@@ -20,6 +18,14 @@ class CLDeviceVk : public CLDeviceImpl ...@@ -20,6 +18,14 @@ class CLDeviceVk : public CLDeviceImpl
public: public:
CLDeviceVk(); CLDeviceVk();
~CLDeviceVk() override; ~CLDeviceVk() 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 getInfoSizeT(cl::DeviceInfo name, size_t *value) const override;
cl_int getInfoStringLength(cl::DeviceInfo name, size_t *value) const override;
cl_int getInfoString(cl::DeviceInfo name, size_t size, char *value) const override;
static Info GetInfo();
}; };
} // namespace rx } // namespace rx
......
...@@ -3,23 +3,21 @@ ...@@ -3,23 +3,21 @@
// 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.
// //
// CLPlatformVk.cpp: // CLPlatformVk.cpp: Implements the class methods for CLPlatformVk.
// Implements the class methods for CLPlatformVk.
//
#include "libANGLE/renderer/vulkan/CLPlatformVk.h" #include "libANGLE/renderer/vulkan/CLPlatformVk.h"
#include "libANGLE/renderer/vulkan/CLDeviceVk.h"
#include "anglebase/no_destructor.h" #include "anglebase/no_destructor.h"
#include "common/angle_version.h" #include "common/angle_version.h"
#include <algorithm>
namespace rx namespace rx
{ {
namespace namespace
{ {
std::string CreateExtensionString(const CLPlatformImpl::ExtensionList &extList) std::string CreateExtensionString(const NameVersionVector &extList)
{ {
std::string extensions; std::string extensions;
for (const cl_name_version &ext : extList) for (const cl_name_version &ext : extList)
...@@ -39,9 +37,20 @@ CLPlatformVk::CLPlatformVk(Info &&info) : CLPlatformImpl(std::move(info)) {} ...@@ -39,9 +37,20 @@ CLPlatformVk::CLPlatformVk(Info &&info) : CLPlatformImpl(std::move(info)) {}
CLPlatformVk::~CLPlatformVk() = default; CLPlatformVk::~CLPlatformVk() = default;
CLPlatformVk::ImplList CLPlatformVk::GetPlatforms() CLDeviceImpl::InitList CLPlatformVk::getDevices()
{
CLDeviceImpl::InitList initList;
CLDeviceImpl::Info info = CLDeviceVk::GetInfo();
if (info.isValid())
{
initList.emplace_back(new CLDeviceVk(), std::move(info));
}
return initList;
}
CLPlatformVk::InitList CLPlatformVk::GetPlatforms()
{ {
ExtensionList extList = { NameVersionVector extList = {
cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_icd"}, cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_icd"},
cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_extended_versioning"}}; cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_extended_versioning"}};
std::string extensions = CreateExtensionString(extList); std::string extensions = CreateExtensionString(extList);
...@@ -49,9 +58,9 @@ CLPlatformVk::ImplList CLPlatformVk::GetPlatforms() ...@@ -49,9 +58,9 @@ CLPlatformVk::ImplList CLPlatformVk::GetPlatforms()
Info info("FULL_PROFILE", std::string(GetVersionString()), GetVersion(), "ANGLE Vulkan", Info info("FULL_PROFILE", std::string(GetVersionString()), GetVersion(), "ANGLE Vulkan",
std::move(extensions), std::move(extList), 0u); std::move(extensions), std::move(extList), 0u);
ImplList implList; InitList initList;
implList.emplace_back(new CLPlatformVk(std::move(info))); initList.emplace_back(new CLPlatformVk(std::move(info)));
return implList; return initList;
} }
const std::string &CLPlatformVk::GetVersionString() const std::string &CLPlatformVk::GetVersionString()
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
// 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.
// //
// CLPlatformVk.h: // CLPlatformVk.h: Defines the class interface for CLPlatformVk, implementing CLPlatformImpl.
// Defines the class interface for CLPlatformVk, implementing CLPlatformImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_CLPLATFORMVK_H_ #ifndef LIBANGLE_RENDERER_VULKAN_CLPLATFORMVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLPLATFORMVK_H_ #define LIBANGLE_RENDERER_VULKAN_CLPLATFORMVK_H_
...@@ -22,7 +20,9 @@ class CLPlatformVk : public CLPlatformImpl ...@@ -22,7 +20,9 @@ class CLPlatformVk : public CLPlatformImpl
public: public:
~CLPlatformVk() override; ~CLPlatformVk() override;
static ImplList GetPlatforms(); CLDeviceImpl::InitList getDevices() override;
static InitList GetPlatforms();
static constexpr cl_version GetVersion(); static constexpr cl_version GetVersion();
static const std::string &GetVersionString(); static const std::string &GetVersionString();
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// 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.
// //
// validationCL.cpp: Validation functions for generic CL entry point parameters // validationCL.cpp: Validation functions for generic CL entry point parameters
#include "libANGLE/validationCL_autogen.h" #include "libANGLE/validationCL_autogen.h"
...@@ -12,28 +11,28 @@ namespace cl ...@@ -12,28 +11,28 @@ namespace cl
{ {
// CL 1.0 // CL 1.0
cl_int ValidateGetPlatformIDs(cl_uint num_entries, cl_int ValidateGetPlatformIDs(cl_uint num_entries,
Platform *const *platformsPacked, Platform *const *platforms,
const cl_uint *num_platforms) const cl_uint *num_platforms)
{ {
if ((num_entries == 0u && platformsPacked != nullptr) || if ((num_entries == 0u && platforms != nullptr) ||
(platformsPacked == nullptr && num_platforms == nullptr)) (platforms == nullptr && num_platforms == nullptr))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_int ValidateGetPlatformInfo(const Platform *platformPacked, cl_int ValidateGetPlatformInfo(const Platform *platform,
PlatformInfo param_namePacked, PlatformInfo 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 (!Platform::IsValid(platformPacked)) if (!Platform::IsValid(platform))
{ {
return CL_INVALID_PLATFORM; return CL_INVALID_PLATFORM;
} }
if (param_namePacked == PlatformInfo::InvalidEnum || if (param_name == PlatformInfo::InvalidEnum ||
(param_value_size == 0u && param_value != nullptr)) (param_value_size == 0u && param_value != nullptr))
{ {
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
...@@ -41,21 +40,41 @@ cl_int ValidateGetPlatformInfo(const Platform *platformPacked, ...@@ -41,21 +40,41 @@ cl_int ValidateGetPlatformInfo(const Platform *platformPacked,
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_int ValidateGetDeviceIDs(const Platform *platformPacked, cl_int ValidateGetDeviceIDs(const Platform *platform,
cl_device_type device_type, cl_device_type device_type,
cl_uint num_entries, cl_uint num_entries,
Device *const *devicesPacked, Device *const *devices,
const cl_uint *num_devices) const cl_uint *num_devices)
{ {
if (!Platform::IsValidOrDefault(platform))
{
return CL_INVALID_PLATFORM;
}
if (!Device::IsValidType(device_type))
{
return CL_INVALID_DEVICE_TYPE;
}
if ((num_entries == 0u && devices != nullptr) || (devices == nullptr && num_devices == nullptr))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_int ValidateGetDeviceInfo(const Device *devicePacked, cl_int ValidateGetDeviceInfo(const Device *device,
DeviceInfo param_namePacked, DeviceInfo 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 (!Device::IsValid(device))
{
return CL_INVALID_DEVICE;
}
if (param_name == DeviceInfo::InvalidEnum || (param_value_size == 0u && param_value != nullptr))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
......
...@@ -482,6 +482,7 @@ libangle_cl_sources = [ ...@@ -482,6 +482,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/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.cpp", "src/libANGLE/renderer/CLPlatformImpl.cpp",
"src/libANGLE/validationCL.cpp", "src/libANGLE/validationCL.cpp",
] ]
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "libGLESv2/cl_stubs_autogen.h" #include "libGLESv2/cl_stubs_autogen.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
#include "libGLESv2/cl_dispatch_table.h" #include "libGLESv2/cl_dispatch_table.h"
#include "libGLESv2/proc_table_cl.h" #include "libGLESv2/proc_table_cl.h"
...@@ -39,7 +40,7 @@ namespace cl ...@@ -39,7 +40,7 @@ namespace cl
namespace namespace
{ {
const Platform::List &InitializePlatforms(bool isIcd) const Platform::PtrList &InitializePlatforms(bool isIcd)
{ {
static bool initialized = false; static bool initialized = false;
if (!initialized) if (!initialized)
...@@ -47,20 +48,20 @@ const Platform::List &InitializePlatforms(bool isIcd) ...@@ -47,20 +48,20 @@ const Platform::List &InitializePlatforms(bool isIcd)
initialized = true; initialized = true;
#ifdef ANGLE_ENABLE_CL_PASSTHROUGH #ifdef ANGLE_ENABLE_CL_PASSTHROUGH
rx::CLPlatformImpl::ImplList implListCL = rx::CLPlatformCL::GetPlatforms(isIcd); rx::CLPlatformImpl::InitList initListCL = rx::CLPlatformCL::GetPlatforms(isIcd);
while (!implListCL.empty()) while (!initListCL.empty())
{ {
Platform::CreatePlatform(gCLIcdDispatchTable, std::move(implListCL.front())); Platform::CreatePlatform(gCLIcdDispatchTable, initListCL.front());
implListCL.pop_front(); initListCL.pop_front();
} }
#endif #endif
#ifdef ANGLE_ENABLE_VULKAN #ifdef ANGLE_ENABLE_VULKAN
rx::CLPlatformImpl::ImplList implListVk = rx::CLPlatformVk::GetPlatforms(); rx::CLPlatformImpl::InitList initListVk = rx::CLPlatformVk::GetPlatforms();
while (!implListVk.empty()) while (!initListVk.empty())
{ {
Platform::CreatePlatform(gCLIcdDispatchTable, std::move(implListVk.front())); Platform::CreatePlatform(gCLIcdDispatchTable, initListVk.front());
implListVk.pop_front(); initListVk.pop_front();
} }
#endif #endif
} }
...@@ -69,7 +70,7 @@ const Platform::List &InitializePlatforms(bool isIcd) ...@@ -69,7 +70,7 @@ const Platform::List &InitializePlatforms(bool isIcd)
cl_int GetPlatforms(cl_uint num_entries, Platform **platforms, cl_uint *num_platforms, bool isIcd) cl_int GetPlatforms(cl_uint num_entries, Platform **platforms, cl_uint *num_platforms, bool isIcd)
{ {
const Platform::List &platformList = InitializePlatforms(isIcd); const Platform::PtrList &platformList = InitializePlatforms(isIcd);
if (num_platforms != nullptr) if (num_platforms != nullptr)
{ {
*num_platforms = static_cast<cl_uint>(platformList.size()); *num_platforms = static_cast<cl_uint>(platformList.size());
...@@ -179,8 +180,8 @@ cl_int GetDeviceIDs(Platform *platform, ...@@ -179,8 +180,8 @@ cl_int GetDeviceIDs(Platform *platform,
Device **devices, Device **devices,
cl_uint *num_devices) cl_uint *num_devices)
{ {
WARN_NOT_SUPPORTED(GetDeviceIDs); return (platform != nullptr ? platform : Platform::GetDefault())
return 0; ->getDeviceIDs(device_type, num_entries, devices, num_devices);
} }
cl_int GetDeviceInfo(Device *device, cl_int GetDeviceInfo(Device *device,
...@@ -189,8 +190,7 @@ cl_int GetDeviceInfo(Device *device, ...@@ -189,8 +190,7 @@ cl_int GetDeviceInfo(Device *device,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetDeviceInfo); return device->getInfo(param_name, param_value_size, param_value, param_value_size_ret);
return 0;
} }
cl_int CreateSubDevices(Device *in_device, cl_int CreateSubDevices(Device *in_device,
......
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