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 @@ ...@@ -19,6 +19,7 @@
#include "CL/cl_icd.h" #include "CL/cl_icd.h"
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <type_traits> #include <type_traits>
namespace cl namespace cl
...@@ -37,28 +38,25 @@ using UserFunc = void(CL_CALLBACK *)(void *args); ...@@ -37,28 +38,25 @@ using UserFunc = void(CL_CALLBACK *)(void *args);
template <typename T = void> template <typename T = void>
struct Dispatch struct Dispatch
{ {
Dispatch() : mDispatch(sDispatch) {} explicit Dispatch(std::uint32_t magic) : mDispatch(sDispatch), mMagic(magic) {}
const cl_icd_dispatch &getDispatch() const { return *mDispatch; } 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; static const cl_icd_dispatch *sDispatch;
protected: protected:
// This has to be the first member to be OpenCL ICD compatible // This has to be the first member to be OpenCL ICD compatible
const cl_icd_dispatch *const mDispatch; const cl_icd_dispatch *const mDispatch;
const std::uint32_t mMagic;
}; };
template <typename T> template <typename T>
const cl_icd_dispatch *Dispatch<T>::sDispatch = nullptr; const cl_icd_dispatch *Dispatch<T>::sDispatch = nullptr;
template <typename NativeObjectType> template <typename NativeObjectType, std::uint32_t magic>
struct NativeObject : public Dispatch<> struct NativeObject : public Dispatch<>
{ {
NativeObject() NativeObject() : Dispatch<>(magic)
{ {
static_assert(std::is_standard_layout<NativeObjectType>::value && static_assert(std::is_standard_layout<NativeObjectType>::value &&
offsetof(NativeObjectType, mDispatch) == 0u, offsetof(NativeObjectType, mDispatch) == 0u,
...@@ -85,35 +83,40 @@ struct NativeObject : public Dispatch<> ...@@ -85,35 +83,40 @@ struct NativeObject : public Dispatch<>
} }
static NativeObjectType *CastNative(NativeObjectType *p) { return p; } static NativeObjectType *CastNative(NativeObjectType *p) { return p; }
static bool IsValid(const NativeObjectType *p)
{
return p != nullptr && p->mDispatch == sDispatch && p->mMagic == magic;
}
}; };
} // namespace cl } // 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_ #endif // ANGLECL_H_
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
"scripts/gl_angle_ext.xml": "scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434", "08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py": "scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1", "9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml": "scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db", "c36001431919e1c435f1215a85f7e1db",
"src/libEGL/egl_loader_autogen.cpp": "src/libEGL/egl_loader_autogen.cpp":
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
"scripts/gl_angle_ext.xml": "scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434", "08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py": "scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1", "9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml": "scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db", "c36001431919e1c435f1215a85f7e1db",
"src/common/entry_points_enum_autogen.cpp": "src/common/entry_points_enum_autogen.cpp":
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"scripts/gl_angle_ext.xml": "scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434", "08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py": "scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1", "9945ba71a4a99464c81ab1341baf6697",
"src/libANGLE/capture/gl_enum_utils_autogen.cpp": "src/libANGLE/capture/gl_enum_utils_autogen.cpp":
"132c9a258dbdcbd40ec5ae988e67350f", "132c9a258dbdcbd40ec5ae988e67350f",
"src/libANGLE/capture/gl_enum_utils_autogen.h": "src/libANGLE/capture/gl_enum_utils_autogen.h":
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
"scripts/gl_angle_ext.xml": "scripts/gl_angle_ext.xml":
"08f74b35d908b7c02b45fdf45572c434", "08f74b35d908b7c02b45fdf45572c434",
"scripts/registry_xml.py": "scripts/registry_xml.py":
"c24204dc60032ace3c2f08bee39211b1", "9945ba71a4a99464c81ab1341baf6697",
"scripts/wgl.xml": "scripts/wgl.xml":
"c36001431919e1c435f1215a85f7e1db", "c36001431919e1c435f1215a85f7e1db",
"src/libGL/proc_table_wgl_autogen.cpp": "src/libGL/proc_table_wgl_autogen.cpp":
......
...@@ -196,8 +196,24 @@ supported_egl_extensions = [ ...@@ -196,8 +196,24 @@ supported_egl_extensions = [
] ]
supported_cl_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_extended_versioning",
"cl_khr_fp64",
"cl_khr_icd", "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). # 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) ...@@ -206,6 +206,31 @@ bool EndsWith(const char *str, const char *suffix)
return EndsWithSuffix(str, strlen(str), suffix, strlen(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) void ToLower(std::string *str)
{ {
for (char &ch : *str) for (char &ch : *str)
......
...@@ -82,6 +82,11 @@ bool EndsWith(const std::string &str, const char *suffix); ...@@ -82,6 +82,11 @@ bool EndsWith(const std::string &str, const char *suffix);
// The comparison is case sensitive. // The comparison is case sensitive.
bool EndsWith(const char *str, const char *suffix); 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. // Convert to lower-case.
void ToLower(std::string *str); void ToLower(std::string *str);
......
...@@ -18,6 +18,8 @@ class Buffer final : public Memory ...@@ -18,6 +18,8 @@ class Buffer final : public Memory
public: public:
// Front end entry functions, only called from OpenCL entry points // Front end entry functions, only called from OpenCL entry points
static bool IsValid(const _cl_mem *buffer);
cl_mem createSubBuffer(MemFlags flags, cl_mem createSubBuffer(MemFlags flags,
cl_buffer_create_type createType, cl_buffer_create_type createType,
const void *createInfo, const void *createInfo,
...@@ -26,8 +28,6 @@ class Buffer final : public Memory ...@@ -26,8 +28,6 @@ class Buffer final : public Memory
bool isRegionValid(size_t offset, size_t size) const; bool isRegionValid(size_t offset, size_t size) const;
bool isRegionValid(const cl_buffer_region &region) const; bool isRegionValid(const cl_buffer_region &region) const;
static bool IsValid(const _cl_mem *buffer);
public: public:
~Buffer() override; ~Buffer() override;
...@@ -48,6 +48,11 @@ class Buffer final : public Memory ...@@ -48,6 +48,11 @@ class Buffer final : public Memory
friend class Object; 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 inline bool Buffer::isRegionValid(size_t offset, size_t size) const
{ {
return offset < mSize && offset + size <= mSize; return offset < mSize && offset + size <= mSize;
...@@ -58,11 +63,6 @@ inline bool Buffer::isRegionValid(const cl_buffer_region &region) const ...@@ -58,11 +63,6 @@ inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
return region.origin < mSize && region.origin + region.size <= mSize; 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 inline MemObjectType Buffer::getType() const
{ {
return MemObjectType::Buffer; return MemObjectType::Buffer;
......
...@@ -21,6 +21,8 @@ class Context final : public _cl_context, public Object ...@@ -21,6 +21,8 @@ class Context final : public _cl_context, public Object
public: public:
// Front end entry functions, only called from OpenCL entry points // 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_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_command_queue createCommandQueueWithProperties(cl_device_id device, cl_command_queue createCommandQueueWithProperties(cl_device_id device,
...@@ -108,8 +110,6 @@ class Context final : public _cl_context, public Object ...@@ -108,8 +110,6 @@ class Context final : public _cl_context, public Object
cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList); cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
public: public:
using PropArray = std::vector<cl_context_properties>; using PropArray = std::vector<cl_context_properties>;
...@@ -190,14 +190,14 @@ inline T &Context::getImpl() const ...@@ -190,14 +190,14 @@ inline T &Context::getImpl() const
inline bool Context::supportsImages() const inline bool Context::supportsImages() const
{ {
return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) { 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()); }) != mDevices.cend());
} }
inline bool Context::supportsIL() const inline bool Context::supportsIL() const
{ {
return (std::find_if(mDevices.cbegin(), mDevices.cend(), [](const DevicePtr &ptr) { 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()); }) != mDevices.cend());
} }
......
...@@ -87,12 +87,12 @@ inline const rx::CLDeviceImpl::Info &Device::getInfo() const ...@@ -87,12 +87,12 @@ inline const rx::CLDeviceImpl::Info &Device::getInfo() const
inline cl_version Device::getVersion() const inline cl_version Device::getVersion() const
{ {
return mInfo.mVersion; return mInfo.version;
} }
inline bool Device::isVersionOrNewer(cl_uint major, cl_uint minor) const 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> template <typename T>
......
...@@ -36,7 +36,7 @@ cl_int Event::getInfo(EventInfo name, size_t valueSize, void *value, size_t *val ...@@ -36,7 +36,7 @@ cl_int Event::getInfo(EventInfo name, size_t valueSize, void *value, size_t *val
switch (name) switch (name)
{ {
case EventInfo::CommandQueue: case EventInfo::CommandQueue:
valPointer = mCommandQueue->getNative(); valPointer = CommandQueue::CastNative(mCommandQueue.get());
copyValue = &valPointer; copyValue = &valPointer;
copySize = sizeof(valPointer); copySize = sizeof(valPointer);
break; break;
......
...@@ -14,6 +14,23 @@ ...@@ -14,6 +14,23 @@
namespace cl 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 cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{ {
size_t valSizeT = 0u; size_t valSizeT = 0u;
...@@ -93,23 +110,6 @@ cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *val ...@@ -93,23 +110,6 @@ cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *val
return CL_SUCCESS; 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; Image::~Image() = default;
bool Image::isRegionValid(const size_t origin[3], const size_t region[3]) const bool Image::isRegionValid(const size_t origin[3], const size_t region[3]) const
......
...@@ -20,11 +20,11 @@ class Image final : public Memory ...@@ -20,11 +20,11 @@ class Image final : public Memory
public: public:
// Front end entry functions, only called from OpenCL entry points // 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 IsTypeValid(MemObjectType imageType);
static bool IsValid(const _cl_mem *image); static bool IsValid(const _cl_mem *image);
cl_int getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
public: public:
~Image() override; ~Image() override;
......
...@@ -30,12 +30,12 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v ...@@ -30,12 +30,12 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v
switch (name) switch (name)
{ {
case KernelInfo::FunctionName: case KernelInfo::FunctionName:
copyValue = mInfo.mFunctionName.c_str(); copyValue = mInfo.functionName.c_str();
copySize = mInfo.mFunctionName.length() + 1u; copySize = mInfo.functionName.length() + 1u;
break; break;
case KernelInfo::NumArgs: case KernelInfo::NumArgs:
copyValue = &mInfo.mNumArgs; copyValue = &mInfo.numArgs;
copySize = sizeof(mInfo.mNumArgs); copySize = sizeof(mInfo.numArgs);
break; break;
case KernelInfo::ReferenceCount: case KernelInfo::ReferenceCount:
valUInt = getRefCount(); valUInt = getRefCount();
...@@ -53,8 +53,8 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v ...@@ -53,8 +53,8 @@ cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *v
copySize = sizeof(valPointer); copySize = sizeof(valPointer);
break; break;
case KernelInfo::Attributes: case KernelInfo::Attributes:
copyValue = mInfo.mAttributes.c_str(); copyValue = mInfo.attributes.c_str();
copySize = mInfo.mAttributes.length() + 1u; copySize = mInfo.attributes.length() + 1u;
break; break;
default: default:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
...@@ -99,7 +99,7 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device, ...@@ -99,7 +99,7 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device,
return CL_INVALID_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; const void *copyValue = nullptr;
size_t copySize = 0u; size_t copySize = 0u;
...@@ -107,28 +107,28 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device, ...@@ -107,28 +107,28 @@ cl_int Kernel::getWorkGroupInfo(cl_device_id device,
switch (name) switch (name)
{ {
case KernelWorkGroupInfo::GlobalWorkSize: case KernelWorkGroupInfo::GlobalWorkSize:
copyValue = &info.mGlobalWorkSize; copyValue = &info.globalWorkSize;
copySize = sizeof(info.mGlobalWorkSize); copySize = sizeof(info.globalWorkSize);
break; break;
case KernelWorkGroupInfo::WorkGroupSize: case KernelWorkGroupInfo::WorkGroupSize:
copyValue = &info.mWorkGroupSize; copyValue = &info.workGroupSize;
copySize = sizeof(info.mWorkGroupSize); copySize = sizeof(info.workGroupSize);
break; break;
case KernelWorkGroupInfo::CompileWorkGroupSize: case KernelWorkGroupInfo::CompileWorkGroupSize:
copyValue = &info.mCompileWorkGroupSize; copyValue = &info.compileWorkGroupSize;
copySize = sizeof(info.mCompileWorkGroupSize); copySize = sizeof(info.compileWorkGroupSize);
break; break;
case KernelWorkGroupInfo::LocalMemSize: case KernelWorkGroupInfo::LocalMemSize:
copyValue = &info.mLocalMemSize; copyValue = &info.localMemSize;
copySize = sizeof(info.mLocalMemSize); copySize = sizeof(info.localMemSize);
break; break;
case KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple: case KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple:
copyValue = &info.mPrefWorkGroupSizeMultiple; copyValue = &info.prefWorkGroupSizeMultiple;
copySize = sizeof(info.mPrefWorkGroupSizeMultiple); copySize = sizeof(info.prefWorkGroupSizeMultiple);
break; break;
case KernelWorkGroupInfo::PrivateMemSize: case KernelWorkGroupInfo::PrivateMemSize:
copyValue = &info.mPrivateMemSize; copyValue = &info.privateMemSize;
copySize = sizeof(info.mPrivateMemSize); copySize = sizeof(info.privateMemSize);
break; break;
default: default:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
...@@ -160,31 +160,31 @@ cl_int Kernel::getArgInfo(cl_uint argIndex, ...@@ -160,31 +160,31 @@ cl_int Kernel::getArgInfo(cl_uint argIndex,
void *value, void *value,
size_t *valueSizeRet) const size_t *valueSizeRet) const
{ {
const rx::CLKernelImpl::ArgInfo &info = mInfo.mArgs[argIndex]; const rx::CLKernelImpl::ArgInfo &info = mInfo.args[argIndex];
const void *copyValue = nullptr; const void *copyValue = nullptr;
size_t copySize = 0u; size_t copySize = 0u;
switch (name) switch (name)
{ {
case KernelArgInfo::AddressQualifier: case KernelArgInfo::AddressQualifier:
copyValue = &info.mAddressQualifier; copyValue = &info.addressQualifier;
copySize = sizeof(info.mAddressQualifier); copySize = sizeof(info.addressQualifier);
break; break;
case KernelArgInfo::AccessQualifier: case KernelArgInfo::AccessQualifier:
copyValue = &info.mAccessQualifier; copyValue = &info.accessQualifier;
copySize = sizeof(info.mAccessQualifier); copySize = sizeof(info.accessQualifier);
break; break;
case KernelArgInfo::TypeName: case KernelArgInfo::TypeName:
copyValue = info.mTypeName.c_str(); copyValue = info.typeName.c_str();
copySize = info.mTypeName.length() + 1u; copySize = info.typeName.length() + 1u;
break; break;
case KernelArgInfo::TypeQualifier: case KernelArgInfo::TypeQualifier:
copyValue = &info.mTypeQualifier; copyValue = &info.typeQualifier;
copySize = sizeof(info.mTypeQualifier); copySize = sizeof(info.typeQualifier);
break; break;
case KernelArgInfo::Name: case KernelArgInfo::Name:
copyValue = info.mName.c_str(); copyValue = info.name.c_str();
copySize = info.mName.length() + 1u; copySize = info.name.length() + 1u;
break; break;
default: default:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
......
...@@ -15,6 +15,34 @@ ...@@ -15,6 +15,34 @@
namespace cl 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) cl_int Memory::setDestructorCallback(MemoryCB pfnNotify, void *userData)
{ {
mDestructorCallbacks.emplace(pfnNotify, userData); mDestructorCallbacks.emplace(pfnNotify, userData);
...@@ -118,30 +146,6 @@ Memory::~Memory() ...@@ -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, Memory::Memory(const Buffer &buffer,
Context &context, Context &context,
PropArray &&properties, PropArray &&properties,
...@@ -164,12 +168,12 @@ Memory::Memory(const Buffer &buffer, ...@@ -164,12 +168,12 @@ Memory::Memory(const Buffer &buffer,
size_t size, size_t size,
cl_int &errorCode) cl_int &errorCode)
: mContext(parent.mContext), : mContext(parent.mContext),
mFlags(flags), mFlags(InheritMemFlags(flags, &parent)),
mHostPtr(parent.mHostPtr != nullptr ? static_cast<char *>(parent.mHostPtr) + offset mHostPtr(parent.mHostPtr != nullptr ? static_cast<char *>(parent.mHostPtr) + offset
: nullptr), : nullptr),
mParent(&parent), mParent(&parent),
mOffset(offset), mOffset(offset),
mImpl(parent.mImpl->createSubBuffer(buffer, size, errorCode)), mImpl(parent.mImpl->createSubBuffer(buffer, flags, size, errorCode)),
mSize(size) mSize(size)
{} {}
...@@ -184,10 +188,10 @@ Memory::Memory(const Image &image, ...@@ -184,10 +188,10 @@ Memory::Memory(const Image &image,
cl_int &errorCode) cl_int &errorCode)
: mContext(&context), : mContext(&context),
mProperties(std::move(properties)), mProperties(std::move(properties)),
mFlags(flags), mFlags(InheritMemFlags(flags, parent)),
mHostPtr(flags.isSet(CL_MEM_USE_HOST_PTR) ? hostPtr : nullptr), mHostPtr(flags.isSet(CL_MEM_USE_HOST_PTR) ? hostPtr : nullptr),
mParent(parent), 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) mSize(mImpl ? mImpl->getSize(errorCode) : 0u)
{} {}
......
...@@ -44,8 +44,6 @@ class Memory : public _cl_mem, public Object ...@@ -44,8 +44,6 @@ class Memory : public _cl_mem, public Object
template <typename T = rx::CLMemoryImpl> template <typename T = rx::CLMemoryImpl>
T &getImpl() const; T &getImpl() const;
MemFlags getEffectiveFlags() const;
static Memory *Cast(cl_mem memobj); static Memory *Cast(cl_mem memobj);
protected: protected:
......
...@@ -116,37 +116,37 @@ cl_int Platform::getInfo(PlatformInfo name, ...@@ -116,37 +116,37 @@ cl_int Platform::getInfo(PlatformInfo name,
switch (name) switch (name)
{ {
case PlatformInfo::Profile: case PlatformInfo::Profile:
copyValue = mInfo.mProfile.c_str(); copyValue = mInfo.profile.c_str();
copySize = mInfo.mProfile.length() + 1u; copySize = mInfo.profile.length() + 1u;
break; break;
case PlatformInfo::Version: case PlatformInfo::Version:
copyValue = mInfo.mVersionStr.c_str(); copyValue = mInfo.versionStr.c_str();
copySize = mInfo.mVersionStr.length() + 1u; copySize = mInfo.versionStr.length() + 1u;
break; break;
case PlatformInfo::NumericVersion: case PlatformInfo::NumericVersion:
copyValue = &mInfo.mVersion; copyValue = &mInfo.version;
copySize = sizeof(mInfo.mVersion); copySize = sizeof(mInfo.version);
break; break;
case PlatformInfo::Name: case PlatformInfo::Name:
copyValue = mInfo.mName.c_str(); copyValue = mInfo.name.c_str();
copySize = mInfo.mName.length() + 1u; copySize = mInfo.name.length() + 1u;
break; break;
case PlatformInfo::Vendor: case PlatformInfo::Vendor:
copyValue = kVendor; copyValue = kVendor;
copySize = sizeof(kVendor); copySize = sizeof(kVendor);
break; break;
case PlatformInfo::Extensions: case PlatformInfo::Extensions:
copyValue = mInfo.mExtensions.c_str(); copyValue = mInfo.extensions.c_str();
copySize = mInfo.mExtensions.length() + 1u; copySize = mInfo.extensions.length() + 1u;
break; break;
case PlatformInfo::ExtensionsWithVersion: case PlatformInfo::ExtensionsWithVersion:
copyValue = mInfo.mExtensionsWithVersion.data(); copyValue = mInfo.extensionsWithVersion.data();
copySize = mInfo.mExtensionsWithVersion.size() * copySize = mInfo.extensionsWithVersion.size() *
sizeof(decltype(mInfo.mExtensionsWithVersion)::value_type); sizeof(decltype(mInfo.extensionsWithVersion)::value_type);
break; break;
case PlatformInfo::HostTimerResolution: case PlatformInfo::HostTimerResolution:
copyValue = &mInfo.mHostTimerRes; copyValue = &mInfo.hostTimerRes;
copySize = sizeof(mInfo.mHostTimerRes); copySize = sizeof(mInfo.hostTimerRes);
break; break;
case PlatformInfo::IcdSuffix: case PlatformInfo::IcdSuffix:
copyValue = kIcdSuffix; copyValue = kIcdSuffix;
...@@ -185,7 +185,7 @@ cl_int Platform::getDeviceIDs(DeviceType deviceType, ...@@ -185,7 +185,7 @@ cl_int Platform::getDeviceIDs(DeviceType deviceType,
cl_uint found = 0u; cl_uint found = 0u;
for (const DevicePtr &device : mDevices) for (const DevicePtr &device : mDevices)
{ {
if (IsDeviceTypeMatch(deviceType, device->getInfo().mType)) if (IsDeviceTypeMatch(deviceType, device->getInfo().type))
{ {
if (devices != nullptr && found < numEntries) if (devices != nullptr && found < numEntries)
{ {
......
...@@ -99,7 +99,7 @@ inline Platform *Platform::CastOrDefault(cl_platform_id platform) ...@@ -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. // default, so this function returns true for a nullptr value if a default platform exists.
inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform) 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 inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
...@@ -109,12 +109,12 @@ 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 inline cl_version Platform::getVersion() const
{ {
return mInfo.mVersion; return mInfo.version;
} }
inline bool Platform::isVersionOrNewer(cl_uint major, cl_uint minor) const 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 inline const DevicePtrs &Platform::getDevices() const
......
...@@ -36,6 +36,7 @@ class CLContextImpl : angle::NonCopyable ...@@ -36,6 +36,7 @@ class CLContextImpl : angle::NonCopyable
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
virtual CLMemoryImpl::Ptr createImage(const cl::Image &image, virtual CLMemoryImpl::Ptr createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format, const cl_image_format &format,
const cl::ImageDescriptor &desc, const cl::ImageDescriptor &desc,
void *hostPtr, void *hostPtr,
......
...@@ -14,7 +14,7 @@ namespace rx ...@@ -14,7 +14,7 @@ namespace rx
CLDeviceImpl::Info::Info() = default; CLDeviceImpl::Info::Info() = default;
CLDeviceImpl::Info::Info(cl::DeviceType type) : mType(type) {} CLDeviceImpl::Info::Info(cl::DeviceType deviceType) : type(deviceType) {}
CLDeviceImpl::Info::~Info() = default; CLDeviceImpl::Info::~Info() = default;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#ifndef LIBANGLE_RENDERER_CLDEVICEIMPL_H_ #ifndef LIBANGLE_RENDERER_CLDEVICEIMPL_H_
#define LIBANGLE_RENDERER_CLDEVICEIMPL_H_ #define LIBANGLE_RENDERER_CLDEVICEIMPL_H_
#include "libANGLE/renderer/CLtypes.h" #include "libANGLE/renderer/CLExtensions.h"
namespace rx namespace rx
{ {
...@@ -22,10 +22,10 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -22,10 +22,10 @@ class CLDeviceImpl : angle::NonCopyable
using CreateData = std::pair<cl::DeviceType, CreateFunc>; using CreateData = std::pair<cl::DeviceType, CreateFunc>;
using CreateDatas = std::list<CreateData>; using CreateDatas = std::list<CreateData>;
struct Info struct Info : public CLExtensions
{ {
Info(); Info();
explicit Info(cl::DeviceType type); explicit Info(cl::DeviceType deviceType);
~Info(); ~Info();
Info(const Info &) = delete; Info(const Info &) = delete;
...@@ -34,37 +34,36 @@ class CLDeviceImpl : angle::NonCopyable ...@@ -34,37 +34,36 @@ class CLDeviceImpl : angle::NonCopyable
Info(Info &&); Info(Info &&);
Info &operator=(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 // In the order as they appear in the OpenCL specification V3.0.7, table 5
cl::DeviceType mType; cl::DeviceType type;
std::vector<size_t> mMaxWorkItemSizes; std::vector<size_t> maxWorkItemSizes;
cl_ulong mMaxMemAllocSize = 0u; cl_ulong maxMemAllocSize = 0u;
cl_bool mImageSupport = CL_FALSE; cl_bool imageSupport = CL_FALSE;
std::string mIL_Version; std::string IL_Version;
NameVersionVector mILsWithVersion; NameVersionVector ILsWithVersion;
size_t mImage2D_MaxWidth = 0u; size_t image2D_MaxWidth = 0u;
size_t mImage2D_MaxHeight = 0u; size_t image2D_MaxHeight = 0u;
size_t mImage3D_MaxWidth = 0u; size_t image3D_MaxWidth = 0u;
size_t mImage3D_MaxHeight = 0u; size_t image3D_MaxHeight = 0u;
size_t mImage3D_MaxDepth = 0u; size_t image3D_MaxDepth = 0u;
size_t mImageMaxBufferSize = 0u; size_t imageMaxBufferSize = 0u;
size_t mImageMaxArraySize = 0u; size_t imageMaxArraySize = 0u;
cl_uint mImagePitchAlignment = 0u; cl_uint imagePitchAlignment = 0u;
cl_uint mImageBaseAddressAlignment = 0u; cl_uint imageBaseAddressAlignment = 0u;
cl_uint mMemBaseAddrAlign = 0u; cl_uint memBaseAddrAlign = 0u;
cl::DeviceExecCapabilities mExecCapabilities; cl::DeviceExecCapabilities execCapabilities;
cl_uint mQueueOnDeviceMaxSize = 0u; cl_uint queueOnDeviceMaxSize = 0u;
std::string mBuiltInKernels; std::string builtInKernels;
NameVersionVector mBuiltInKernelsWithVersion; NameVersionVector builtInKernelsWithVersion;
std::string mVersionStr; std::string versionStr;
cl_version mVersion = 0u; cl_version version = 0u;
NameVersionVector mOpenCL_C_AllVersions; NameVersionVector OpenCL_C_AllVersions;
NameVersionVector mOpenCL_C_Features; NameVersionVector OpenCL_C_Features;
std::string mExtensions; NameVersionVector extensionsWithVersion;
NameVersionVector mExtensionsWithVersion; std::vector<cl_device_partition_property> partitionProperties;
std::vector<cl_device_partition_property> mPartitionProperties; std::vector<cl_device_partition_property> partitionType;
std::vector<cl_device_partition_property> mPartitionType;
}; };
CLDeviceImpl(const cl::Device &device); 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 ...@@ -31,12 +31,12 @@ class CLKernelImpl : angle::NonCopyable
WorkGroupInfo(WorkGroupInfo &&); WorkGroupInfo(WorkGroupInfo &&);
WorkGroupInfo &operator=(WorkGroupInfo &&); WorkGroupInfo &operator=(WorkGroupInfo &&);
std::array<size_t, 3u> mGlobalWorkSize = {}; std::array<size_t, 3u> globalWorkSize = {};
size_t mWorkGroupSize = 0u; size_t workGroupSize = 0u;
std::array<size_t, 3u> mCompileWorkGroupSize = {}; std::array<size_t, 3u> compileWorkGroupSize = {};
cl_ulong mLocalMemSize = 0u; cl_ulong localMemSize = 0u;
size_t mPrefWorkGroupSizeMultiple = 0u; size_t prefWorkGroupSizeMultiple = 0u;
cl_ulong mPrivateMemSize = 0u; cl_ulong privateMemSize = 0u;
}; };
struct ArgInfo struct ArgInfo
...@@ -50,13 +50,13 @@ class CLKernelImpl : angle::NonCopyable ...@@ -50,13 +50,13 @@ class CLKernelImpl : angle::NonCopyable
ArgInfo(ArgInfo &&); ArgInfo(ArgInfo &&);
ArgInfo &operator=(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_address_qualifier addressQualifier = 0u;
cl_kernel_arg_access_qualifier mAccessQualifier = 0u; cl_kernel_arg_access_qualifier accessQualifier = 0u;
std::string mTypeName; std::string typeName;
cl_kernel_arg_type_qualifier mTypeQualifier = 0u; cl_kernel_arg_type_qualifier typeQualifier = 0u;
std::string mName; std::string name;
}; };
struct Info struct Info
...@@ -70,14 +70,14 @@ class CLKernelImpl : angle::NonCopyable ...@@ -70,14 +70,14 @@ class CLKernelImpl : angle::NonCopyable
Info(Info &&); Info(Info &&);
Info &operator=(Info &&); Info &operator=(Info &&);
bool isValid() const { return !mFunctionName.empty(); } bool isValid() const { return !functionName.empty(); }
std::string mFunctionName; std::string functionName;
cl_uint mNumArgs = 0u; cl_uint numArgs = 0u;
std::string mAttributes; std::string attributes;
std::vector<WorkGroupInfo> mWorkGroups; std::vector<WorkGroupInfo> workGroups;
std::vector<ArgInfo> mArgs; std::vector<ArgInfo> args;
}; };
CLKernelImpl(const cl::Kernel &kernel); CLKernelImpl(const cl::Kernel &kernel);
......
...@@ -24,6 +24,7 @@ class CLMemoryImpl : angle::NonCopyable ...@@ -24,6 +24,7 @@ class CLMemoryImpl : angle::NonCopyable
virtual size_t getSize(cl_int &errorCode) const = 0; virtual size_t getSize(cl_int &errorCode) const = 0;
virtual CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer, virtual CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size, size_t size,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLContextImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include "libANGLE/renderer/CLExtensions.h"
namespace rx namespace rx
{ {
...@@ -21,7 +22,7 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -21,7 +22,7 @@ class CLPlatformImpl : angle::NonCopyable
using CreateFunc = std::function<Ptr(const cl::Platform &)>; using CreateFunc = std::function<Ptr(const cl::Platform &)>;
using CreateFuncs = std::list<CreateFunc>; using CreateFuncs = std::list<CreateFunc>;
struct Info struct Info : public CLExtensions
{ {
Info(); Info();
~Info(); ~Info();
...@@ -32,15 +33,14 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -32,15 +33,14 @@ class CLPlatformImpl : angle::NonCopyable
Info(Info &&); Info(Info &&);
Info &operator=(Info &&); Info &operator=(Info &&);
bool isValid() const { return mVersion != 0u; } bool isValid() const { return version != 0u; }
std::string mProfile; std::string profile;
std::string mVersionStr; std::string versionStr;
cl_version mVersion = 0u; cl_version version = 0u;
std::string mName; std::string name;
std::string mExtensions; NameVersionVector extensionsWithVersion;
NameVersionVector mExtensionsWithVersion; cl_ulong hostTimerRes = 0u;
cl_ulong mHostTimerRes = 0u;
}; };
explicit CLPlatformImpl(const cl::Platform &platform); explicit CLPlatformImpl(const cl::Platform &platform);
......
...@@ -126,6 +126,7 @@ CLMemoryImpl::Ptr CLContextCL::createBuffer(const cl::Buffer &buffer, ...@@ -126,6 +126,7 @@ CLMemoryImpl::Ptr CLContextCL::createBuffer(const cl::Buffer &buffer,
} }
CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image, CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format, const cl_image_format &format,
const cl::ImageDescriptor &desc, const cl::ImageDescriptor &desc,
void *hostPtr, void *hostPtr,
...@@ -144,14 +145,14 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image, ...@@ -144,14 +145,14 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
if (image.getProperties().empty()) if (image.getProperties().empty())
{ {
nativeImage = mNative->getDispatch().clCreateImage( nativeImage = mNative->getDispatch().clCreateImage(mNative, flags.get(), &format,
mNative, image.getFlags().get(), &format, &nativeDesc, hostPtr, &errorCode); &nativeDesc, hostPtr, &errorCode);
} }
else else
{ {
nativeImage = mNative->getDispatch().clCreateImageWithProperties( nativeImage = mNative->getDispatch().clCreateImageWithProperties(
mNative, image.getProperties().data(), image.getFlags().get(), &format, &nativeDesc, mNative, image.getProperties().data(), flags.get(), &format, &nativeDesc, hostPtr,
hostPtr, &errorCode); &errorCode);
} }
} }
else else
...@@ -160,12 +161,12 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image, ...@@ -160,12 +161,12 @@ CLMemoryImpl::Ptr CLContextCL::createImage(const cl::Image &image,
{ {
case cl::MemObjectType::Image2D: case cl::MemObjectType::Image2D:
nativeImage = mNative->getDispatch().clCreateImage2D( nativeImage = mNative->getDispatch().clCreateImage2D(
mNative, image.getFlags().get(), &format, desc.width, desc.height, mNative, flags.get(), &format, desc.width, desc.height, desc.rowPitch, hostPtr,
desc.rowPitch, hostPtr, &errorCode); &errorCode);
break; break;
case cl::MemObjectType::Image3D: case cl::MemObjectType::Image3D:
nativeImage = mNative->getDispatch().clCreateImage3D( 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); desc.rowPitch, desc.slicePitch, hostPtr, &errorCode);
break; break;
default: default:
......
...@@ -38,6 +38,7 @@ class CLContextCL : public CLContextImpl ...@@ -38,6 +38,7 @@ class CLContextCL : public CLContextImpl
cl_int &errorCode) override; cl_int &errorCode) override;
CLMemoryImpl::Ptr createImage(const cl::Image &image, CLMemoryImpl::Ptr createImage(const cl::Image &image,
cl::MemFlags flags,
const cl_image_format &format, const cl_image_format &format,
const cl::ImageDescriptor &desc, const cl::ImageDescriptor &desc,
void *hostPtr, void *hostPtr,
......
...@@ -68,7 +68,7 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const ...@@ -68,7 +68,7 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
Info info(type); Info info(type);
std::vector<char> valString; std::vector<char> valString;
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.mMaxWorkItemSizes)) if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxWorkItemSizes, info.maxWorkItemSizes))
{ {
return Info{}; return Info{};
} }
...@@ -76,22 +76,22 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const ...@@ -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." // "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 // 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. // Custom devices are currently not supported by this back end.
if (info.mMaxWorkItemSizes.size() < 3u || info.mMaxWorkItemSizes[0] == 0u || if (info.maxWorkItemSizes.size() < 3u || info.maxWorkItemSizes[0] == 0u ||
info.mMaxWorkItemSizes[1] == 0u || info.mMaxWorkItemSizes[2] == 0u) info.maxWorkItemSizes[1] == 0u || info.maxWorkItemSizes[2] == 0u)
{ {
ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES"; ERR() << "Invalid CL_DEVICE_MAX_WORK_ITEM_SIZES";
return Info{}; return Info{};
} }
if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.mMaxMemAllocSize) || if (!GetDeviceInfo(mNative, cl::DeviceInfo::MaxMemAllocSize, info.maxMemAllocSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageSupport, info.mImageSupport) || !GetDeviceInfo(mNative, cl::DeviceInfo::ImageSupport, info.imageSupport) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxWidth, info.mImage2D_MaxWidth) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxWidth, info.image2D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.mImage2D_MaxHeight) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image2D_MaxHeight, info.image2D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.mImage3D_MaxWidth) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxWidth, info.image3D_MaxWidth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.mImage3D_MaxHeight) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxHeight, info.image3D_MaxHeight) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.mImage3D_MaxDepth) || !GetDeviceInfo(mNative, cl::DeviceInfo::Image3D_MaxDepth, info.image3D_MaxDepth) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.mMemBaseAddrAlign) || !GetDeviceInfo(mNative, cl::DeviceInfo::MemBaseAddrAlign, info.memBaseAddrAlign) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExecutionCapabilities, info.mExecCapabilities)) !GetDeviceInfo(mNative, cl::DeviceInfo::ExecutionCapabilities, info.execCapabilities))
{ {
return Info{}; return Info{};
} }
...@@ -100,76 +100,83 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const ...@@ -100,76 +100,83 @@ CLDeviceImpl::Info CLDeviceCL::createInfo(cl::DeviceType type) const
{ {
return Info{}; return Info{};
} }
info.mVersionStr.assign(valString.data()); info.versionStr.assign(valString.data());
// Limit version number to supported version if (!GetDeviceInfo(mNative, cl::DeviceInfo::Extensions, valString))
if (info.mVersionStr[7] != '1')
{ {
info.mVersionStr[7] = '1'; return Info{};
info.mVersionStr[9] = '2';
} }
std::string extensionStr(valString.data());
info.mVersion = ExtractCLVersion(info.mVersionStr); // TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/6053
if (info.mVersion == 0u) 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{}; 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) || if (!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxBufferSize, info.imageMaxBufferSize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxArraySize, info.mImageMaxArraySize) || !GetDeviceInfo(mNative, cl::DeviceInfo::ImageMaxArraySize, info.imageMaxArraySize) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernels, valString)) !GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernels, valString))
{ {
return Info{}; return Info{};
} }
info.mBuiltInKernels.assign(valString.data()); info.builtInKernels.assign(valString.data());
if (!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties, if (!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionProperties,
info.mPartitionProperties) || info.partitionProperties) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.mPartitionType)) !GetDeviceInfo(mNative, cl::DeviceInfo::PartitionType, info.partitionType))
{ {
return Info{}; return Info{};
} }
} }
if (info.mVersion >= CL_MAKE_VERSION(2, 0, 0) && if (info.version >= CL_MAKE_VERSION(2, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ImagePitchAlignment, info.mImagePitchAlignment) || (!GetDeviceInfo(mNative, cl::DeviceInfo::ImagePitchAlignment, info.imagePitchAlignment) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ImageBaseAddressAlignment, !GetDeviceInfo(mNative, cl::DeviceInfo::ImageBaseAddressAlignment,
info.mImageBaseAddressAlignment) || info.imageBaseAddressAlignment) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::QueueOnDeviceMaxSize, info.mQueueOnDeviceMaxSize))) !GetDeviceInfo(mNative, cl::DeviceInfo::QueueOnDeviceMaxSize, info.queueOnDeviceMaxSize)))
{ {
return Info{}; 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)) if (!GetDeviceInfo(mNative, cl::DeviceInfo::IL_Version, valString))
{ {
return Info{}; return Info{};
} }
info.mIL_Version.assign(valString.data()); info.IL_Version.assign(valString.data());
} }
if (info.mVersion >= CL_MAKE_VERSION(3, 0, 0) && if (info.version >= CL_MAKE_VERSION(3, 0, 0) &&
(!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.mILsWithVersion) || (!GetDeviceInfo(mNative, cl::DeviceInfo::ILsWithVersion, info.ILsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernelsWithVersion, !GetDeviceInfo(mNative, cl::DeviceInfo::BuiltInKernelsWithVersion,
info.mBuiltInKernelsWithVersion) || info.builtInKernelsWithVersion) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions, !GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_AllVersions, info.OpenCL_C_AllVersions) ||
info.mOpenCL_C_AllVersions) || !GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.OpenCL_C_Features) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::OpenCL_C_Features, info.mOpenCL_C_Features) ||
!GetDeviceInfo(mNative, cl::DeviceInfo::ExtensionsWithVersion, !GetDeviceInfo(mNative, cl::DeviceInfo::ExtensionsWithVersion,
info.mExtensionsWithVersion))) info.extensionsWithVersion)))
{ {
return Info{}; return Info{};
} }
RemoveUnsupportedCLExtensions(info.mExtensionsWithVersion); RemoveUnsupportedCLExtensions(info.extensionsWithVersion);
return info; return info;
} }
......
...@@ -172,55 +172,55 @@ CLKernelImpl::Info CLKernelCL::createInfo(cl_int &errorCode) const ...@@ -172,55 +172,55 @@ CLKernelImpl::Info CLKernelCL::createInfo(cl_int &errorCode) const
const cl::Context &ctx = mKernel.getProgram().getContext(); const cl::Context &ctx = mKernel.getProgram().getContext();
Info info; Info info;
if (!GetKernelString(mNative, cl::KernelInfo::FunctionName, info.mFunctionName, errorCode) || if (!GetKernelString(mNative, cl::KernelInfo::FunctionName, info.functionName, errorCode) ||
!GetKernelInfo(mNative, cl::KernelInfo::NumArgs, info.mNumArgs, errorCode) || !GetKernelInfo(mNative, cl::KernelInfo::NumArgs, info.numArgs, errorCode) ||
(ctx.getPlatform().isVersionOrNewer(1u, 2u) && (ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
!GetKernelString(mNative, cl::KernelInfo::Attributes, info.mAttributes, errorCode))) !GetKernelString(mNative, cl::KernelInfo::Attributes, info.attributes, errorCode)))
{ {
return Info{}; return Info{};
} }
info.mWorkGroups.resize(ctx.getDevices().size()); info.workGroups.resize(ctx.getDevices().size());
for (size_t index = 0u; index < ctx.getDevices().size(); ++index) for (size_t index = 0u; index < ctx.getDevices().size(); ++index)
{ {
const cl_device_id device = ctx.getDevices()[index]->getImpl<CLDeviceCL>().getNative(); 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) && if ((ctx.getPlatform().isVersionOrNewer(1u, 2u) &&
ctx.getDevices()[index]->supportsBuiltInKernel(info.mFunctionName) && ctx.getDevices()[index]->supportsBuiltInKernel(info.functionName) &&
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::GlobalWorkSize, !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::GlobalWorkSize,
workGroup.mGlobalWorkSize, errorCode)) || workGroup.globalWorkSize, errorCode)) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::WorkGroupSize, !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::WorkGroupSize,
workGroup.mWorkGroupSize, errorCode) || workGroup.workGroupSize, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::CompileWorkGroupSize, !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::CompileWorkGroupSize,
workGroup.mCompileWorkGroupSize, errorCode) || workGroup.compileWorkGroupSize, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::LocalMemSize, !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::LocalMemSize,
workGroup.mLocalMemSize, errorCode) || workGroup.localMemSize, errorCode) ||
!GetWorkGroupInfo(mNative, device, !GetWorkGroupInfo(mNative, device,
cl::KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple, cl::KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple,
workGroup.mPrefWorkGroupSizeMultiple, errorCode) || workGroup.prefWorkGroupSizeMultiple, errorCode) ||
!GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::PrivateMemSize, !GetWorkGroupInfo(mNative, device, cl::KernelWorkGroupInfo::PrivateMemSize,
workGroup.mPrivateMemSize, errorCode)) workGroup.privateMemSize, errorCode))
{ {
return Info{}; return Info{};
} }
} }
info.mArgs.resize(info.mNumArgs); info.args.resize(info.numArgs);
if (ctx.getPlatform().isVersionOrNewer(1u, 2u)) 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, if (!GetArgInfo(mNative, index, cl::KernelArgInfo::AddressQualifier,
arg.mAddressQualifier, errorCode) || arg.addressQualifier, errorCode) ||
!GetArgInfo(mNative, index, cl::KernelArgInfo::AccessQualifier, !GetArgInfo(mNative, index, cl::KernelArgInfo::AccessQualifier, arg.accessQualifier,
arg.mAccessQualifier, errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::TypeName, arg.mTypeName,
errorCode) || errorCode) ||
!GetArgInfo(mNative, index, cl::KernelArgInfo::TypeQualifier, arg.mTypeQualifier, !GetArgString(mNative, index, cl::KernelArgInfo::TypeName, arg.typeName,
errorCode) || errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::Name, arg.mName, errorCode)) !GetArgInfo(mNative, index, cl::KernelArgInfo::TypeQualifier, arg.typeQualifier,
errorCode) ||
!GetArgString(mNative, index, cl::KernelArgInfo::Name, arg.name, errorCode))
{ {
return Info{}; return Info{};
} }
......
...@@ -46,12 +46,13 @@ size_t CLMemoryCL::getSize(cl_int &errorCode) const ...@@ -46,12 +46,13 @@ size_t CLMemoryCL::getSize(cl_int &errorCode) const
} }
CLMemoryImpl::Ptr CLMemoryCL::createSubBuffer(const cl::Buffer &buffer, CLMemoryImpl::Ptr CLMemoryCL::createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size, size_t size,
cl_int &errorCode) cl_int &errorCode)
{ {
const cl_buffer_region region = {buffer.getOffset(), size}; const cl_buffer_region region = {buffer.getOffset(), size};
const cl_mem nativeBuffer = mNative->getDispatch().clCreateSubBuffer( 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) return CLMemoryImpl::Ptr(nativeBuffer != nullptr ? new CLMemoryCL(buffer, nativeBuffer)
: nullptr); : nullptr);
} }
......
...@@ -24,6 +24,7 @@ class CLMemoryCL : public CLMemoryImpl ...@@ -24,6 +24,7 @@ class CLMemoryCL : public CLMemoryImpl
size_t getSize(cl_int &errorCode) const override; size_t getSize(cl_int &errorCode) const override;
CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer, CLMemoryImpl::Ptr createSubBuffer(const cl::Buffer &buffer,
cl::MemFlags flags,
size_t size, size_t size,
cl_int &errorCode) override; cl_int &errorCode) override;
......
...@@ -124,20 +124,13 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -124,20 +124,13 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
// Fetch common platform info // Fetch common platform info
Info info; Info info;
const std::string vendor = GetPlatformString(mNative, cl::PlatformInfo::Vendor); const std::string vendor = GetPlatformString(mNative, cl::PlatformInfo::Vendor);
info.mProfile = GetPlatformString(mNative, cl::PlatformInfo::Profile); info.profile = GetPlatformString(mNative, cl::PlatformInfo::Profile);
info.mVersionStr = GetPlatformString(mNative, cl::PlatformInfo::Version); info.versionStr = GetPlatformString(mNative, cl::PlatformInfo::Version);
info.mName = GetPlatformString(mNative, cl::PlatformInfo::Name); info.name = GetPlatformString(mNative, cl::PlatformInfo::Name);
info.mExtensions = GetPlatformString(mNative, cl::PlatformInfo::Extensions); std::string extensionStr = GetPlatformString(mNative, cl::PlatformInfo::Extensions);
// Limit version number to supported version if (vendor.empty() || info.profile.empty() || info.versionStr.empty() || info.name.empty() ||
if (info.mVersionStr[7] != '1') extensionStr.empty())
{
info.mVersionStr[7] = '1';
info.mVersionStr[9] = '2';
}
if (vendor.empty() || info.mProfile.empty() || info.mVersionStr.empty() || info.mName.empty() ||
info.mExtensions.empty())
{ {
return Info{}; return Info{};
} }
...@@ -149,27 +142,43 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -149,27 +142,43 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; return Info{};
} }
// Skip platform if it is not ICD compatible // TODO(jplate) Remove workaround after bug is fixed http://anglebug.com/6053
if (info.mExtensions.find("cl_khr_icd") == std::string::npos) if (info.versionStr.compare(0u, 15u, "OpenCL 3.0 CUDA", 15u) == 0)
{ {
WARN() << "CL platform is not ICD compatible"; extensionStr.append(" cl_khr_depth_images cl_khr_image2d_from_buffer");
return Info{}; }
// 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) if (version == 0u)
{ {
return Info{}; return Info{};
} }
// Customize version string and name, and remove unsupported extensions // Remove unsupported and initialize extensions
info.mVersionStr += " (ANGLE " ANGLE_VERSION_STRING ")"; RemoveUnsupportedCLExtensions(extensionStr);
info.mName.insert(0u, "ANGLE pass-through -> "); info.initializeExtensions(std::move(extensionStr));
RemoveUnsupportedCLExtensions(info.mExtensions);
// 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) && if (version >= CL_MAKE_VERSION(2, 1, 0) &&
mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_HOST_TIMER_RESOLUTION, mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_HOST_TIMER_RESOLUTION,
sizeof(info.mHostTimerRes), &info.mHostTimerRes, sizeof(info.hostTimerRes), &info.hostTimerRes,
nullptr) != CL_SUCCESS) nullptr) != CL_SUCCESS)
{ {
ERR() << "Failed to query CL platform info for CL_PLATFORM_HOST_TIMER_RESOLUTION"; ERR() << "Failed to query CL platform info for CL_PLATFORM_HOST_TIMER_RESOLUTION";
...@@ -178,46 +187,46 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -178,46 +187,46 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
if (version < CL_MAKE_VERSION(3, 0, 0)) if (version < CL_MAKE_VERSION(3, 0, 0))
{ {
info.mVersion = version; info.version = version;
} }
else else
{ {
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_NUMERIC_VERSION, if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_NUMERIC_VERSION,
sizeof(info.mVersion), &info.mVersion, sizeof(info.version), &info.version,
nullptr) != CL_SUCCESS) nullptr) != CL_SUCCESS)
{ {
ERR() << "Failed to query CL platform info for CL_PLATFORM_NUMERIC_VERSION"; ERR() << "Failed to query CL platform info for CL_PLATFORM_NUMERIC_VERSION";
return Info{}; return Info{};
} }
else if (CL_VERSION_MAJOR(info.mVersion) != CL_VERSION_MAJOR(version) || else if (CL_VERSION_MAJOR(info.version) != CL_VERSION_MAJOR(version) ||
CL_VERSION_MINOR(info.mVersion) != CL_VERSION_MINOR(version)) CL_VERSION_MINOR(info.version) != CL_VERSION_MINOR(version))
{ {
WARN() << "CL_PLATFORM_NUMERIC_VERSION = " << CL_VERSION_MAJOR(info.mVersion) << '.' WARN() << "CL_PLATFORM_NUMERIC_VERSION = " << CL_VERSION_MAJOR(info.version) << '.'
<< CL_VERSION_MINOR(info.mVersion) << CL_VERSION_MINOR(info.version)
<< " does not match version string: " << info.mVersionStr; << " does not match version string: " << info.versionStr;
} }
size_t valueSize = 0u; size_t valueSize = 0u;
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION, if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
0u, nullptr, &valueSize) != CL_SUCCESS || 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"; ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
return Info{}; return Info{};
} }
info.mExtensionsWithVersion.resize( info.extensionsWithVersion.resize(valueSize /
valueSize / sizeof(decltype(info.mExtensionsWithVersion)::value_type)); sizeof(decltype(info.extensionsWithVersion)::value_type));
if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION, if (mNative->getDispatch().clGetPlatformInfo(mNative, CL_PLATFORM_EXTENSIONS_WITH_VERSION,
valueSize, info.mExtensionsWithVersion.data(), valueSize, info.extensionsWithVersion.data(),
nullptr) != CL_SUCCESS) nullptr) != CL_SUCCESS)
{ {
ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION"; ERR() << "Failed to query CL platform info for CL_PLATFORM_EXTENSIONS_WITH_VERSION";
return Info{}; 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().clSetEventCallback == nullptr ||
mNative->getDispatch().clCreateSubBuffer == nullptr || mNative->getDispatch().clCreateSubBuffer == nullptr ||
mNative->getDispatch().clSetMemObjectDestructorCallback == nullptr || mNative->getDispatch().clSetMemObjectDestructorCallback == nullptr ||
...@@ -231,7 +240,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -231,7 +240,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; 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().clCreateSubDevices == nullptr ||
mNative->getDispatch().clRetainDevice == nullptr || mNative->getDispatch().clRetainDevice == nullptr ||
mNative->getDispatch().clReleaseDevice == nullptr || mNative->getDispatch().clReleaseDevice == nullptr ||
...@@ -252,7 +261,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -252,7 +261,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; 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().clCreateCommandQueueWithProperties == nullptr ||
mNative->getDispatch().clCreatePipe == nullptr || mNative->getDispatch().clCreatePipe == nullptr ||
mNative->getDispatch().clGetPipeInfo == nullptr || mNative->getDispatch().clGetPipeInfo == nullptr ||
...@@ -271,7 +280,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -271,7 +280,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; 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().clCloneKernel == nullptr ||
mNative->getDispatch().clCreateProgramWithIL == nullptr || mNative->getDispatch().clCreateProgramWithIL == nullptr ||
mNative->getDispatch().clEnqueueSVMMigrateMem == nullptr || mNative->getDispatch().clEnqueueSVMMigrateMem == nullptr ||
...@@ -284,7 +293,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -284,7 +293,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; 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().clSetProgramReleaseCallback == nullptr ||
mNative->getDispatch().clSetProgramSpecializationConstant == nullptr)) mNative->getDispatch().clSetProgramSpecializationConstant == nullptr))
{ {
...@@ -292,7 +301,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const ...@@ -292,7 +301,7 @@ CLPlatformImpl::Info CLPlatformCL::createInfo() const
return Info{}; 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().clCreateBufferWithProperties == nullptr ||
mNative->getDispatch().clCreateImageWithProperties == nullptr || mNative->getDispatch().clCreateImageWithProperties == nullptr ||
mNative->getDispatch().clSetContextDestructorCallback == nullptr)) mNative->getDispatch().clSetContextDestructorCallback == nullptr))
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
#include <unordered_set> #include <unordered_set>
#define ANGLE_SUPPORTED_OPENCL_EXTENSIONS "cl_khr_extended_versioning", "cl_khr_icd"
namespace rx namespace rx
{ {
...@@ -27,8 +25,32 @@ using CLExtensionSet = std::unordered_set<std::string>; ...@@ -27,8 +25,32 @@ using CLExtensionSet = std::unordered_set<std::string>;
// Get a set of OpenCL extensions which are supported to be passed through // Get a set of OpenCL extensions which are supported to be passed through
inline const CLExtensionSet &GetSupportedCLExtensions() inline const CLExtensionSet &GetSupportedCLExtensions()
{ {
static angle::base::NoDestructor<CLExtensionSet> sExtensions( static angle::base::NoDestructor<const CLExtensionSet> sExtensions({
{ANGLE_SUPPORTED_OPENCL_EXTENSIONS}); // 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; return *sExtensions;
} }
......
...@@ -46,13 +46,13 @@ CLPlatformImpl::Info CLPlatformVk::createInfo() const ...@@ -46,13 +46,13 @@ CLPlatformImpl::Info CLPlatformVk::createInfo() const
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"}};
Info info; Info info;
info.mProfile.assign("FULL_PROFILE"); info.initializeExtensions(CreateExtensionString(extList));
info.mVersionStr.assign(GetVersionString()); info.profile.assign("FULL_PROFILE");
info.mVersion = GetVersion(); info.versionStr.assign(GetVersionString());
info.mName.assign("ANGLE Vulkan"); info.version = GetVersion();
info.mExtensions.assign(CreateExtensionString(extList)); info.name.assign("ANGLE Vulkan");
info.mExtensionsWithVersion = std::move(extList); info.extensionsWithVersion = std::move(extList);
info.mHostTimerRes = 0u; info.hostTimerRes = 0u;
return info; return info;
} }
......
...@@ -473,6 +473,7 @@ libangle_cl_headers = [ ...@@ -473,6 +473,7 @@ libangle_cl_headers = [
"src/libANGLE/renderer/CLContextImpl.h", "src/libANGLE/renderer/CLContextImpl.h",
"src/libANGLE/renderer/CLDeviceImpl.h", "src/libANGLE/renderer/CLDeviceImpl.h",
"src/libANGLE/renderer/CLEventImpl.h", "src/libANGLE/renderer/CLEventImpl.h",
"src/libANGLE/renderer/CLExtensions.h",
"src/libANGLE/renderer/CLKernelImpl.h", "src/libANGLE/renderer/CLKernelImpl.h",
"src/libANGLE/renderer/CLMemoryImpl.h", "src/libANGLE/renderer/CLMemoryImpl.h",
"src/libANGLE/renderer/CLPlatformImpl.h", "src/libANGLE/renderer/CLPlatformImpl.h",
...@@ -501,6 +502,7 @@ libangle_cl_sources = [ ...@@ -501,6 +502,7 @@ libangle_cl_sources = [
"src/libANGLE/renderer/CLContextImpl.cpp", "src/libANGLE/renderer/CLContextImpl.cpp",
"src/libANGLE/renderer/CLDeviceImpl.cpp", "src/libANGLE/renderer/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLEventImpl.cpp", "src/libANGLE/renderer/CLEventImpl.cpp",
"src/libANGLE/renderer/CLExtensions.cpp",
"src/libANGLE/renderer/CLKernelImpl.cpp", "src/libANGLE/renderer/CLKernelImpl.cpp",
"src/libANGLE/renderer/CLMemoryImpl.cpp", "src/libANGLE/renderer/CLMemoryImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.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