Commit daf18594 by John Plate

CL: Refactor front end entry functions

Move all front end functions that are only called from the OpenCL entry points to a separate section at the top of the front end object class bodies, which improves readability. Bug: angleproject:6001 Change-Id: Id360adbf0c439e4068c379aa4ea1da25e99f7b53 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2928419Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent 3c1b02b5
......@@ -10,8 +10,6 @@
namespace cl
{
Buffer::~Buffer() = default;
cl_mem Buffer::createSubBuffer(MemFlags flags,
cl_buffer_create_type createType,
const void *createInfo,
......@@ -21,6 +19,8 @@ cl_mem Buffer::createSubBuffer(MemFlags flags,
return Object::Create<Buffer>(errorCode, *this, flags, region.origin, region.size);
}
Buffer::~Buffer() = default;
Buffer::Buffer(Context &context,
PropArray &&properties,
MemFlags flags,
......
......@@ -16,20 +16,24 @@ namespace cl
class Buffer final : public Memory
{
public:
~Buffer() override;
cl_mem_object_type getType() const final;
bool isSubBuffer() const;
bool isRegionValid(const cl_buffer_region &region) const;
// Front end entry functions, only called from OpenCL entry points
cl_mem createSubBuffer(MemFlags flags,
cl_buffer_create_type createType,
const void *createInfo,
cl_int &errorCode);
bool isRegionValid(const cl_buffer_region &region) const;
static bool IsValid(const _cl_mem *buffer);
public:
~Buffer() override;
cl_mem_object_type getType() const final;
bool isSubBuffer() const;
private:
Buffer(Context &context,
PropArray &&properties,
......@@ -43,24 +47,24 @@ class Buffer final : public Memory
friend class Object;
};
inline cl_mem_object_type Buffer::getType() const
inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
{
return CL_MEM_OBJECT_BUFFER;
return region.origin < mSize && region.origin + region.size <= mSize;
}
inline bool Buffer::isSubBuffer() const
inline bool Buffer::IsValid(const _cl_mem *buffer)
{
return mParent != nullptr;
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == CL_MEM_OBJECT_BUFFER;
}
inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
inline cl_mem_object_type Buffer::getType() const
{
return region.origin < mSize && region.origin + region.size <= mSize;
return CL_MEM_OBJECT_BUFFER;
}
inline bool Buffer::IsValid(const _cl_mem *buffer)
inline bool Buffer::isSubBuffer() const
{
return Memory::IsValid(buffer) && buffer->cast<Memory>().getType() == CL_MEM_OBJECT_BUFFER;
return mParent != nullptr;
}
} // namespace cl
......
......@@ -15,14 +15,6 @@
namespace cl
{
CommandQueue::~CommandQueue()
{
if (mDevice->mDefaultCommandQueue == this)
{
mDevice->mDefaultCommandQueue = nullptr;
}
}
cl_int CommandQueue::getInfo(CommandQueueInfo name,
size_t valueSize,
void *value,
......@@ -114,15 +106,13 @@ cl_int CommandQueue::setProperty(CommandQueueProperties properties,
return result;
}
CommandQueue::CommandQueue(Context &context,
Device &device,
CommandQueueProperties properties,
cl_int &errorCode)
: mContext(&context),
mDevice(&device),
mProperties(properties),
mImpl(context.getImpl().createCommandQueue(*this, errorCode))
{}
CommandQueue::~CommandQueue()
{
if (mDevice->mDefaultCommandQueue == this)
{
mDevice->mDefaultCommandQueue = nullptr;
}
}
CommandQueue::CommandQueue(Context &context,
Device &device,
......@@ -143,4 +133,14 @@ CommandQueue::CommandQueue(Context &context,
}
}
CommandQueue::CommandQueue(Context &context,
Device &device,
CommandQueueProperties properties,
cl_int &errorCode)
: mContext(&context),
mDevice(&device),
mProperties(properties),
mImpl(context.getImpl().createCommandQueue(*this, errorCode))
{}
} // namespace cl
......@@ -20,6 +20,18 @@ namespace cl
class CommandQueue final : public _cl_command_queue, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(CommandQueueInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const;
cl_int setProperty(CommandQueueProperties properties,
cl_bool enable,
cl_command_queue_properties *oldProperties);
public:
using PropArray = std::vector<cl_queue_properties>;
static constexpr cl_uint kNoSize = std::numeric_limits<cl_uint>::max();
......@@ -33,26 +45,20 @@ class CommandQueue final : public _cl_command_queue, public Object
bool hasSize() const;
cl_uint getSize() const;
cl_int getInfo(CommandQueueInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const;
cl_int setProperty(CommandQueueProperties properties,
cl_bool enable,
cl_command_queue_properties *oldProperties);
template <typename T = rx::CLCommandQueueImpl>
T &getImpl() const;
private:
CommandQueue(Context &context,
Device &device,
PropArray &&propArray,
CommandQueueProperties properties,
cl_uint size,
cl_int &errorCode);
CommandQueue(Context &context,
Device &device,
PropArray &&propArray,
CommandQueueProperties properties,
cl_uint size,
cl_int &errorCode);
const ContextPtr mContext;
......@@ -90,6 +96,12 @@ inline cl_uint CommandQueue::getSize() const
return mSize;
}
template <typename T>
inline T &CommandQueue::getImpl() const
{
return static_cast<T &>(*mImpl);
}
} // namespace cl
#endif // LIBANGLE_CLCOMMANDQUEUE_H_
......@@ -20,8 +20,6 @@
namespace cl
{
Context::~Context() = default;
cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
std::vector<cl_device_id> devices;
......@@ -79,13 +77,6 @@ cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t
return CL_SUCCESS;
}
cl_command_queue Context::createCommandQueue(cl_device_id device,
CommandQueueProperties properties,
cl_int &errorCode)
{
return Object::Create<CommandQueue>(errorCode, *this, device->cast<Device>(), properties);
}
cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
const cl_queue_properties *properties,
cl_int &errorCode)
......@@ -117,6 +108,13 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
std::move(propArray), props, size);
}
cl_command_queue Context::createCommandQueue(cl_device_id device,
CommandQueueProperties properties,
cl_int &errorCode)
{
return Object::Create<CommandQueue>(errorCode, *this, device->cast<Device>(), properties);
}
cl_mem Context::createBuffer(const cl_mem_properties *properties,
MemFlags flags,
size_t size,
......@@ -171,15 +169,6 @@ cl_mem Context::createImage3D(MemFlags flags,
nullptr, hostPtr);
}
cl_sampler Context::createSampler(cl_bool normalizedCoords,
AddressingMode addressingMode,
FilterMode filterMode,
cl_int &errorCode)
{
return Object::Create<Sampler>(errorCode, *this, Sampler::PropArray{}, normalizedCoords,
addressingMode, filterMode);
}
cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *properties,
cl_int &errorCode)
{
......@@ -216,6 +205,15 @@ cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *pro
addressingMode, filterMode);
}
cl_sampler Context::createSampler(cl_bool normalizedCoords,
AddressingMode addressingMode,
FilterMode filterMode,
cl_int &errorCode)
{
return Object::Create<Sampler>(errorCode, *this, Sampler::PropArray{}, normalizedCoords,
addressingMode, filterMode);
}
cl_program Context::createProgramWithSource(cl_uint count,
const char **strings,
const size_t *lengths,
......@@ -303,6 +301,8 @@ cl_int Context::waitForEvents(cl_uint numEvents, const cl_event *eventList)
return mImpl->waitForEvents(events);
}
Context::~Context() = default;
void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData)
{
Context *const context = static_cast<Context *>(userData);
......
......@@ -19,31 +19,18 @@ namespace cl
class Context final : public _cl_context, public Object
{
public:
using PropArray = std::vector<cl_context_properties>;
~Context() override;
const Platform &getPlatform() const noexcept;
const DevicePtrs &getDevices() const;
bool hasDevice(const _cl_device_id *device) const;
template <typename T = rx::CLContextImpl>
T &getImpl() const;
bool supportsImages() const;
bool supportsIL() const;
bool supportsBuiltInKernel(const std::string &name) const;
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_command_queue createCommandQueue(cl_device_id device,
CommandQueueProperties properties,
cl_int &errorCode);
cl_command_queue createCommandQueueWithProperties(cl_device_id device,
const cl_queue_properties *properties,
cl_int &errorCode);
cl_command_queue createCommandQueue(cl_device_id device,
CommandQueueProperties properties,
cl_int &errorCode);
cl_mem createBuffer(const cl_mem_properties *properties,
MemFlags flags,
size_t size,
......@@ -75,14 +62,14 @@ class Context final : public _cl_context, public Object
void *hostPtr,
cl_int &errorCode);
cl_sampler createSamplerWithProperties(const cl_sampler_properties *properties,
cl_int &errorCode);
cl_sampler createSampler(cl_bool normalizedCoords,
AddressingMode addressingMode,
FilterMode filterMode,
cl_int &errorCode);
cl_sampler createSamplerWithProperties(const cl_sampler_properties *properties,
cl_int &errorCode);
cl_program createProgramWithSource(cl_uint count,
const char **strings,
const size_t *lengths,
......@@ -108,6 +95,22 @@ class Context final : public _cl_context, public Object
static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
public:
using PropArray = std::vector<cl_context_properties>;
~Context() override;
const Platform &getPlatform() const noexcept;
const DevicePtrs &getDevices() const;
bool hasDevice(const _cl_device_id *device) const;
template <typename T = rx::CLContextImpl>
T &getImpl() const;
bool supportsImages() const;
bool supportsIL() const;
bool supportsBuiltInKernel(const std::string &name) const;
static void CL_CALLBACK ErrorCallback(const char *errinfo,
const void *privateInfo,
size_t cb,
......@@ -140,6 +143,14 @@ class Context final : public _cl_context, public Object
friend class Object;
};
inline bool Context::IsValidAndVersionOrNewer(const _cl_context *context,
cl_uint major,
cl_uint minor)
{
return IsValid(context) &&
context->cast<Context>().getPlatform().isVersionOrNewer(major, minor);
}
inline const Platform &Context::getPlatform() const noexcept
{
return mPlatform;
......@@ -184,14 +195,6 @@ inline bool Context::supportsBuiltInKernel(const std::string &name) const
}) != mDevices.cend());
}
inline bool Context::IsValidAndVersionOrNewer(const _cl_context *context,
cl_uint major,
cl_uint minor)
{
return IsValid(context) &&
context->cast<Context>().getPlatform().isVersionOrNewer(major, minor);
}
} // namespace cl
#endif // LIBANGLE_CLCONTEXT_H_
......@@ -14,33 +14,6 @@
namespace cl
{
Device::~Device() = default;
bool Device::supportsBuiltInKernel(const std::string &name) const
{
if (name.empty() || mInfo.mBuiltInKernels.empty())
{
return false;
}
// Compare kernel name with all sub-strings terminated by semi-colon or end of string
std::string::size_type start = 0u;
do
{
std::string::size_type end = mInfo.mBuiltInKernels.find(';', start);
if (end == std::string::npos)
{
end = mInfo.mBuiltInKernels.length();
}
const std::string::size_type length = end - start;
if (length == name.length() && mInfo.mBuiltInKernels.compare(start, length, name) == 0)
{
return true;
}
start = end + 1u;
} while (start < mInfo.mBuiltInKernels.size());
return false;
}
cl_int Device::getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
static_assert(std::is_same<cl_uint, cl_bool>::value &&
......@@ -380,6 +353,33 @@ cl_int Device::createSubDevices(const cl_device_partition_property *properties,
return errorCode;
}
Device::~Device() = default;
bool Device::supportsBuiltInKernel(const std::string &name) const
{
if (name.empty() || mInfo.mBuiltInKernels.empty())
{
return false;
}
// Compare kernel name with all sub-strings terminated by semi-colon or end of string
std::string::size_type start = 0u;
do
{
std::string::size_type end = mInfo.mBuiltInKernels.find(';', start);
if (end == std::string::npos)
{
end = mInfo.mBuiltInKernels.length();
}
const std::string::size_type length = end - start;
if (length == name.length() && mInfo.mBuiltInKernels.compare(start, length, name) == 0)
{
return true;
}
start = end + 1u;
} while (start < mInfo.mBuiltInKernels.size());
return false;
}
Device::Device(Platform &platform,
Device *parent,
DeviceType type,
......
......@@ -20,30 +20,29 @@ namespace cl
class Device final : public _cl_device_id, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices,
cl_device_id *subDevices,
cl_uint *numDevicesRet);
public:
~Device() override;
Platform &getPlatform() noexcept;
const Platform &getPlatform() const noexcept;
bool isRoot() const noexcept;
template <typename T = rx::CLDeviceImpl>
T &getImpl() const;
const rx::CLDeviceImpl::Info &getInfo() const;
cl_version getVersion() const;
bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
bool supportsBuiltInKernel(const std::string &name) const;
cl_int getInfoUInt(DeviceInfo name, cl_uint *value) const;
cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const;
cl_int getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
template <typename T = rx::CLDeviceImpl>
T &getImpl() const;
cl_int createSubDevices(const cl_device_partition_property *properties,
cl_uint numDevices,
cl_device_id *subDevices,
cl_uint *numDevicesRet);
bool supportsBuiltInKernel(const std::string &name) const;
static bool IsValidType(DeviceType type);
......@@ -79,12 +78,6 @@ inline bool Device::isRoot() const noexcept
return mParent == nullptr;
}
template <typename T>
inline T &Device::getImpl() const
{
return static_cast<T &>(*mImpl);
}
inline const rx::CLDeviceImpl::Info &Device::getInfo() const
{
return mInfo;
......@@ -100,14 +93,10 @@ inline bool Device::isVersionOrNewer(cl_uint major, cl_uint minor) const
return mInfo.mVersion >= CL_MAKE_VERSION(major, minor, 0u);
}
inline cl_int Device::getInfoUInt(DeviceInfo name, cl_uint *value) const
{
return mImpl->getInfoUInt(name, value);
}
inline cl_int Device::getInfoULong(DeviceInfo name, cl_ulong *value) const
template <typename T>
inline T &Device::getImpl() const
{
return mImpl->getInfoULong(name, value);
return static_cast<T &>(*mImpl);
}
inline bool Device::IsValidType(DeviceType type)
......
......@@ -15,22 +15,6 @@
namespace cl
{
Event::~Event() = default;
void Event::callback(cl_int commandStatus)
{
ASSERT(commandStatus >= 0 && commandStatus < 3);
for (const CallbackData &data : mCallbacks[commandStatus])
{
data.first(this, commandStatus, data.second);
}
// This event can be released after the callback was called.
if (release())
{
delete this;
}
}
cl_int Event::setUserEventStatus(cl_int executionStatus)
{
const cl_int errorCode = mImpl->setUserEventStatus(executionStatus);
......@@ -122,6 +106,22 @@ cl_int Event::setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, voi
return CL_SUCCESS;
}
Event::~Event() = default;
void Event::callback(cl_int commandStatus)
{
ASSERT(commandStatus >= 0 && commandStatus < 3);
for (const CallbackData &data : mCallbacks[commandStatus])
{
data.first(this, commandStatus, data.second);
}
// This event can be released after the callback was called.
if (release())
{
delete this;
}
}
Event::Event(Context &context, cl_int &errorCode)
: mContext(&context),
mImpl(context.getImpl().createUserEvent(*this, errorCode)),
......
......@@ -20,6 +20,15 @@ namespace cl
class Event final : public _cl_event, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int setUserEventStatus(cl_int executionStatus);
cl_int getInfo(EventInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_int setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData);
public:
~Event() override;
Context &getContext();
......@@ -33,12 +42,6 @@ class Event final : public _cl_event, public Object
void callback(cl_int commandStatus);
cl_int setUserEventStatus(cl_int executionStatus);
cl_int getInfo(EventInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_int setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData);
private:
using CallbackData = std::pair<EventCB, void *>;
......
......@@ -14,8 +14,6 @@
namespace cl
{
Image::~Image() = default;
cl_int Image::getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
size_t valSizeT = 0u;
......@@ -116,6 +114,8 @@ bool Image::IsValid(const _cl_mem *image)
return true;
}
Image::~Image() = default;
Image::Image(Context &context,
PropArray &&properties,
MemFlags flags,
......
......@@ -16,6 +16,13 @@ namespace cl
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 IsValid(const _cl_mem *image);
public:
~Image() override;
cl_mem_object_type getType() const final;
......@@ -23,10 +30,6 @@ class Image final : public Memory
const cl_image_format &getFormat() const;
const ImageDescriptor &getDescriptor() const;
cl_int getInfo(ImageInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
static bool IsValid(const _cl_mem *image);
private:
Image(Context &context,
PropArray &&properties,
......
......@@ -15,8 +15,6 @@
namespace cl
{
Kernel::~Kernel() = default;
cl_int Kernel::getInfo(KernelInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
cl_uint valUInt = 0u;
......@@ -207,6 +205,8 @@ cl_int Kernel::getArgInfo(cl_uint argIndex,
return CL_SUCCESS;
}
Kernel::~Kernel() = default;
Kernel::Kernel(Program &program, const char *name, cl_int &errorCode)
: mProgram(&program),
mImpl(program.getImpl().createKernel(*this, name, errorCode)),
......
......@@ -17,13 +17,7 @@ namespace cl
class Kernel final : public _cl_kernel, public Object
{
public:
~Kernel() override;
const Program &getProgram() const;
const rx::CLKernelImpl::Info &getInfo() const;
template <typename T>
T &getImpl() const;
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(KernelInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
......@@ -39,6 +33,15 @@ class Kernel final : public _cl_kernel, public Object
void *value,
size_t *valueSizeRet) const;
public:
~Kernel() override;
const Program &getProgram() const;
const rx::CLKernelImpl::Info &getInfo() const;
template <typename T = rx::CLKernelImpl>
T &getImpl() const;
private:
Kernel(Program &program, const char *name, cl_int &errorCode);
Kernel(Program &program, const rx::CLKernelImpl::CreateFunc &createFunc, cl_int &errorCode);
......
......@@ -15,8 +15,6 @@
namespace cl
{
Memory::~Memory() = default;
cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
static_assert(
......@@ -103,6 +101,8 @@ cl_int Memory::getInfo(MemInfo name, size_t valueSize, void *value, size_t *valu
return CL_SUCCESS;
}
Memory::~Memory() = default;
Memory::Memory(const Buffer &buffer,
Context &context,
PropArray &&properties,
......
......@@ -18,6 +18,11 @@ namespace cl
class Memory : public _cl_mem, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
public:
using PropArray = std::vector<cl_mem_properties>;
~Memory() override;
......@@ -31,7 +36,8 @@ class Memory : public _cl_mem, public Object
const MemoryPtr &getParent() const;
size_t getOffset() const;
cl_int getInfo(MemInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
template <typename T = rx::CLMemoryImpl>
T &getImpl() const;
protected:
Memory(const Buffer &buffer,
......@@ -104,6 +110,12 @@ inline size_t Memory::getOffset() const
return mOffset;
}
template <typename T>
inline T &Memory::getImpl() const
{
return static_cast<T &>(*mImpl);
}
} // namespace cl
#endif // LIBANGLE_CLMEMORY_H_
......@@ -60,7 +60,59 @@ Context::PropArray ParseContextProperties(const cl_context_properties *propertie
} // namespace
Platform::~Platform() = default;
void Platform::Initialize(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::CreateFuncs &&createFuncs)
{
PlatformPtrs &platforms = GetPointers();
ASSERT(_cl_platform_id::sDispatch == nullptr && platforms.empty());
if (_cl_platform_id::sDispatch != nullptr || !platforms.empty())
{
ERR() << "Already initialized";
return;
}
_cl_platform_id::sDispatch = &dispatch;
_cl_device_id::sDispatch = &dispatch;
_cl_context::sDispatch = &dispatch;
_cl_command_queue::sDispatch = &dispatch;
_cl_mem::sDispatch = &dispatch;
_cl_program::sDispatch = &dispatch;
_cl_kernel::sDispatch = &dispatch;
_cl_event::sDispatch = &dispatch;
_cl_sampler::sDispatch = &dispatch;
platforms.reserve(createFuncs.size());
while (!createFuncs.empty())
{
platforms.emplace_back(new Platform(createFuncs.front()));
if (!platforms.back()->mInfo.isValid() || platforms.back()->mDevices.empty())
{
platforms.pop_back();
}
createFuncs.pop_front();
}
}
cl_int Platform::GetPlatformIDs(cl_uint numEntries,
cl_platform_id *platforms,
cl_uint *numPlatforms)
{
const PlatformPtrs &availPlatforms = GetPlatforms();
if (numPlatforms != nullptr)
{
*numPlatforms = static_cast<cl_uint>(availPlatforms.size());
}
if (platforms != nullptr)
{
cl_uint entry = 0u;
auto platformIt = availPlatforms.cbegin();
while (entry < numEntries && platformIt != availPlatforms.cend())
{
platforms[entry++] = (*platformIt++).get();
}
}
return CL_SUCCESS;
}
cl_int Platform::getInfo(PlatformInfo name,
size_t valueSize,
......@@ -165,51 +217,6 @@ cl_int Platform::getDeviceIDs(DeviceType deviceType,
return CL_SUCCESS;
}
void Platform::Initialize(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::CreateFuncs &&createFuncs)
{
PlatformPtrs &platforms = GetPointers();
ASSERT(Dispatch::sDispatch == nullptr && platforms.empty());
if (Dispatch::sDispatch != nullptr || !platforms.empty())
{
ERR() << "Already initialized";
return;
}
Dispatch::sDispatch = &dispatch;
platforms.reserve(createFuncs.size());
while (!createFuncs.empty())
{
platforms.emplace_back(new Platform(createFuncs.front()));
if (!platforms.back()->mInfo.isValid() || platforms.back()->mDevices.empty())
{
platforms.pop_back();
}
createFuncs.pop_front();
}
}
cl_int Platform::GetPlatformIDs(cl_uint numEntries,
cl_platform_id *platforms,
cl_uint *numPlatforms)
{
const PlatformPtrs &availPlatforms = GetPlatforms();
if (numPlatforms != nullptr)
{
*numPlatforms = static_cast<cl_uint>(availPlatforms.size());
}
if (platforms != nullptr)
{
cl_uint entry = 0u;
auto platformIt = availPlatforms.cbegin();
while (entry < numEntries && platformIt != availPlatforms.cend())
{
platforms[entry++] = (*platformIt++).get();
}
}
return CL_SUCCESS;
}
cl_context Platform::CreateContext(const cl_context_properties *properties,
cl_uint numDevices,
const cl_device_id *devices,
......@@ -245,6 +252,8 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti
userData, userSync);
}
Platform::~Platform() = default;
Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc)
: mImpl(createFunc(*this)),
mInfo(mImpl->createInfo()),
......
......@@ -20,15 +20,18 @@ namespace cl
class Platform final : public _cl_platform_id, public Object
{
public:
~Platform() override;
// Front end entry functions, only called from OpenCL entry points
const rx::CLPlatformImpl::Info &getInfo() const;
cl_version getVersion() const;
bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
const DevicePtrs &getDevices() const;
static void Initialize(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::CreateFuncs &&createFuncs);
template <typename T = rx::CLPlatformImpl>
T &getImpl() const;
static Platform *GetDefault();
static Platform *CastOrDefault(cl_platform_id platform);
static bool IsValidOrDefault(const _cl_platform_id *platform);
static cl_int GetPlatformIDs(cl_uint numEntries,
cl_platform_id *platforms,
cl_uint *numPlatforms);
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
......@@ -37,13 +40,6 @@ class Platform final : public _cl_platform_id, public Object
cl_device_id *devices,
cl_uint *numDevices) const;
static void Initialize(const cl_icd_dispatch &dispatch,
rx::CLPlatformImpl::CreateFuncs &&createFuncs);
static cl_int GetPlatformIDs(cl_uint numEntries,
cl_platform_id *platforms,
cl_uint *numPlatforms);
static cl_context CreateContext(const cl_context_properties *properties,
cl_uint numDevices,
const cl_device_id *devices,
......@@ -57,10 +53,18 @@ class Platform final : public _cl_platform_id, public Object
void *userData,
cl_int &errorCode);
public:
~Platform() override;
const rx::CLPlatformImpl::Info &getInfo() const;
cl_version getVersion() const;
bool isVersionOrNewer(cl_uint major, cl_uint minor) const;
const DevicePtrs &getDevices() const;
template <typename T = rx::CLPlatformImpl>
T &getImpl() const;
static const PlatformPtrs &GetPlatforms();
static Platform *GetDefault();
static Platform *CastOrDefault(cl_platform_id platform);
static bool IsValidOrDefault(const _cl_platform_id *platform);
static constexpr const char *GetVendor();
......@@ -79,6 +83,23 @@ class Platform final : public _cl_platform_id, public Object
static constexpr char kIcdSuffix[] = "ANGLE";
};
inline Platform *Platform::GetDefault()
{
return GetPlatforms().empty() ? nullptr : GetPlatforms().front().get();
}
inline Platform *Platform::CastOrDefault(cl_platform_id platform)
{
return platform != nullptr ? &platform->cast<Platform>() : GetDefault();
}
// Our CL implementation defines that a nullptr value chooses the platform that we provide as
// default, so this function returns true for a nullptr value if a default platform exists.
inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform)
{
return platform != nullptr ? platform->isValid() : GetDefault() != nullptr;
}
inline const rx::CLPlatformImpl::Info &Platform::getInfo() const
{
return mInfo;
......@@ -105,37 +126,20 @@ inline T &Platform::getImpl() const
return static_cast<T &>(*mImpl);
}
inline PlatformPtrs &Platform::GetPointers()
{
static angle::base::NoDestructor<PlatformPtrs> sPointers;
return *sPointers;
}
inline const PlatformPtrs &Platform::GetPlatforms()
{
return GetPointers();
}
inline Platform *Platform::GetDefault()
{
return GetPlatforms().empty() ? nullptr : GetPlatforms().front().get();
}
inline Platform *Platform::CastOrDefault(cl_platform_id platform)
{
return platform != nullptr ? &platform->cast<Platform>() : GetDefault();
}
// Our CL implementation defines that a nullptr value chooses the platform that we provide as
// default, so this function returns true for a nullptr value if a default platform exists.
inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform)
constexpr const char *Platform::GetVendor()
{
return platform != nullptr ? platform->isValid() : GetDefault() != nullptr;
return kVendor;
}
constexpr const char *Platform::GetVendor()
inline PlatformPtrs &Platform::GetPointers()
{
return kVendor;
static angle::base::NoDestructor<PlatformPtrs> sPointers;
return *sPointers;
}
} // namespace cl
......
......@@ -15,8 +15,6 @@
namespace cl
{
Program::~Program() = default;
cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
static_assert(std::is_same<cl_uint, cl_bool>::value &&
......@@ -162,6 +160,8 @@ cl_int Program::createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *n
return errorCode;
}
Program::~Program() = default;
Program::Program(Context &context, std::string &&source, cl_int &errorCode)
: mContext(&context),
mDevices(context.getDevices()),
......
......@@ -17,6 +17,15 @@ namespace cl
class Program final : public _cl_program, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_kernel createKernel(const char *kernel_name, cl_int &errorCode);
cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
public:
~Program() override;
Context &getContext();
......@@ -26,12 +35,6 @@ class Program final : public _cl_program, public Object
template <typename T = rx::CLProgramImpl>
T &getImpl() const;
cl_int getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_kernel createKernel(const char *kernel_name, cl_int &errorCode);
cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
private:
Program(Context &context, std::string &&source, cl_int &errorCode);
Program(Context &context, const void *il, size_t length, cl_int &errorCode);
......
......@@ -14,8 +14,6 @@
namespace cl
{
Sampler::~Sampler() = default;
cl_int Sampler::getInfo(SamplerInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
static_assert(std::is_same<cl_uint, cl_addressing_mode>::value &&
......@@ -81,6 +79,8 @@ cl_int Sampler::getInfo(SamplerInfo name, size_t valueSize, void *value, size_t
return CL_SUCCESS;
}
Sampler::~Sampler() = default;
Sampler::Sampler(Context &context,
PropArray &&properties,
cl_bool normalizedCoords,
......
......@@ -17,6 +17,11 @@ namespace cl
class Sampler final : public _cl_sampler, public Object
{
public:
// Front end entry functions, only called from OpenCL entry points
cl_int getInfo(SamplerInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
public:
using PropArray = std::vector<cl_sampler_properties>;
~Sampler() override;
......@@ -27,7 +32,8 @@ class Sampler final : public _cl_sampler, public Object
AddressingMode getAddressingMode() const;
FilterMode getFilterMode() const;
cl_int getInfo(SamplerInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
template <typename T = rx::CLSamplerImpl>
T &getImpl() const;
private:
Sampler(Context &context,
......@@ -72,6 +78,12 @@ inline FilterMode Sampler::getFilterMode() const
return mFilterMode;
}
template <typename T>
inline T &Sampler::getImpl() const
{
return static_cast<T &>(*mImpl);
}
} // namespace cl
#endif // LIBANGLE_CLSAMPLER_H_
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