Commit 69562546 by John Plate Committed by Angle LUCI CQ

CL: Refactor info structs and fix conformance bug

- Remove variable name prefix from Info structs to be more consistent with other ANGLE structs. - Fix CL object validation check with magics, since the Mesa solution doesn't work without RTTI. - Add support for some extensions required by OpenCL 1.1 and for some optional extensions. - Fix more conformance bugs. Bug: angleproject:6015 Change-Id: I41b1c45d95059a9994f5dc78bf9b74476cc6f2d4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2956349 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent dc334829
......@@ -19,6 +19,7 @@
#include "CL/cl_icd.h"
#include <cstddef>
#include <cstdint>
#include <type_traits>
namespace cl
......@@ -37,28 +38,25 @@ using UserFunc = void(CL_CALLBACK *)(void *args);
template <typename T = void>
struct Dispatch
{
Dispatch() : mDispatch(sDispatch) {}
explicit Dispatch(std::uint32_t magic) : mDispatch(sDispatch), mMagic(magic) {}
const cl_icd_dispatch &getDispatch() const { return *mDispatch; }
bool isValid() const { return mDispatch == sDispatch; }
static bool IsValid(const Dispatch *p) { return p != nullptr && p->isValid(); }
static const cl_icd_dispatch *sDispatch;
protected:
// This has to be the first member to be OpenCL ICD compatible
const cl_icd_dispatch *const mDispatch;
const std::uint32_t mMagic;
};
template <typename T>
const cl_icd_dispatch *Dispatch<T>::sDispatch = nullptr;
template <typename NativeObjectType>
template <typename NativeObjectType, std::uint32_t magic>
struct NativeObject : public Dispatch<>
{
NativeObject()
NativeObject() : Dispatch<>(magic)
{
static_assert(std::is_standard_layout<NativeObjectType>::value &&
offsetof(NativeObjectType, mDispatch) == 0u,
......@@ -85,35 +83,40 @@ struct NativeObject : public Dispatch<>
}
static NativeObjectType *CastNative(NativeObjectType *p) { return p; }
static bool IsValid(const NativeObjectType *p)
{
return p != nullptr && p->mDispatch == sDispatch && p->mMagic == magic;
}
};
} // namespace cl
struct _cl_platform_id : public cl::NativeObject<_cl_platform_id>
struct _cl_platform_id : public cl::NativeObject<_cl_platform_id, 0x12345678u>
{};
struct _cl_device_id : public cl::NativeObject<_cl_device_id>
struct _cl_device_id : public cl::NativeObject<_cl_device_id, 0x23456789u>
{};
struct _cl_context : public cl::NativeObject<_cl_context>
struct _cl_context : public cl::NativeObject<_cl_context, 0x3456789Au>
{};
struct _cl_command_queue : public cl::NativeObject<_cl_command_queue>
struct _cl_command_queue : public cl::NativeObject<_cl_command_queue, 0x456789ABu>
{};
struct _cl_mem : public cl::NativeObject<_cl_mem>
struct _cl_mem : public cl::NativeObject<_cl_mem, 0x56789ABCu>
{};
struct _cl_program : public cl::NativeObject<_cl_program>
struct _cl_program : public cl::NativeObject<_cl_program, 0x6789ABCDu>
{};
struct _cl_kernel : public cl::NativeObject<_cl_kernel>
struct _cl_kernel : public cl::NativeObject<_cl_kernel, 0x789ABCDEu>
{};
struct _cl_event : public cl::NativeObject<_cl_event>
struct _cl_event : public cl::NativeObject<_cl_event, 0x89ABCDEFu>
{};
struct _cl_sampler : public cl::NativeObject<_cl_sampler>
struct _cl_sampler : public cl::NativeObject<_cl_sampler, 0x9ABCDEF0u>
{};
#endif // ANGLECL_H_
......@@ -12,7 +12,7 @@
"scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1",
"9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db",
"src/libEGL/egl_loader_autogen.cpp":
......
......@@ -16,7 +16,7 @@
"scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1",
"9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db",
"src/common/entry_points_enum_autogen.cpp":
......
......@@ -6,7 +6,7 @@
"scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1",
"9945ba71a4a99464c81ab1341baf6697",
"src/libANGLE/capture/gl_enum_utils_autogen.cpp":
"132c9a258dbdcbd40ec5ae988e67350f",
"src/libANGLE/capture/gl_enum_utils_autogen.h":
......
......@@ -12,7 +12,7 @@
"scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1",
"9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db",
"src/libGL/proc_table_wgl_autogen.cpp":
......
......@@ -196,8 +196,24 @@ supported_egl_extensions = [
]
supported_cl_extensions = [
# Since OpenCL 1.1
"cl_khr_byte_addressable_store",
"cl_khr_global_int32_base_atomics",
"cl_khr_global_int32_extended_atomics",
"cl_khr_local_int32_base_atomics",
"cl_khr_local_int32_extended_atomics",
# OpenCL 2.0 - 2.2
"cl_khr_3d_image_writes",
"cl_khr_depth_images",
"cl_khr_image2d_from_buffer",
# Optional
"cl_khr_extended_versioning",
"cl_khr_fp64",
"cl_khr_icd",
"cl_khr_int64_base_atomics",
"cl_khr_int64_extended_atomics",
]
# Strip these suffixes from Context entry point names. NV is excluded (for now).
......
......@@ -206,6 +206,31 @@ bool EndsWith(const char *str, const char *suffix)
return EndsWithSuffix(str, strlen(str), suffix, strlen(suffix));
}
bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token)
{
if (token.empty())
{
return false;
}
// Compare token with all sub-strings terminated by delimiter or end of string
std::string::size_type start = 0u;
do
{
std::string::size_type end = tokenStr.find(delimiter, start);
if (end == std::string::npos)
{
end = tokenStr.length();
}
const std::string::size_type length = end - start;
if (length == token.length() && tokenStr.compare(start, length, token) == 0)
{
return true;
}
start = end + 1u;
} while (start < tokenStr.size());
return false;
}
void ToLower(std::string *str)
{
for (char &ch : *str)
......
......@@ -82,6 +82,11 @@ bool EndsWith(const std::string &str, const char *suffix);
// The comparison is case sensitive.
bool EndsWith(const char *str, const char *suffix);
// Check if the given token string contains the given token.
// The tokens are separated by the given delimiter.
// The comparison is case sensitive.
bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token);
// Convert to lower-case.
void ToLower(std::string *str);
......
......@@ -18,6 +18,8 @@ class Buffer final : public Memory
public:
// Front end entry functions, only called from OpenCL entry points
static bool IsValid(const _cl_mem *buffer);
cl_mem createSubBuffer(MemFlags flags,
cl_buffer_create_type createType,
const void *createInfo,
......@@ -26,8 +28,6 @@ class Buffer final : public Memory
bool isRegionValid(size_t offset, size_t size) const;
bool isRegionValid(const cl_buffer_region &region) const;
static bool IsValid(const _cl_mem *buffer);
public:
~Buffer() override;
......@@ -48,6 +48,11 @@ class Buffer final : public Memory
friend class Object;
};
inline bool Buffer::IsValid(const _cl_mem *buffer)
{
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == MemObjectType::Buffer;
}
inline bool Buffer::isRegionValid(size_t offset, size_t size) const
{
return offset < mSize && offset + size <= mSize;
......@@ -58,11 +63,6 @@ inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
return region.origin < mSize && region.origin + region.size <= mSize;
}
inline bool Buffer::IsValid(const _cl_mem *buffer)
{
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == MemObjectType::Buffer;
}
inline MemObjectType Buffer::getType() const
{
return MemObjectType::Buffer;
......
......@@ -21,6 +21,8 @@ class Context final : public _cl_context, public Object
public:
// Front end entry functions, only called from OpenCL entry points
static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_command_queue createCommandQueueWithProperties(cl_device_id device,
......@@ -108,8 +110,6 @@ class Context final : public _cl_context, public Object
cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
public:
using PropArray = std::vector<cl_context_properties>;
......@@ -190,14 +190,14 @@ inline T &Context::getImpl() const
inline bool Context::supportsImages() const
{
return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) {
return ptr->getInfo().mImageSupport == CL_TRUE;
return ptr->getInfo().imageSupport == CL_TRUE;
}) != mDevices.cend());
}
inline bool Context::supportsIL() const
{
return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) {
return !ptr->getInfo().mIL_Version.empty();
return !ptr->getInfo().IL_Version.empty();
}) != mDevices.cend());
}
......
......@@ -87,12 +87,12 @@ inline const rx::CLDeviceImpl::Info &Device::getInfo() const
inline cl_version Device::getVersion() const
{
return mInfo.mVersion;
return mInfo.version;
}
inline bool Device::isVersionOrNewer(cl_uint major, cl_uint minor) const
{
return mInfo.mVersion >= CL_MAKE_VERSION(major, minor, 0u);
return mInfo.version >= CL_MAKE_VERSION(major, minor, 0u);
}
template <typename T>
......
......@@ -36,7 +36,7 @@ cl_int Event::getInfo(EventInfo name, size_t valueSize, void *value, size_t *val
switch (name)
{
case EventInfo::CommandQueue:
valPointer = mCommandQueue->getNative();
valPointer = CommandQueue::CastNative(mCommandQueue.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
......
......@@ -14,6 +14,23 @@
namespace cl
{
bool Image::IsTypeValid(MemObjectType imageType)
{
switch (imageType)
{
case MemObjectType::Image1D:
case MemObjectType::Image2D:
case MemObjectType::Image3D:
case MemObjectType::Image1D_Array:
case MemObjectType::Image2D_Array:
case MemObjectType::Image1D_Buffer:
break;
default:
return false;
}
return true;
}
cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
size_t valSizeT = 0u;
......@@ -93,23 +110,6 @@ cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *val
return CL_SUCCESS;
}
bool Image::IsTypeValid(MemObjectType imageType)
{
switch (imageType)
{
case MemObjectType::Image1D:
case MemObjectType::Image2D:
case MemObjectType::Image3D:
case MemObjectType::Image1D_Array:
case MemObjectType::Image2D_Array:
case MemObjectType::Image1D_Buffer:
break;
default:
return false;
}
return true;
}
Image::~Image() = default;
bool Image::isRegionValid(const size_t origin[3], const size_t region[3]) const
......
......@@ -20,11 +20,11 @@ class Image final : public Memory
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
static bool IsTypeValid(MemObjectType imageType);
static bool IsValid(const _cl_mem *image);
cl_int getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
public:
~Image() override;
......
......@@ -30,12 +30,12 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v
switch (name)
{
case KernelInfo::FunctionName:
copyValue = mInfo.mFunctionName.c_str();
copySize = mInfo.mFunctionName.length() + 1u;
copyValue = mInfo.functionName.c_str();
copySize = mInfo.functionName.length() + 1u;
break;
case KernelInfo::NumArgs:
copyValue = &mInfo.mNumArgs;
copySize = sizeof(mInfo.mNumArgs);
copyValue = &mInfo.numArgs;
copySize = sizeof(mInfo.numArgs);
break;
case KernelInfo::ReferenceCount:
valUInt = getRefCount();
......@@ -53,8 +53,8 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v
copySize = sizeof(valPointer);
break;
case KernelInfo::Attributes:
copyValue = mInfo.mAttributes.c_str();
copySize = mInfo.mAttributes.length() + 1u;
copyValue = mInfo.attributes.c_str();
copySize = mInfo.attributes.length() + 1u;
break;
default:
return CL_INVALID_VALUE;
......@@ -99,7 +99,7 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device,
return CL_INVALID_DEVICE;
}
}
const rx::CLKernelImpl::WorkGroupInfo &info = mInfo.mWorkGroups[index];
const rx::CLKernelImpl::WorkGroupInfo &info = mInfo.workGroups[index];
const void *copyValue = nullptr;
size_t copySize = 0u;
......@@ -107,28 +107,28 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device,
switch (name)
{
case KernelWorkGroupInfo::GlobalWorkSize:
copyValue = &info.mGlobalWorkSize;
copySize = sizeof(info.mGlobalWorkSize);
copyValue = &info.globalWorkSize;
copySize = sizeof(info.globalWorkSize);
break;
case KernelWorkGroupInfo::WorkGroupSize:
copyValue = &info.mWorkGroupSize;
copySize = sizeof(info.mWorkGroupSize);
copyValue = &info.workGroupSize;
copySize = sizeof(info.workGroupSize);
break;
case KernelWorkGroupInfo::CompileWorkGroupSize:
copyValue = &info.mCompileWorkGroupSize;
copySize = sizeof(info.mCompileWorkGroupSize);
copyValue = &info.compileWorkGroupSize;
copySize = sizeof(info.compileWorkGroupSize);
break;
case KernelWorkGroupInfo::LocalMemSize:
copyValue = &info.mLocalMemSize;
copySize = sizeof(info.mLocalMemSize);
copyValue = &info.localMemSize;
copySize = sizeof(info.localMemSize);
break;
case KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple:
copyValue = &info.mPrefWorkGroupSizeMultiple;
copySize = sizeof(info.mPrefWorkGroupSizeMultiple);
copyValue = &info.prefWorkGroupSizeMultiple;
copySize = sizeof(info.prefWorkGroupSizeMultiple);
break;
case KernelWorkGroupInfo::PrivateMemSize:
copyValue = &info.mPrivateMemSize;
copySize = sizeof(info.mPrivateMemSize);
copyValue = &info.privateMemSize;
copySize = sizeof(info.privateMemSize);
break;
default:
return CL_INVALID_VALUE;
......@@ -160,31 +160,31 @@ cl_int Kernel::getArgInfo(cl_uint argIndex,
void *value,
size_t *valueSizeRet) const
{
const rx::CLKernelImpl::ArgInfo &info = mInfo.mArgs[argIndex];
const rx::CLKernelImpl::ArgInfo &info = mInfo.args[argIndex];
const void *copyValue = nullptr;
size_t copySize = 0u;
switch (name)
{
case KernelArgInfo::AddressQualifier:
copyValue = &info.mAddressQualifier;
copySize = sizeof(info.mAddressQualifier);
copyValue = &info.addressQualifier;
copySize = sizeof(info.addressQualifier);
break;
case KernelArgInfo::AccessQualifier:
copyValue = &info.mAccessQualifier;
copySize = sizeof(info.mAccessQualifier);
copyValue = &info.accessQualifier;
copySize = sizeof(info.accessQualifier);
break;
case KernelArgInfo::TypeName:
copyValue = info.mTypeName.c_str();
copySize = info.mTypeName.length() + 1u;
copyValue = info.typeName.c_str();
copySize = info.typeName.length() + 1u;
break;
case KernelArgInfo::TypeQualifier:
copyValue = &info.mTypeQualifier;
copySize = sizeof(info.mTypeQualifier);
copyValue = &info.typeQualifier;
copySize = sizeof(info.typeQualifier);
break;
case KernelArgInfo::Name:
copyValue = info.mName.c_str();
copySize = info.mName.length() + 1u;
copyValue = info.name.c_str();
copySize = info.name.length() + 1u;
break;
default:
return CL_INVALID_VALUE;
......
......@@ -15,6 +15,34 @@
namespace cl
{
namespace
{
MemFlags InheritMemFlags(MemFlags flags, Memory *parent)
{
if (parent != nullptr)
{
const MemFlags parentFlags = parent->getFlags();
const MemFlags access(CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
const MemFlags hostAccess(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY |
CL_MEM_HOST_NO_ACCESS);
const MemFlags hostPtrFlags(CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
CL_MEM_COPY_HOST_PTR);
if (flags.isNotSet(access))
{
flags.set(parentFlags.mask(access));
}
if (flags.isNotSet(hostAccess))
{
flags.set(parentFlags.mask(hostAccess));
}
flags.set(parentFlags.mask(hostPtrFlags));
}
return flags;
}
} // namespace
cl_int Memory::setDestructorCallback(MemoryCB pfnNotify, void *userData)
{
mDestructorCallbacks.emplace(pfnNotify, userData);
......@@ -118,30 +146,6 @@ Memory::~Memory()
}
}
MemFlags Memory::getEffectiveFlags() const
{
MemFlags flags = mFlags;
if (mParent)
{
const MemFlags parent = mParent->getFlags();
const MemFlags access(CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
const MemFlags hostAccess(CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY |
CL_MEM_HOST_NO_ACCESS);
const MemFlags hostPtrFlags(CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR |
CL_MEM_COPY_HOST_PTR);
if (flags.isNotSet(access))
{
flags.set(parent.mask(access));
}
if (flags.isNotSet(hostAccess))
{
flags.set(parent.mask(hostAccess));
}
flags.set(parent.mask(hostPtrFlags));
}
return flags;
}
Memory::Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
......@@ -164,12 +168,12 @@ Memory::Memory(const Buffer &buffer,
size_t size,
cl_int &errorCode)
: mContext(parent.mContext),
mFlags(flags),
mFlags(InheritMemFlags(flags, &parent)),
mHostPtr(parent.mHostPtr != nullptr ? static_cast<char *>(parent.mHostPtr) + offset
: nullptr),
mParent(&parent),
mOffset(offset),
mImpl(parent.mImpl->createSubBuffer(buffer, size, errorCode)),
mImpl(parent.mImpl->createSubBuffer(buffer, flags, size, errorCode)),
mSize(size)
{}
......@@ -184,10 +188,10 @@ Memory::Memory(const Image &image,
cl_int &errorCode)
: mContext(&context),
mProperties(std::move(properties)),
mFlags(flags),
mFlags(InheritMemFlags(flags, parent)),
mHostPtr(flags.isSet(CL_MEM_USE_HOST_PTR) ? hostPtr : nullptr),
mParent(parent),
mImpl(context.getImpl().createImage(image, format, desc, hostPtr, errorCode)),
mImpl(context.getImpl().createImage(image, flags, format, desc, hostPtr, errorCode)),
mSize(mImpl ? mImpl->getSize(errorCode) : 0u)
{}
......
......@@ -44,8 +44,6 @@ class Memory : public _cl_mem, public Object
template <typename T = rx::CLMemoryImpl>
T &getImpl() const;
MemFlags getEffectiveFlags() const;
static Memory *Cast(cl_mem memobj);
protected:
......
......@@ -116,37 +116,37 @@ cl_int Platform::getInfo(PlatformInfo name,
switch (name)
{
case PlatformInfo::Profile:
copyValue = mInfo.mProfile.c_str();
copySize = mInfo.mProfile.length() + 1u;
copyValue = mInfo.profile.c_str();
copySize = mInfo.profile.length() + 1u;
break;
case PlatformInfo::Version:
copyValue = mInfo.mVersionStr.c_str();
copySize = mInfo.mVersionStr.length() + 1u;
copyValue = mInfo.versionStr.c_str();
copySize = mInfo.versionStr.length() + 1u;
break;
case PlatformInfo::NumericVersion:
copyValue = &mInfo.mVersion;
copySize = sizeof(mInfo.mVersion);
copyValue = &mInfo.version;
copySize = sizeof(mInfo.version);
break;
case PlatformInfo::Name:
copyValue = mInfo.mName.c_str();
copySize = mInfo.mName.length() + 1u;
copyValue = mInfo.name.c_str();
copySize = mInfo.name.length() + 1u;
break;
case PlatformInfo::Vendor:
copyValue = kVendor;
copySize = sizeof(kVendor);
break;
case PlatformInfo::Extensions:
copyValue = mInfo.mExtensions.c_str();
copySize = mInfo.mExtensions.length() + 1u;
copyValue = mInfo.extensions.c_str();
copySize = mInfo.extensions.length() + 1u;
break;
case PlatformInfo::ExtensionsWithVersion:
copyValue = mInfo.mExtensionsWithVersion.data();
copySize = mInfo.mExtensionsWithVersion.size() *
sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type);
copyValue = mInfo.extensionsWithVersion.data();
copySize = mInfo.extensionsWithVersion.size() *
sizeof(decltype(mInfo.extensionsWithVersion)::value_type);
break;
case PlatformInfo::HostTimerResolution:
copyValue = &mInfo.mHostTimerRes;
copySize = sizeof(mInfo.mHostTimerRes);
copyValue = &mInfo.hostTimerRes;
copySize = sizeof(mInfo.hostTimerRes);
break;
case PlatformInfo::IcdSuffix:
copyValue = kIcdSuffix;
......@@ -185,7 +185,7 @@ cl_int Platform::getDeviceIDs(DeviceType deviceType,
cl_uint found = 0u;
for (const DevicePtr &device : mDevices)
{
if (IsDeviceTypeMatch(deviceType, device->getInfo().mType))
if (IsDeviceTypeMatch(deviceType, device->getInfo().type))
{
if (devices != nullptr && found < numEntries)
{
......
......@@ -99,7 +99,7 @@ inline Platform *Platform::CastOrDefault(cl_platform_id platform)
// default, so this function returns true for a nullptr value if a default platform exists.
inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform)
{
return platform != nullptr ? platform->isValid() : GetDefault() != nullptr;
return platform != nullptr ? IsValid(platform) : GetDefault() != nullptr;
}
inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
......@@ -109,12 +109,12 @@ inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
inline cl_version Platform::getVersion() const
{
return mInfo.mVersion;
return mInfo.version;
}
inline bool Platform::isVersionOrNewer(cl_uint major, cl_uint minor) const
{
return mInfo.mVersion >= CL_MAKE_VERSION(major, minor, 0u);
return mInfo.version >= CL_MAKE_VERSION(major, minor, 0u);
}
inline const DevicePtrs &Platform::getDevices() const
......
......@@ -36,6 +36,7 @@ class CLContextImpl : angle::NonCopyable
cl_int &errorCode) = 0;
virtual CLMemoryImpl::Ptr createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format,
const cl::ImageDescriptor &desc,
void *hostPtr,
......
......@@ -14,7 +14,7 @@ namespace rx
CLDeviceImpl::Info::Info() = default;
CLDeviceImpl::Info::Info(cl::DeviceType type) : mType(type) {}
CLDeviceImpl::Info::Info(cl::DeviceType deviceType) : type(deviceType) {}
CLDeviceImpl::Info::~Info() = default;
......
......@@ -8,7 +8,7 @@
#ifndef LIBANGLE_RENDERER_CLDEVICEIMPL_H_
#define LIBANGLE_RENDERER_CLDEVICEIMPL_H_
#include "libANGLE/renderer/CLtypes.h"
#include "libANGLE/renderer/CLExtensions.h"
namespace rx
{
......@@ -22,10 +22,10 @@ class CLDeviceImpl : angle::NonCopyable
using CreateData = std::pair<cl::DeviceType, CreateFunc>;
using CreateDatas = std::list<CreateData>;
struct Info
struct Info : public CLExtensions
{
Info();
explicit Info(cl::DeviceType type);
explicit Info(cl::DeviceType deviceType);
~Info();
Info(const Info &) = delete;
......@@ -34,37 +34,36 @@ class CLDeviceImpl : angle::NonCopyable
Info(Info &&);
Info &operator=(Info &&);
bool isValid() const { return mVersion != 0u; }
bool isValid() const { return version != 0u; }
// In the order as they appear in the OpenCL specification V3.0.7, table 5
cl::DeviceType mType;
std::vector<size_t> mMaxWorkItemSizes;
cl_ulong mMaxMemAllocSize = 0u;
cl_bool mImageSupport = CL_FALSE;
std::string mIL_Version;
NameVersionVector mILsWithVersion;
size_t mImage2D_MaxWidth = 0u;
size_t mImage2D_MaxHeight = 0u;
size_t mImage3D_MaxWidth = 0u;
size_t mImage3D_MaxHeight = 0u;
size_t mImage3D_MaxDepth = 0u;
size_t mImageMaxBufferSize = 0u;
size_t mImageMaxArraySize = 0u;
cl_uint mImagePitchAlignment = 0u;
cl_uint mImageBaseAddressAlignment = 0u;
cl_uint mMemBaseAddrAlign = 0u;
cl::DeviceExecCapabilities mExecCapabilities;
cl_uint mQueueOnDeviceMaxSize = 0u;
std::string mBuiltInKernels;
NameVersionVector mBuiltInKernelsWithVersion;
std::string mVersionStr;
cl_version mVersion = 0u;
NameVersionVector mOpenCL_C_AllVersions;
NameVersionVector mOpenCL_C_Features;
std::string mExtensions;
NameVersionVector mExtensionsWithVersion;
std::vector<cl_device_partition_property> mPartitionProperties;
std::vector<cl_device_partition_property> mPartitionType;
cl::DeviceType type;
std::vector<size_t> maxWorkItemSizes;
cl_ulong maxMemAllocSize = 0u;
cl_bool imageSupport = CL_FALSE;
std::string IL_Version;
NameVersionVector ILsWithVersion;
size_t image2D_MaxWidth = 0u;
size_t image2D_MaxHeight = 0u;
size_t image3D_MaxWidth = 0u;
size_t image3D_MaxHeight = 0u;
size_t image3D_MaxDepth = 0u;
size_t imageMaxBufferSize = 0u;
size_t imageMaxArraySize = 0u;
cl_uint imagePitchAlignment = 0u;
cl_uint imageBaseAddressAlignment = 0u;
cl_uint memBaseAddrAlign = 0u;
cl::DeviceExecCapabilities execCapabilities;
cl_uint queueOnDeviceMaxSize = 0u;
std::string builtInKernels;
NameVersionVector builtInKernelsWithVersion;
std::string versionStr;
cl_version version = 0u;
NameVersionVector OpenCL_C_AllVersions;
NameVersionVector OpenCL_C_Features;
NameVersionVector extensionsWithVersion;
std::vector<cl_device_partition_property> partitionProperties;
std::vector<cl_device_partition_property> partitionType;
};
CLDeviceImpl(const cl::Device &device);
......
//
// 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.
//
// CLExtensions.cpp: Implements the struct methods for CLExtension.
#include "libANGLE/renderer/CLExtensions.h"
#include "common/string_utils.h"
namespace rx
{
CLExtensions::CLExtensions() = default;
CLExtensions::~CLExtensions() = default;
CLExtensions::CLExtensions(CLExtensions &&) = default;
CLExtensions &CLExtensions::operator=(CLExtensions &&) = default;
void CLExtensions::initializeExtensions(std::string &&extensionStr)
{
extensions.assign(std::move(extensionStr));
if (extensions.empty())
{
return;
}
auto hasExtension = [&](const std::string &extension) {
return angle::ContainsToken(extensions, ' ', extension);
};
khrByteAddressableStore = hasExtension("cl_khr_byte_addressable_store");
khrGlobalInt32BaseAtomics = hasExtension("cl_khr_global_int32_base_atomics");
khrGlobalInt32ExtendedAtomics = hasExtension("cl_khr_global_int32_extended_atomics");
khrLocalInt32BaseAtomics = hasExtension("cl_khr_local_int32_base_atomics");
khrLocalInt32ExtendedAtomics = hasExtension("cl_khr_local_int32_extended_atomics");
khr3D_ImageWrites = hasExtension("cl_khr_3d_image_writes");
khrDepthImages = hasExtension("cl_khr_depth_images");
khrImage2D_FromBuffer = hasExtension("cl_khr_image2d_from_buffer");
khrExtendedVersioning = hasExtension("cl_khr_extended_versioning");
khrFP64 = hasExtension("cl_khr_fp64");
khrICD = hasExtension("cl_khr_icd");
khrInt64BaseAtomics = hasExtension("cl_khr_int64_base_atomics");
khrInt64ExtendedAtomics = hasExtension("cl_khr_int64_extended_atomics");
}
} // namespace rx
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLExtensions.h: Defines the rx::CLExtensions struct.
#ifndef LIBANGLE_RENDERER_CLEXTENSIONS_H_
#define LIBANGLE_RENDERER_CLEXTENSIONS_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
struct CLExtensions
{
CLExtensions();
~CLExtensions();
CLExtensions(const CLExtensions &) = delete;
CLExtensions &operator=(const CLExtensions &) = delete;
CLExtensions(CLExtensions &&);
CLExtensions &operator=(CLExtensions &&);
void initializeExtensions(std::string &&extensionStr);
std::string extensions;
// These Khronos extension names must be returned by all devices that support OpenCL 1.1.
bool khrByteAddressableStore = false; // cl_khr_byte_addressable_store
bool khrGlobalInt32BaseAtomics = false; // cl_khr_global_int32_base_atomics
bool khrGlobalInt32ExtendedAtomics = false; // cl_khr_global_int32_extended_atomics
bool khrLocalInt32BaseAtomics = false; // cl_khr_local_int32_base_atomics
bool khrLocalInt32ExtendedAtomics = false; // cl_khr_local_int32_extended_atomics
// These Khronos extension names must be returned by all devices that support
// OpenCL 2.0, OpenCL 2.1, or OpenCL 2.2. For devices that support OpenCL 3.0, these
// extension names must be returned when and only when the optional feature is supported.
bool khr3D_ImageWrites = false; // cl_khr_3d_image_writes
bool khrDepthImages = false; // cl_khr_depth_images
bool khrImage2D_FromBuffer = false; // cl_khr_image2d_from_buffer
// Optional extensions
bool khrExtendedVersioning = false; // cl_khr_extended_versioning
bool khrFP64 = false; // cl_khr_fp64
bool khrICD = false; // cl_khr_icd
bool khrInt64BaseAtomics = false; // cl_khr_int64_base_atomics
bool khrInt64ExtendedAtomics = false; // cl_khr_int64_extended_atomics
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CLEXTENSIONS_H_
......@@ -31,12 +31,12 @@ class CLKernelImpl : angle::NonCopyable
WorkGroupInfo(WorkGroupInfo &&);
WorkGroupInfo &operator=(WorkGroupInfo &&);
std::array<size_t, 3u> mGlobalWorkSize = {};
size_t mWorkGroupSize = 0u;
std::array<size_t, 3u> mCompileWorkGroupSize = {};
cl_ulong mLocalMemSize = 0u;
size_t mPrefWorkGroupSizeMultiple = 0u;
cl_ulong mPrivateMemSize = 0u;
std::array<size_t, 3u> globalWorkSize = {};
size_t workGroupSize = 0u;
std::array<size_t, 3u> compileWorkGroupSize = {};
cl_ulong localMemSize = 0u;
size_t prefWorkGroupSizeMultiple = 0u;
cl_ulong privateMemSize = 0u;
};
struct ArgInfo
......@@ -50,13 +50,13 @@ class CLKernelImpl : angle::NonCopyable
ArgInfo(ArgInfo &&);
ArgInfo &operator=(ArgInfo &&);
bool isAvailable() const { return !mName.empty(); }
bool isAvailable() const { return !name.empty(); }
cl_kernel_arg_address_qualifier mAddressQualifier = 0u;
cl_kernel_arg_access_qualifier mAccessQualifier = 0u;
std::string mTypeName;
cl_kernel_arg_type_qualifier mTypeQualifier = 0u;
std::string mName;
cl_kernel_arg_address_qualifier addressQualifier = 0u;
cl_kernel_arg_access_qualifier accessQualifier = 0u;
std::string typeName;
cl_kernel_arg_type_qualifier typeQualifier = 0u;
std::string name;
};
struct Info
......@@ -70,14 +70,14 @@ class CLKernelImpl : angle::NonCopyable
Info(Info &&);
Info &operator=(Info &&);
bool isValid() const { return !mFunctionName.empty(); }
bool isValid() const { return !functionName.empty(); }
std::string mFunctionName;
cl_uint mNumArgs = 0u;
std::string mAttributes;
std::string functionName;
cl_uint numArgs = 0u;
std::string attributes;
std::vector<WorkGroupInfo> mWorkGroups;
std::vector<ArgInfo> mArgs;
std::vector<WorkGroupInfo> workGroups;
std::vector<ArgInfo> args;
};
CLKernelImpl(const cl::Kernel &kernel);
......
......@@ -24,6 +24,7 @@ class CLMemoryImpl : angle::NonCopyable
virtual size_t getSize(cl_int &errorCode) const = 0;
virtual CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size,
cl_int &errorCode) = 0;
......
......@@ -10,6 +10,7 @@
#include "libANGLE/renderer/CLContextImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h"
#include "libANGLE/renderer/CLExtensions.h"
namespace rx
{
......@@ -21,7 +22,7 @@ class CLPlatformImpl : angle::NonCopyable
using CreateFunc = std::function<Ptr(const cl::Platform &)>;
using CreateFuncs = std::list<CreateFunc>;
struct Info
struct Info : public CLExtensions
{
Info();
~Info();
......@@ -32,15 +33,14 @@ class CLPlatformImpl : angle::NonCopyable
Info(Info &&);
Info &operator=(Info &&);
bool isValid() const { return mVersion != 0u; }
bool isValid() const { return version != 0u; }
std::string mProfile;
std::string mVersionStr;
cl_version mVersion = 0u;
std::string mName;
std::string mExtensions;
NameVersionVector mExtensionsWithVersion;
cl_ulong mHostTimerRes = 0u;
std::string profile;
std::string versionStr;
cl_version version = 0u;
std::string name;
NameVersionVector extensionsWithVersion;
cl_ulong hostTimerRes = 0u;
};
explicit CLPlatformImpl(const cl::Platform &platform);
......
......@@ -126,6 +126,7 @@ CLMemoryImpl::Ptr CLContextCL::createBuffer(const cl::Buffer &buffer,
}
CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format,
const cl::ImageDescriptor &desc,
void *hostPtr,
......@@ -144,14 +145,14 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
if (image.getProperties().empty())
{
nativeImage = mNative->getDispatch().clCreateImage(
mNative, image.getFlags().get(), &format, &nativeDesc, hostPtr, &errorCode);
nativeImage = mNative->getDispatch().clCreateImage(mNative, flags.get(), &format,
&nativeDesc, hostPtr, &errorCode);
}
else
{
nativeImage = mNative->getDispatch().clCreateImageWithProperties(
mNative, image.getProperties().data(), image.getFlags().get(), &format, &nativeDesc,
hostPtr, &errorCode);
mNative, image.getProperties().data(), flags.get(), &format, &nativeDesc, hostPtr,
&errorCode);
}
}
else
......@@ -160,12 +161,12 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
{
case cl::MemObjectType::Image2D:
nativeImage = mNative->getDispatch().clCreateImage2D(
mNative, image.getFlags().get(), &format, desc.width, desc.height,
desc.rowPitch, hostPtr, &errorCode);
mNative, flags.get(), &format, desc.width, desc.height, desc.rowPitch, hostPtr,
&errorCode);
break;
case cl::MemObjectType::Image3D:
nativeImage = mNative->getDispatch().clCreateImage3D(
mNative, image.getFlags().get(), &format, desc.width, desc.height, desc.depth,
mNative, flags.get(), &format, desc.width, desc.height, desc.depth,
desc.rowPitch, desc.slicePitch, hostPtr, &errorCode);
break;
default:
......
......@@ -38,6 +38,7 @@ class CLContextCL : public CLContextImpl
cl_int &errorCode) override;
CLMemoryImpl::Ptr createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format,
const cl::ImageDescriptor &desc,
void *hostPtr,
......
......@@ -68,7 +68,7 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
Info info(type);
std::vector<char> valString;
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes))
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.maxWorkItemSizes))
{
return Info{};
}
......@@ -76,22 +76,22 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
// "The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM."
// https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clGetDeviceInfo
// Custom devices are currently not supported by this back end.
if (info.mMaxWorkItemSizes.size() < 3u || info.mMaxWorkItemSizes[0] == 0u ||
info.mMaxWorkItemSizes[1] == 0u || info.mMaxWorkItemSizes[2] == 0u)
if (info.maxWorkItemSizes.size() < 3u || info.maxWorkItemSizes[0] == 0u ||
info.maxWorkItemSizes[1] == 0u || info.maxWorkItemSizes[2] == 0u)
{
ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES";
return Info{};
}
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.mMaxMemAllocSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageSupport, info.mImageSupport) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxWidth, info.mImage2D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.mImage2D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.mImage3D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.mImage3D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.mImage3D_MaxDepth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.mMemBaseAddrAlign) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExecutionCapabilities, info.mExecCapabilities))
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.maxMemAllocSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageSupport, info.imageSupport) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxWidth, info.image2D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.image2D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.image3D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.image3D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.image3D_MaxDepth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.memBaseAddrAlign) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExecutionCapabilities, info.execCapabilities))
{
return Info{};
}
......@@ -100,76 +100,83 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
{
return Info{};
}
info.mVersionStr.assign(valString.data());
info.versionStr.assign(valString.data());
// Limit version number to supported version
if (info.mVersionStr[7] != '1')
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
{
info.mVersionStr[7] = '1';
info.mVersionStr[9] = '2';
return Info{};
}
std::string extensionStr(valString.data());
info.mVersion = ExtractCLVersion(info.mVersionStr);
if (info.mVersion == 0u)
// TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/6053
if (info.versionStr.compare(0u, 15u, "OpenCL 3.0 CUDA", 15u) == 0)
{
return Info{};
extensionStr.append(" cl_khr_depth_images cl_khr_image2d_from_buffer");
}
if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
// Limit version number to supported version
if (info.versionStr[7] != '1')
{
info.versionStr[7] = '1';
info.versionStr[9] = '2';
}
info.version = ExtractCLVersion(info.versionStr);
if (info.version == 0u)
{
return Info{};
}
info.mExtensions.assign(valString.data());
RemoveUnsupportedCLExtensions(info.mExtensions);
if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0))
RemoveUnsupportedCLExtensions(extensionStr);
info.initializeExtensions(std::move(extensionStr));
if (info.version >= CL_MAKE_VERSION(1, 2, 0))
{
if (!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxBufferSize, info.mImageMaxBufferSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxArraySize, info.mImageMaxArraySize) ||
if (!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxBufferSize, info.imageMaxBufferSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxArraySize, info.imageMaxArraySize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernels, valString))
{
return Info{};
}
info.mBuiltInKernels.assign(valString.data());
info.builtInKernels.assign(valString.data());
if (!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties,
info.mPartitionProperties) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.mPartitionType))
info.partitionProperties) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.partitionType))
{
return Info{};
}
}
if (info.mVersion >= CL_MAKE_VERSION(2, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ImagePitchAlignment, info.mImagePitchAlignment) ||
if (info.version >= CL_MAKE_VERSION(2, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ImagePitchAlignment, info.imagePitchAlignment) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageBaseAddressAlignment,
info.mImageBaseAddressAlignment) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::QueueOnDeviceMaxSize, info.mQueueOnDeviceMaxSize)))
info.imageBaseAddressAlignment) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::QueueOnDeviceMaxSize, info.queueOnDeviceMaxSize)))
{
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(2, 1, 0))
if (info.version >= CL_MAKE_VERSION(2, 1, 0))
{
if (!GetDeviceInfo(mNative, cl::DeviceInfo::IL_Version, valString))
{
return Info{};
}
info.mIL_Version.assign(valString.data());
info.IL_Version.assign(valString.data());
}
if (info.mVersion >= CL_MAKE_VERSION(3, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.mILsWithVersion) ||
if (info.version >= CL_MAKE_VERSION(3, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.ILsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernelsWithVersion,
info.mBuiltInKernelsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions,
info.mOpenCL_C_AllVersions) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.mOpenCL_C_Features) ||
info.builtInKernelsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions, info.OpenCL_C_AllVersions) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.OpenCL_C_Features) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExtensionsWithVersion,
info.mExtensionsWithVersion)))
info.extensionsWithVersion)))
{
return Info{};
}
RemoveUnsupportedCLExtensions(info.mExtensionsWithVersion);
RemoveUnsupportedCLExtensions(info.extensionsWithVersion);
return info;
}
......
......@@ -172,55 +172,55 @@ CLKernelImpl::Info CLKernelCL::createInfo(cl_int &errorCode) const
const cl::Context &ctx = mKernel.getProgram().getContext();
Info info;
if (!GetKernelString(mNative, cl::KernelInfo::FunctionName, info.mFunctionName, errorCode) ||
!GetKernelInfo(mNative, cl::KernelInfo::NumArgs, info.mNumArgs, errorCode) ||
if (!GetKernelString(mNative, cl::KernelInfo::FunctionName, info.functionName, errorCode) ||
!GetKernelInfo(mNative, cl::KernelInfo::NumArgs, info.numArgs, errorCode) ||
(ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
!GetKernelString(mNative, cl::KernelInfo::Attributes, info.mAttributes, errorCode)))
!GetKernelString(mNative, cl::KernelInfo::Attributes, info.attributes, errorCode)))
{
return Info{};
}
info.mWorkGroups.resize(ctx.getDevices().size());
info.workGroups.resize(ctx.getDevices().size());
for (size_t index = 0u; index < ctx.getDevices().size(); ++index)
{
const cl_device_id device = ctx.getDevices()[index]->getImpl<CLDeviceCL>().getNative();
WorkGroupInfo &workGroup = info.mWorkGroups[index];
WorkGroupInfo &workGroup = info.workGroups[index];
if ((ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
ctx.getDevices()[index]->supportsBuiltInKernel(info.mFunctionName) &&
ctx.getDevices()[index]->supportsBuiltInKernel(info.functionName) &&
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::GlobalWorkSize,
workGroup.mGlobalWorkSize, errorCode)) ||
workGroup.globalWorkSize, errorCode)) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::WorkGroupSize,
workGroup.mWorkGroupSize, errorCode) ||
workGroup.workGroupSize, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::CompileWorkGroupSize,
workGroup.mCompileWorkGroupSize, errorCode) ||
workGroup.compileWorkGroupSize, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::LocalMemSize,
workGroup.mLocalMemSize, errorCode) ||
workGroup.localMemSize, errorCode) ||
!GetWorkGroupInfo(mNative, device,
cl::KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple,
workGroup.mPrefWorkGroupSizeMultiple, errorCode) ||
workGroup.prefWorkGroupSizeMultiple, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::PrivateMemSize,
workGroup.mPrivateMemSize, errorCode))
workGroup.privateMemSize, errorCode))
{
return Info{};
}
}
info.mArgs.resize(info.mNumArgs);
info.args.resize(info.numArgs);
if (ctx.getPlatform().isVersionOrNewer(1u, 2u))
{
for (cl_uint index = 0u; index < info.mNumArgs; ++index)
for (cl_uint index = 0u; index < info.numArgs; ++index)
{
ArgInfo &arg = info.mArgs[index];
ArgInfo &arg = info.args[index];
if (!GetArgInfo(mNative, index, cl::KernelArgInfo::AddressQualifier,
arg.mAddressQualifier, errorCode) ||
!GetArgInfo(mNative, index, cl::KernelArgInfo::AccessQualifier,
arg.mAccessQualifier, errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::TypeName, arg.mTypeName,
arg.addressQualifier, errorCode) ||
!GetArgInfo(mNative, index, cl::KernelArgInfo::AccessQualifier, arg.accessQualifier,
errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::TypeName, arg.typeName,
errorCode) ||
!GetArgInfo(mNative, index, cl::KernelArgInfo::TypeQualifier, arg.mTypeQualifier,
!GetArgInfo(mNative, index, cl::KernelArgInfo::TypeQualifier, arg.typeQualifier,
errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::Name, arg.mName, errorCode))
!GetArgString(mNative, index, cl::KernelArgInfo::Name, arg.name, errorCode))
{
return Info{};
}
......
......@@ -46,12 +46,13 @@ size_t CLMemoryCL::getSize(cl_int &errorCode) const
}
CLMemoryImpl::Ptr CLMemoryCL::createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size,
cl_int &errorCode)
{
const cl_buffer_region region = {buffer.getOffset(), size};
const cl_mem nativeBuffer = mNative->getDispatch().clCreateSubBuffer(
mNative, buffer.getFlags().get(), CL_BUFFER_CREATE_TYPE_REGION, &region, &errorCode);
mNative, flags.get(), CL_BUFFER_CREATE_TYPE_REGION, &region, &errorCode);
return CLMemoryImpl::Ptr(nativeBuffer != nullptr ? new CLMemoryCL(buffer, nativeBuffer)
: nullptr);
}
......
......@@ -24,6 +24,7 @@ class CLMemoryCL : public CLMemoryImpl
size_t getSize(cl_int &errorCode) const override;
CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size,
cl_int &errorCode) override;
......
......@@ -124,20 +124,13 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
// Fetch common platform info
Info info;
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);
info.profile = GetPlatformString(mNative, cl::PlatformInfo::Profile);
info.versionStr = GetPlatformString(mNative, cl::PlatformInfo::Version);
info.name = GetPlatformString(mNative, cl::PlatformInfo::Name);
std::string extensionStr = GetPlatformString(mNative, cl::PlatformInfo::Extensions);
// Limit version number to supported version
if (info.mVersionStr[7] != '1')
{
info.mVersionStr[7] = '1';
info.mVersionStr[9] = '2';
}
if (vendor.empty() || info.mProfile.empty() || info.mVersionStr.empty() || info.mName.empty() ||
info.mExtensions.empty())
if (vendor.empty() || info.profile.empty() || info.versionStr.empty() || info.name.empty() ||
extensionStr.empty())
{
return Info{};
}
......@@ -149,27 +142,43 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
// Skip platform if it is not ICD compatible
if (info.mExtensions.find("cl_khr_icd") == std::string::npos)
// TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/6053
if (info.versionStr.compare(0u, 15u, "OpenCL 3.0 CUDA", 15u) == 0)
{
WARN() << "CL platform is not ICD compatible";
return Info{};
extensionStr.append(" cl_khr_depth_images cl_khr_image2d_from_buffer");
}
// Limit version number to supported version
if (info.versionStr[7] != '1')
{
info.versionStr[7] = '1';
info.versionStr[9] = '2';
}
const cl_version version = ExtractCLVersion(info.mVersionStr);
const cl_version version = ExtractCLVersion(info.versionStr);
if (version == 0u)
{
return Info{};
}
// Customize version string and name, and remove unsupported extensions
info.mVersionStr += " (ANGLE " ANGLE_VERSION_STRING ")";
info.mName.insert(0u, "ANGLE pass-through -> ");
RemoveUnsupportedCLExtensions(info.mExtensions);
// Remove unsupported and initialize extensions
RemoveUnsupportedCLExtensions(extensionStr);
info.initializeExtensions(std::move(extensionStr));
// Skip platform if it is not ICD compatible
if (!info.khrICD)
{
WARN() << "CL platform is not ICD compatible";
return Info{};
}
// Customize version string and name
info.versionStr += " (ANGLE " ANGLE_VERSION_STRING ")";
info.name.insert(0u, "ANGLE pass-through -> ");
if (version >= CL_MAKE_VERSION(2, 1, 0) &&
mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_HOST_TIMER_RESOLUTION,
sizeof(info.mHostTimerRes), &info.mHostTimerRes,
sizeof(info.hostTimerRes), &info.hostTimerRes,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_HOST_TIMER_RESOLUTION";
......@@ -178,46 +187,46 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
if (version < CL_MAKE_VERSION(3, 0, 0))
{
info.mVersion = version;
info.version = version;
}
else
{
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_NUMERIC_VERSION,
sizeof(info.mVersion), &info.mVersion,
sizeof(info.version), &info.version,
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_NUMERIC_VERSION";
return Info{};
}
else if (CL_VERSION_MAJOR(info.mVersion) != CL_VERSION_MAJOR(version) ||
CL_VERSION_MINOR(info.mVersion) != CL_VERSION_MINOR(version))
else if (CL_VERSION_MAJOR(info.version) != CL_VERSION_MAJOR(version) ||
CL_VERSION_MINOR(info.version) != CL_VERSION_MINOR(version))
{
WARN() << "CL_PLATFORM_NUMERIC_VERSION = " << CL_VERSION_MAJOR(info.mVersion) << '.'
<< CL_VERSION_MINOR(info.mVersion)
<< " does not match version string: " << info.mVersionStr;
WARN() << "CL_PLATFORM_NUMERIC_VERSION = " << CL_VERSION_MAJOR(info.version) << '.'
<< CL_VERSION_MINOR(info.version)
<< " does not match version string: " << info.versionStr;
}
size_t valueSize = 0u;
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
0u, nullptr, &valueSize) != CL_SUCCESS ||
(valueSize % sizeof(decltype(info.mExtensionsWithVersion)::value_type)) != 0u)
(valueSize % sizeof(decltype(info.extensionsWithVersion)::value_type)) != 0u)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
return Info{};
}
info.mExtensionsWithVersion.resize(
valueSize / sizeof(decltype(info.mExtensionsWithVersion)::value_type));
info.extensionsWithVersion.resize(valueSize /
sizeof(decltype(info.extensionsWithVersion)::value_type));
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
valueSize, info.mExtensionsWithVersion.data(),
valueSize, info.extensionsWithVersion.data(),
nullptr) != CL_SUCCESS)
{
ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
return Info{};
}
RemoveUnsupportedCLExtensions(info.mExtensionsWithVersion);
RemoveUnsupportedCLExtensions(info.extensionsWithVersion);
}
if (info.mVersion >= CL_MAKE_VERSION(1, 1, 0) &&
if (info.version >= CL_MAKE_VERSION(1, 1, 0) &&
(mNative->getDispatch().clSetEventCallback == nullptr ||
mNative->getDispatch().clCreateSubBuffer == nullptr ||
mNative->getDispatch().clSetMemObjectDestructorCallback == nullptr ||
......@@ -231,7 +240,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(1, 2, 0) &&
if (info.version >= CL_MAKE_VERSION(1, 2, 0) &&
(mNative->getDispatch().clCreateSubDevices == nullptr ||
mNative->getDispatch().clRetainDevice == nullptr ||
mNative->getDispatch().clReleaseDevice == nullptr ||
......@@ -252,7 +261,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(2, 0, 0) &&
if (info.version >= CL_MAKE_VERSION(2, 0, 0) &&
(mNative->getDispatch().clCreateCommandQueueWithProperties == nullptr ||
mNative->getDispatch().clCreatePipe == nullptr ||
mNative->getDispatch().clGetPipeInfo == nullptr ||
......@@ -271,7 +280,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(2, 1, 0) &&
if (info.version >= CL_MAKE_VERSION(2, 1, 0) &&
(mNative->getDispatch().clCloneKernel == nullptr ||
mNative->getDispatch().clCreateProgramWithIL == nullptr ||
mNative->getDispatch().clEnqueueSVMMigrateMem == nullptr ||
......@@ -284,7 +293,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(2, 2, 0) &&
if (info.version >= CL_MAKE_VERSION(2, 2, 0) &&
(mNative->getDispatch().clSetProgramReleaseCallback == nullptr ||
mNative->getDispatch().clSetProgramSpecializationConstant == nullptr))
{
......@@ -292,7 +301,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{};
}
if (info.mVersion >= CL_MAKE_VERSION(3, 0, 0) &&
if (info.version >= CL_MAKE_VERSION(3, 0, 0) &&
(mNative->getDispatch().clCreateBufferWithProperties == nullptr ||
mNative->getDispatch().clCreateImageWithProperties == nullptr ||
mNative->getDispatch().clSetContextDestructorCallback == nullptr))
......
......@@ -14,8 +14,6 @@
#include <unordered_set>
#define ANGLE_SUPPORTED_OPENCL_EXTENSIONS "cl_khr_extended_versioning", "cl_khr_icd"
namespace rx
{
......@@ -27,8 +25,32 @@ using CLExtensionSet = std::unordered_set<std::string>;
// Get a set of OpenCL extensions which are supported to be passed through
inline const CLExtensionSet &GetSupportedCLExtensions()
{
static angle::base::NoDestructor<CLExtensionSet> sExtensions(
{ANGLE_SUPPORTED_OPENCL_EXTENSIONS});
static angle::base::NoDestructor<const CLExtensionSet> sExtensions({
// clang-format off
// These Khronos extension names must be returned by all devices that support OpenCL 1.1.
"cl_khr_byte_addressable_store",
"cl_khr_global_int32_base_atomics",
"cl_khr_global_int32_extended_atomics",
"cl_khr_local_int32_base_atomics",
"cl_khr_local_int32_extended_atomics",
// These Khronos extension names must be returned by all devices that support
// OpenCL 2.0, OpenCL 2.1, or OpenCL 2.2. For devices that support OpenCL 3.0, these
// extension names must be returned when and only when the optional feature is supported.
"cl_khr_3d_image_writes",
"cl_khr_depth_images",
"cl_khr_image2d_from_buffer",
// Optional extensions
"cl_khr_extended_versioning",
"cl_khr_fp64",
"cl_khr_icd",
"cl_khr_int64_base_atomics",
"cl_khr_int64_extended_atomics"
// clang-format on
});
return *sExtensions;
}
......
......@@ -46,13 +46,13 @@ CLPlatformImpl::Info CLPlatformVk::createInfo() const
cl_name_version{CL_MAKE_VERSION(1, 0, 0), "cl_khr_extended_versioning"}};
Info info;
info.mProfile.assign("FULL_PROFILE");
info.mVersionStr.assign(GetVersionString());
info.mVersion = GetVersion();
info.mName.assign("ANGLE Vulkan");
info.mExtensions.assign(CreateExtensionString(extList));
info.mExtensionsWithVersion = std::move(extList);
info.mHostTimerRes = 0u;
info.initializeExtensions(CreateExtensionString(extList));
info.profile.assign("FULL_PROFILE");
info.versionStr.assign(GetVersionString());
info.version = GetVersion();
info.name.assign("ANGLE Vulkan");
info.extensionsWithVersion = std::move(extList);
info.hostTimerRes = 0u;
return info;
}
......
......@@ -473,6 +473,7 @@ libangle_cl_headers = [
"src/libANGLE/renderer/CLContextImpl.h",
"src/libANGLE/renderer/CLDeviceImpl.h",
"src/libANGLE/renderer/CLEventImpl.h",
"src/libANGLE/renderer/CLExtensions.h",
"src/libANGLE/renderer/CLKernelImpl.h",
"src/libANGLE/renderer/CLMemoryImpl.h",
"src/libANGLE/renderer/CLPlatformImpl.h",
......@@ -501,6 +502,7 @@ libangle_cl_sources = [
"src/libANGLE/renderer/CLContextImpl.cpp",
"src/libANGLE/renderer/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLEventImpl.cpp",
"src/libANGLE/renderer/CLExtensions.cpp",
"src/libANGLE/renderer/CLKernelImpl.cpp",
"src/libANGLE/renderer/CLMemoryImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.cpp",
......
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