Commit 6622d2b4 by John Plate Committed by Angle LUCI CQ

CL: command queues for front end and pass-through

Bug: angleproject:5956 Change-Id: I6d9d4e4e7dfc5402408e3b002e66e4eae752967d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2903091Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: John Plate <jplate@google.com>
parent 937b29ab
...@@ -7,9 +7,157 @@ ...@@ -7,9 +7,157 @@
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLPlatform.h"
#include <cstring>
namespace cl namespace cl
{ {
CommandQueue::CommandQueue(const cl_icd_dispatch &dispatch) : _cl_command_queue(dispatch) {} CommandQueue::~CommandQueue()
{
if (mDevice->mDefaultCommandQueue == this)
{
mDevice->mDefaultCommandQueue = nullptr;
}
}
bool CommandQueue::release()
{
const bool released = removeRef();
if (released)
{
mContext->destroyCommandQueue(this);
}
return released;
}
cl_int CommandQueue::getInfo(CommandQueueInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet)
{
void *valPointer = nullptr;
const void *copyValue = nullptr;
size_t copySize = 0u;
switch (name)
{
case CommandQueueInfo::Context:
valPointer = static_cast<cl_context>(mContext.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case CommandQueueInfo::Device:
valPointer = static_cast<cl_device_id>(mDevice.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case CommandQueueInfo::ReferenceCount:
copyValue = getRefCountPtr();
copySize = sizeof(*getRefCountPtr());
break;
case CommandQueueInfo::Properties:
copyValue = &mProperties;
copySize = sizeof(mProperties);
break;
case CommandQueueInfo::PropertiesArray:
copyValue = mPropArray.data();
copySize = mPropArray.size() * sizeof(decltype(mPropArray)::value_type);
break;
case CommandQueueInfo::Size:
copyValue = &mSize;
copySize = sizeof(mSize);
break;
case CommandQueueInfo::DeviceDefault:
valPointer = static_cast<cl_command_queue>(mDevice->mDefaultCommandQueue);
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
default:
return CL_INVALID_VALUE;
}
if (value != nullptr)
{
if (valueSize < copySize)
{
return CL_INVALID_VALUE;
}
if (copyValue != nullptr)
{
std::memcpy(value, copyValue, copySize);
}
}
if (valueSizeRet != nullptr)
{
*valueSizeRet = copySize;
}
return CL_SUCCESS;
}
cl_int CommandQueue::setProperty(cl_command_queue_properties properties,
cl_bool enable,
cl_command_queue_properties *oldProperties)
{
if (oldProperties != nullptr)
{
*oldProperties = mProperties;
}
const cl_int result = mImpl->setProperty(properties, enable);
if (result == CL_SUCCESS)
{
if (enable == CL_FALSE)
{
mProperties &= ~properties;
}
else
{
mProperties |= properties;
}
}
return result;
}
bool CommandQueue::IsValid(const _cl_command_queue *commandQueue)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->hasCommandQueue(commandQueue);
}) != platforms.cend();
}
CommandQueue::CommandQueue(ContextRefPtr &&context,
DeviceRefPtr &&device,
cl_command_queue_properties properties,
cl_int *errcodeRet)
: _cl_command_queue(context->getDispatch()),
mContext(std::move(context)),
mDevice(std::move(device)),
mProperties(properties),
mImpl(mContext->mImpl->createCommandQueue(*this, errcodeRet))
{}
CommandQueue::CommandQueue(ContextRefPtr &&context,
DeviceRefPtr &&device,
PropArray &&propArray,
cl_command_queue_properties properties,
cl_uint size,
cl_int *errcodeRet)
: _cl_command_queue(context->getDispatch()),
mContext(std::move(context)),
mDevice(std::move(device)),
mPropArray(std::move(propArray)),
mProperties(properties),
mSize(size),
mImpl(mContext->mImpl->createCommandQueue(*this, errcodeRet))
{
if ((mProperties & CL_QUEUE_ON_DEVICE_DEFAULT) != 0u)
{
mDevice->mDefaultCommandQueue = this;
}
}
} // namespace cl } // namespace cl
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#define LIBANGLE_CLCOMMANDQUEUE_H_ #define LIBANGLE_CLCOMMANDQUEUE_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLObject.h"
#include "libANGLE/renderer/CLCommandQueueImpl.h"
#include <limits>
namespace cl namespace cl
{ {
...@@ -17,10 +20,83 @@ namespace cl ...@@ -17,10 +20,83 @@ namespace cl
class CommandQueue final : public _cl_command_queue, public Object class CommandQueue final : public _cl_command_queue, public Object
{ {
public: public:
CommandQueue(const cl_icd_dispatch &dispatch); using PtrList = std::list<CommandQueuePtr>;
~CommandQueue() = default; using PropArray = std::vector<cl_queue_properties>;
static constexpr cl_uint kNoSize = std::numeric_limits<cl_uint>::max();
~CommandQueue();
const Context &getContext() const;
const Device &getDevice() const;
cl_command_queue_properties getProperties() const;
bool hasSize() const;
cl_uint getSize() const;
void retain() noexcept;
bool release();
cl_int getInfo(CommandQueueInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
cl_int setProperty(cl_command_queue_properties properties,
cl_bool enable,
cl_command_queue_properties *oldProperties);
static bool IsValid(const _cl_command_queue *commandQueue);
private:
CommandQueue(ContextRefPtr &&context,
DeviceRefPtr &&device,
cl_command_queue_properties properties,
cl_int *errcodeRet);
CommandQueue(ContextRefPtr &&context,
DeviceRefPtr &&device,
PropArray &&propArray,
cl_command_queue_properties properties,
cl_uint size,
cl_int *errcodeRet);
const ContextRefPtr mContext;
const DeviceRefPtr mDevice;
const PropArray mPropArray;
cl_command_queue_properties mProperties;
const cl_uint mSize = kNoSize;
const rx::CLCommandQueueImpl::Ptr mImpl;
friend class Context;
}; };
inline const Context &CommandQueue::getContext() const
{
return *mContext;
}
inline const Device &CommandQueue::getDevice() const
{
return *mDevice;
}
inline cl_command_queue_properties CommandQueue::getProperties() const
{
return mProperties;
}
inline bool CommandQueue::hasSize() const
{
return mSize != kNoSize;
}
inline cl_uint CommandQueue::getSize() const
{
return mSize;
}
inline void CommandQueue::retain() noexcept
{
addRef();
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLCOMMANDQUEUE_H_ #endif // LIBANGLE_CLCOMMANDQUEUE_H_
...@@ -75,6 +75,59 @@ cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t ...@@ -75,6 +75,59 @@ cl_int Context::getInfo(ContextInfo name, size_t valueSize, void *value, size_t
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_command_queue Context::createCommandQueue(cl_device_id device,
cl_command_queue_properties properties,
cl_int *errcodeRet)
{
mCommandQueues.emplace_back(new CommandQueue(
ContextRefPtr(this), DeviceRefPtr(static_cast<Device *>(device)), properties, errcodeRet));
if (!mCommandQueues.back()->mImpl)
{
mCommandQueues.back()->release();
return nullptr;
}
return mCommandQueues.back().get();
}
cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
const cl_queue_properties *properties,
cl_int *errcodeRet)
{
CommandQueue::PropArray propArray;
cl_command_queue_properties props = 0u;
cl_uint size = CommandQueue::kNoSize;
if (properties != nullptr)
{
const cl_queue_properties *propIt = properties;
while (*propIt != 0)
{
switch (*propIt++)
{
case CL_QUEUE_PROPERTIES:
props = *propIt++;
break;
case CL_QUEUE_SIZE:
size = static_cast<decltype(size)>(*propIt++);
break;
}
}
// Include the trailing zero
++propIt;
propArray.reserve(propIt - properties);
propArray.insert(propArray.cend(), properties, propIt);
}
mCommandQueues.emplace_back(new CommandQueue(ContextRefPtr(this),
DeviceRefPtr(static_cast<Device *>(device)),
std::move(propArray), props, size, errcodeRet));
if (!mCommandQueues.back()->mImpl)
{
mCommandQueues.back()->release();
return nullptr;
}
return mCommandQueues.back().get();
}
bool Context::IsValid(const _cl_context *context) bool Context::IsValid(const _cl_context *context)
{ {
const Platform::PtrList &platforms = Platform::GetPlatforms(); const Platform::PtrList &platforms = Platform::GetPlatforms();
...@@ -121,6 +174,23 @@ Context::Context(Platform &platform, ...@@ -121,6 +174,23 @@ Context::Context(Platform &platform,
mUserData(userData) mUserData(userData)
{} {}
void Context::destroyCommandQueue(CommandQueue *commandQueue)
{
auto commandQueueIt = mCommandQueues.cbegin();
while (commandQueueIt != mCommandQueues.cend() && commandQueueIt->get() != commandQueue)
{
++commandQueueIt;
}
if (commandQueueIt != mCommandQueues.cend())
{
mCommandQueues.erase(commandQueueIt);
}
else
{
ERR() << "CommandQueue not found";
}
}
void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData) void Context::ErrorCallback(const char *errinfo, const void *privateInfo, size_t cb, void *userData)
{ {
Context *const context = static_cast<Context *>(userData); Context *const context = static_cast<Context *>(userData);
......
...@@ -9,12 +9,10 @@ ...@@ -9,12 +9,10 @@
#ifndef LIBANGLE_CLCONTEXT_H_ #ifndef LIBANGLE_CLCONTEXT_H_
#define LIBANGLE_CLCONTEXT_H_ #define LIBANGLE_CLCONTEXT_H_
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLRefPointer.h"
#include "libANGLE/renderer/CLContextImpl.h" #include "libANGLE/renderer/CLContextImpl.h"
#include <list>
namespace cl namespace cl
{ {
...@@ -22,18 +20,27 @@ class Context final : public _cl_context, public Object ...@@ -22,18 +20,27 @@ class Context final : public _cl_context, public Object
{ {
public: public:
using PtrList = std::list<ContextPtr>; using PtrList = std::list<ContextPtr>;
using RefPtr = RefPointer<Context>;
using PropArray = std::vector<cl_context_properties>; using PropArray = std::vector<cl_context_properties>;
~Context(); ~Context();
Platform &getPlatform() const noexcept; const Platform &getPlatform() const noexcept;
bool hasDevice(const _cl_device_id *device) const;
bool hasCommandQueue(const _cl_command_queue *commandQueue) const;
void retain() noexcept; void retain() noexcept;
bool release(); bool release();
cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet); cl_int getInfo(ContextInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
cl_command_queue createCommandQueue(cl_device_id device,
cl_command_queue_properties properties,
cl_int *errcodeRet);
cl_command_queue createCommandQueueWithProperties(cl_device_id device,
const cl_queue_properties *properties,
cl_int *errcodeRet);
static bool IsValid(const _cl_context *context); static bool IsValid(const _cl_context *context);
private: private:
...@@ -53,6 +60,8 @@ class Context final : public _cl_context, public Object ...@@ -53,6 +60,8 @@ class Context final : public _cl_context, public Object
bool userSync, bool userSync,
cl_int *errcodeRet); cl_int *errcodeRet);
void destroyCommandQueue(CommandQueue *commandQueue);
static void CL_CALLBACK ErrorCallback(const char *errinfo, static void CL_CALLBACK ErrorCallback(const char *errinfo,
const void *privateInfo, const void *privateInfo,
size_t cb, size_t cb,
...@@ -65,14 +74,31 @@ class Context final : public _cl_context, public Object ...@@ -65,14 +74,31 @@ class Context final : public _cl_context, public Object
const ContextErrorCB mNotify; const ContextErrorCB mNotify;
void *const mUserData; void *const mUserData;
CommandQueue::PtrList mCommandQueues;
friend class CommandQueue;
friend class Platform; friend class Platform;
}; };
inline Platform &Context::getPlatform() const noexcept inline const Platform &Context::getPlatform() const noexcept
{ {
return mPlatform; return mPlatform;
} }
inline bool Context::hasDevice(const _cl_device_id *device) const
{
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const DeviceRefPtr &ptr) {
return ptr.get() == device;
}) != mDevices.cend();
}
inline bool Context::hasCommandQueue(const _cl_command_queue *commandQueue) const
{
return std::find_if(mCommandQueues.cbegin(), mCommandQueues.cend(),
[=](const CommandQueuePtr &ptr) { return ptr.get() == commandQueue; }) !=
mCommandQueues.cend();
}
inline void Context::retain() noexcept inline void Context::retain() noexcept
{ {
addRef(); addRef();
......
...@@ -24,16 +24,22 @@ class Device final : public _cl_device_id, public Object ...@@ -24,16 +24,22 @@ class Device final : public _cl_device_id, public Object
~Device(); ~Device();
Platform &getPlatform() const noexcept; Platform &getPlatform() noexcept;
const Platform &getPlatform() const noexcept;
bool isRoot() const noexcept; bool isRoot() const noexcept;
rx::CLDeviceImpl &getImpl() const;
template <typename T>
T &getImpl() const;
const rx::CLDeviceImpl::Info &getInfo() const; const rx::CLDeviceImpl::Info &getInfo() const;
bool hasSubDevice(const _cl_device_id *device) const; bool hasSubDevice(const _cl_device_id *device) const;
void retain() noexcept; void retain() noexcept;
bool release(); bool release();
cl_int getInfoUInt(DeviceInfo name, cl_uint *value) const;
cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const; cl_int getInfoULong(DeviceInfo name, cl_ulong *value) const;
cl_int getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet); cl_int getInfo(DeviceInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
cl_int createSubDevices(const cl_device_partition_property *properties, cl_int createSubDevices(const cl_device_partition_property *properties,
...@@ -59,11 +65,18 @@ class Device final : public _cl_device_id, public Object ...@@ -59,11 +65,18 @@ class Device final : public _cl_device_id, public Object
const rx::CLDeviceImpl::Info mInfo; const rx::CLDeviceImpl::Info mInfo;
DevicePtrList mSubDevices; DevicePtrList mSubDevices;
CommandQueue *mDefaultCommandQueue = nullptr;
friend class CommandQueue;
friend class Platform; friend class Platform;
}; };
inline Platform &Device::getPlatform() const noexcept inline Platform &Device::getPlatform() noexcept
{
return mPlatform;
}
inline const Platform &Device::getPlatform() const noexcept
{ {
return mPlatform; return mPlatform;
} }
...@@ -73,9 +86,10 @@ inline bool Device::isRoot() const noexcept ...@@ -73,9 +86,10 @@ inline bool Device::isRoot() const noexcept
return !mParent; return !mParent;
} }
inline rx::CLDeviceImpl &Device::getImpl() const template <typename T>
inline T &Device::getImpl() const
{ {
return *mImpl; return static_cast<T>(*mImpl);
} }
inline const rx::CLDeviceImpl::Info &Device::getInfo() const inline const rx::CLDeviceImpl::Info &Device::getInfo() const
...@@ -98,6 +112,11 @@ inline void Device::retain() noexcept ...@@ -98,6 +112,11 @@ inline void Device::retain() noexcept
} }
} }
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 inline cl_int Device::getInfoULong(DeviceInfo name, cl_ulong *value) const
{ {
return mImpl->getInfoULong(name, value); return mImpl->getInfoULong(name, value);
......
...@@ -32,26 +32,23 @@ Context::PropArray ParseContextProperties(const cl_context_properties *propertie ...@@ -32,26 +32,23 @@ Context::PropArray ParseContextProperties(const cl_context_properties *propertie
Context::PropArray propArray; Context::PropArray propArray;
if (properties != nullptr) if (properties != nullptr)
{ {
// Count the trailing zero
size_t propSize = 1u;
const cl_context_properties *propIt = properties; const cl_context_properties *propIt = properties;
while (*propIt != 0) while (*propIt != 0)
{ {
++propSize;
switch (*propIt++) switch (*propIt++)
{ {
case CL_CONTEXT_PLATFORM: case CL_CONTEXT_PLATFORM:
platform = reinterpret_cast<Platform *>(*propIt++); platform = reinterpret_cast<Platform *>(*propIt++);
++propSize;
break; break;
case CL_CONTEXT_INTEROP_USER_SYNC: case CL_CONTEXT_INTEROP_USER_SYNC:
userSync = *propIt++ != CL_FALSE; userSync = *propIt++ != CL_FALSE;
++propSize;
break; break;
} }
} }
propArray.reserve(propSize); // Include the trailing zero
propArray.insert(propArray.cend(), properties, properties + propSize); ++propIt;
propArray.reserve(propIt - properties);
propArray.insert(propArray.cend(), properties, propIt);
} }
if (platform == nullptr) if (platform == nullptr)
{ {
......
...@@ -32,6 +32,7 @@ class Platform final : public _cl_platform_id, public Object ...@@ -32,6 +32,7 @@ class Platform final : public _cl_platform_id, public Object
bool hasDevice(const _cl_device_id *device) const; bool hasDevice(const _cl_device_id *device) const;
const DevicePtrList &getDevices() const; const DevicePtrList &getDevices() const;
bool hasContext(const _cl_context *context) const; bool hasContext(const _cl_context *context) const;
bool hasCommandQueue(const _cl_command_queue *commandQueue) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet); cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet);
...@@ -111,6 +112,13 @@ inline bool Platform::hasContext(const _cl_context *context) const ...@@ -111,6 +112,13 @@ inline bool Platform::hasContext(const _cl_context *context) const
}) != mContexts.cend(); }) != mContexts.cend();
} }
inline bool Platform::hasCommandQueue(const _cl_command_queue *commandQueue) const
{
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const ContextPtr &ptr) {
return ptr->hasCommandQueue(commandQueue);
}) != mContexts.cend();
}
inline Platform::PtrList &Platform::GetList() inline Platform::PtrList &Platform::GetList()
{ {
static angle::base::NoDestructor<PtrList> sList; static angle::base::NoDestructor<PtrList> sList;
......
...@@ -45,8 +45,10 @@ using PlatformPtr = std::unique_ptr<Platform>; ...@@ -45,8 +45,10 @@ using PlatformPtr = std::unique_ptr<Platform>;
using ProgramPtr = std::unique_ptr<Program>; using ProgramPtr = std::unique_ptr<Program>;
using SamplerPtr = std::unique_ptr<Sampler>; using SamplerPtr = std::unique_ptr<Sampler>;
using DevicePtrList = std::list<DevicePtr>; using ContextRefPtr = RefPointer<Context>;
using DeviceRefPtr = RefPointer<Device>; using DeviceRefPtr = RefPointer<Device>;
using DevicePtrList = std::list<DevicePtr>;
using DeviceRefList = std::vector<DeviceRefPtr>; using DeviceRefList = std::vector<DeviceRefPtr>;
} // namespace cl } // namespace cl
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLCommandQueueImpl.cpp: Implements the class methods for CLCommandQueueImpl.
#include "libANGLE/renderer/CLCommandQueueImpl.h"
namespace rx
{
CLCommandQueueImpl::CLCommandQueueImpl(const cl::CommandQueue &commandQueue)
: mCommandQueue(commandQueue)
{}
CLCommandQueueImpl::~CLCommandQueueImpl() = default;
} // 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.
//
// CLCommandQueueImpl.h: Defines the abstract rx::CLCommandQueueImpl class.
#ifndef LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#define LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
class CLCommandQueueImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLCommandQueueImpl>;
CLCommandQueueImpl(const cl::CommandQueue &commandQueue);
virtual ~CLCommandQueueImpl();
virtual cl_int setProperty(cl_command_queue_properties properties, cl_bool enable) = 0;
protected:
const cl::CommandQueue &mCommandQueue;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CLCOMMANDQUEUEIMPL_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifndef LIBANGLE_RENDERER_CLCONTEXTIMPL_H_ #ifndef LIBANGLE_RENDERER_CLCONTEXTIMPL_H_
#define LIBANGLE_RENDERER_CLCONTEXTIMPL_H_ #define LIBANGLE_RENDERER_CLCONTEXTIMPL_H_
#include "libANGLE/renderer/CLCommandQueueImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
namespace rx namespace rx
...@@ -23,6 +24,9 @@ class CLContextImpl : angle::NonCopyable ...@@ -23,6 +24,9 @@ class CLContextImpl : angle::NonCopyable
virtual cl::DeviceRefList getDevices() const = 0; virtual cl::DeviceRefList getDevices() const = 0;
virtual CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue,
cl_int *errcodeRet) = 0;
protected: protected:
const cl::Context &mContext; const cl::Context &mContext;
}; };
......
...@@ -9,6 +9,8 @@ import("../../../../gni/angle.gni") ...@@ -9,6 +9,8 @@ import("../../../../gni/angle.gni")
assert(angle_enable_cl_passthrough) assert(angle_enable_cl_passthrough)
_cl_backend_sources = [ _cl_backend_sources = [
"CLCommandQueueCL.cpp",
"CLCommandQueueCL.h",
"CLContextCL.cpp", "CLContextCL.cpp",
"CLContextCL.h", "CLContextCL.h",
"CLDeviceCL.cpp", "CLDeviceCL.cpp",
......
//
// 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.
//
// CLCommandQueueCL.cpp: Implements the class methods for CLCommandQueueCL.
#include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/Debug.h"
namespace rx
{
CLCommandQueueCL::CLCommandQueueCL(const cl::CommandQueue &commandQueue, cl_command_queue native)
: CLCommandQueueImpl(commandQueue), mNative(native)
{}
CLCommandQueueCL::~CLCommandQueueCL()
{
if (mNative->getDispatch().clReleaseCommandQueue(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL command-queue";
}
}
cl_int CLCommandQueueCL::setProperty(cl_command_queue_properties properties, cl_bool enable)
{
return mNative->getDispatch().clSetCommandQueueProperty(mNative, properties, enable, nullptr);
}
} // 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.
//
// CLCommandQueueCL.h: Defines the class interface for CLCommandQueueCL,
// implementing CLCommandQueueImpl.
#ifndef LIBANGLE_RENDERER_CL_CLCOMMANDQUEUECL_H_
#define LIBANGLE_RENDERER_CL_CLCOMMANDQUEUECL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLContextImpl.h"
namespace rx
{
class CLCommandQueueCL : public CLCommandQueueImpl
{
public:
CLCommandQueueCL(const cl::CommandQueue &commandQueue, cl_command_queue native);
~CLCommandQueueCL() override;
cl_int setProperty(cl_command_queue_properties properties, cl_bool enable) override;
private:
const cl_command_queue mNative;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLCOMMANDQUEUECL_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "libANGLE/renderer/cl/CLContextCL.h" #include "libANGLE/renderer/cl/CLContextCL.h"
#include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h" #include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
...@@ -47,7 +48,7 @@ cl::DeviceRefList CLContextCL::getDevices() const ...@@ -47,7 +48,7 @@ cl::DeviceRefList CLContextCL::getDevices() const
{ {
auto it = platformDevices.cbegin(); auto it = platformDevices.cbegin();
while (it != platformDevices.cend() && while (it != platformDevices.cend() &&
static_cast<CLDeviceCL &>((*it)->getImpl()).getNative() != nativeDevice) (*it)->getImpl<CLDeviceCL &>().getNative() != nativeDevice)
{ {
++it; ++it;
} }
...@@ -69,4 +70,27 @@ cl::DeviceRefList CLContextCL::getDevices() const ...@@ -69,4 +70,27 @@ cl::DeviceRefList CLContextCL::getDevices() const
return cl::DeviceRefList{}; return cl::DeviceRefList{};
} }
CLCommandQueueImpl::Ptr CLContextCL::createCommandQueue(const cl::CommandQueue &commandQueue,
cl_int *errcodeRet)
{
const cl::Device &device = commandQueue.getDevice();
const cl_device_id nativeDevice = device.getImpl<CLDeviceCL &>().getNative();
cl_command_queue nativeQueue = nullptr;
if (device.getInfo().mVersion < CL_MAKE_VERSION(2, 0, 0))
{
nativeQueue = mNative->getDispatch().clCreateCommandQueue(
mNative, nativeDevice, commandQueue.getProperties(), errcodeRet);
}
else
{
const cl_queue_properties propArray[] = {CL_QUEUE_PROPERTIES, commandQueue.getProperties(),
commandQueue.hasSize() ? CL_QUEUE_SIZE : 0u,
commandQueue.getSize(), 0u};
nativeQueue = mNative->getDispatch().clCreateCommandQueueWithProperties(
mNative, nativeDevice, propArray, errcodeRet);
}
return CLCommandQueueImpl::Ptr(
nativeQueue != nullptr ? new CLCommandQueueCL(commandQueue, nativeQueue) : nullptr);
}
} // namespace rx } // namespace rx
...@@ -23,6 +23,9 @@ class CLContextCL : public CLContextImpl ...@@ -23,6 +23,9 @@ class CLContextCL : public CLContextImpl
cl::DeviceRefList getDevices() const override; cl::DeviceRefList getDevices() const override;
CLCommandQueueImpl::Ptr createCommandQueue(const cl::CommandQueue &commandQueue,
cl_int *errcodeRet) override;
private: private:
const cl_context mNative; const cl_context mNative;
}; };
......
...@@ -352,7 +352,7 @@ CLContextImpl::Ptr CLPlatformCL::createContext(const cl::Context &context, ...@@ -352,7 +352,7 @@ CLContextImpl::Ptr CLPlatformCL::createContext(const cl::Context &context,
std::vector<cl_device_id> nativeDevices; std::vector<cl_device_id> nativeDevices;
for (const cl::DeviceRefPtr &device : devices) for (const cl::DeviceRefPtr &device : devices)
{ {
nativeDevices.emplace_back(static_cast<CLDeviceCL &>(device->getImpl()).getNative()); nativeDevices.emplace_back(device->getImpl<CLDeviceCL &>().getNative());
} }
CLContextImpl::Ptr contextImpl; CLContextImpl::Ptr contextImpl;
......
...@@ -105,6 +105,8 @@ _vulkan_backend_sources = [ ...@@ -105,6 +105,8 @@ _vulkan_backend_sources = [
if (angle_enable_cl) { if (angle_enable_cl) {
_vulkan_backend_sources += [ _vulkan_backend_sources += [
"CLCommandQueueVk.cpp",
"CLCommandQueueVk.h",
"CLContextVk.cpp", "CLContextVk.cpp",
"CLContextVk.h", "CLContextVk.h",
"CLDeviceVk.cpp", "CLDeviceVk.cpp",
......
//
// 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.
//
// CLCommandQueueVk.cpp: Implements the class methods for CLCommandQueueVk.
#include "libANGLE/renderer/vulkan/CLCommandQueueVk.h"
namespace rx
{
CLCommandQueueVk::CLCommandQueueVk(const cl::CommandQueue &commandQueue)
: CLCommandQueueImpl(commandQueue)
{}
CLCommandQueueVk::~CLCommandQueueVk() = default;
} // 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.
//
// CLCommandQueueVk.h: Defines the class interface for CLCommandQueueVk,
// implementing CLCommandQueueImpl.
#ifndef LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_
#include "libANGLE/renderer/vulkan/cl_types.h"
#include "libANGLE/renderer/CLCommandQueueImpl.h"
namespace rx
{
class CLCommandQueueVk : public CLCommandQueueImpl
{
public:
CLCommandQueueVk(const cl::CommandQueue &commandQueue);
~CLCommandQueueVk() override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_
...@@ -222,12 +222,12 @@ cl_int ValidateGetContextInfo(cl_context context, ...@@ -222,12 +222,12 @@ cl_int ValidateGetContextInfo(cl_context context,
cl_int ValidateRetainCommandQueue(cl_command_queue command_queue) cl_int ValidateRetainCommandQueue(cl_command_queue command_queue)
{ {
return CL_SUCCESS; return CommandQueue::IsValid(command_queue) ? CL_SUCCESS : CL_INVALID_COMMAND_QUEUE;
} }
cl_int ValidateReleaseCommandQueue(cl_command_queue command_queue) cl_int ValidateReleaseCommandQueue(cl_command_queue command_queue)
{ {
return CL_SUCCESS; return CommandQueue::IsValid(command_queue) ? CL_SUCCESS : CL_INVALID_COMMAND_QUEUE;
} }
cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue, cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
...@@ -236,6 +236,20 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue, ...@@ -236,6 +236,20 @@ cl_int ValidateGetCommandQueueInfo(cl_command_queue command_queue,
const void *param_value, const void *param_value,
const size_t *param_value_size_ret) const size_t *param_value_size_ret)
{ {
if (!CommandQueue::IsValid(command_queue))
{
return CL_INVALID_COMMAND_QUEUE;
}
const cl_version version =
static_cast<CommandQueue *>(command_queue)->getDevice().getInfo().mVersion;
if (param_name == CommandQueueInfo::InvalidEnum ||
(param_name == CommandQueueInfo::Size && version < CL_MAKE_VERSION(2, 0, 0)) ||
(param_name == CommandQueueInfo::DeviceDefault && version < CL_MAKE_VERSION(2, 1, 0)) ||
(param_name == CommandQueueInfo::PropertiesArray && version < CL_MAKE_VERSION(3, 0, 0)) ||
(param_value_size == 0u && param_value != nullptr))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -637,6 +651,15 @@ cl_int ValidateSetCommandQueueProperty(cl_command_queue command_queue, ...@@ -637,6 +651,15 @@ cl_int ValidateSetCommandQueueProperty(cl_command_queue command_queue,
cl_bool enable, cl_bool enable,
const cl_command_queue_properties *old_properties) const cl_command_queue_properties *old_properties)
{ {
if (!CommandQueue::IsValid(command_queue))
{
return CL_INVALID_COMMAND_QUEUE;
}
// Fails if properties bitfield is not zero after masking out all allowed values
if ((properties & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_PROFILING_ENABLE)) != 0u)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -698,6 +721,19 @@ bool ValidateCreateCommandQueue(cl_context context, ...@@ -698,6 +721,19 @@ bool ValidateCreateCommandQueue(cl_context context,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
if (!Context::IsValid(context))
{
ANGLE_ERROR_RETURN(CL_INVALID_CONTEXT, false);
}
if (!static_cast<Context *>(context)->hasDevice(device))
{
ANGLE_ERROR_RETURN(CL_INVALID_DEVICE, false);
}
// Fails if properties bitfield is not zero after masking out all allowed values
if ((properties & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_PROFILING_ENABLE)) != 0u)
{
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
return true; return true;
} }
...@@ -817,7 +853,8 @@ cl_int ValidateCreateSubDevices(cl_device_id in_device, ...@@ -817,7 +853,8 @@ cl_int ValidateCreateSubDevices(cl_device_id in_device,
const cl_device_id *out_devices, const cl_device_id *out_devices,
const cl_uint *num_devices_ret) const cl_uint *num_devices_ret)
{ {
if (!Device::IsValid(in_device)) if (!Device::IsValid(in_device) ||
static_cast<Device *>(in_device)->getInfo().mVersion < CL_MAKE_VERSION(1, 2, 0))
{ {
return CL_INVALID_DEVICE; return CL_INVALID_DEVICE;
} }
...@@ -832,12 +869,18 @@ cl_int ValidateCreateSubDevices(cl_device_id in_device, ...@@ -832,12 +869,18 @@ cl_int ValidateCreateSubDevices(cl_device_id in_device,
cl_int ValidateRetainDevice(cl_device_id device) cl_int ValidateRetainDevice(cl_device_id device)
{ {
return Device::IsValid(device) ? CL_SUCCESS : CL_INVALID_DEVICE; return Device::IsValid(device) &&
static_cast<Device *>(device)->getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0)
? CL_SUCCESS
: CL_INVALID_DEVICE;
} }
cl_int ValidateReleaseDevice(cl_device_id device) cl_int ValidateReleaseDevice(cl_device_id device)
{ {
return Device::IsValid(device) ? CL_SUCCESS : CL_INVALID_DEVICE; return Device::IsValid(device) &&
static_cast<Device *>(device)->getInfo().mVersion >= CL_MAKE_VERSION(1, 2, 0)
? CL_SUCCESS
: CL_INVALID_DEVICE;
} }
bool ValidateCreateImage(cl_context context, bool ValidateCreateImage(cl_context context,
...@@ -963,6 +1006,55 @@ bool ValidateCreateCommandQueueWithProperties(cl_context context, ...@@ -963,6 +1006,55 @@ bool ValidateCreateCommandQueueWithProperties(cl_context context,
const cl_queue_properties *properties, const cl_queue_properties *properties,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
if (!Context::IsValid(context))
{
ANGLE_ERROR_RETURN(CL_INVALID_CONTEXT, false);
}
if (!static_cast<Context *>(context)->hasDevice(device) ||
static_cast<Device *>(device)->getInfo().mVersion < CL_MAKE_VERSION(2, 0, 0))
{
ANGLE_ERROR_RETURN(CL_INVALID_DEVICE, false);
}
if (properties != nullptr)
{
while (*properties != 0)
{
switch (*properties++)
{
case CL_QUEUE_PROPERTIES:
{
const cl_command_queue_properties props = *properties++;
// Fails if properties bitfield is not zero after masking out allowed values
if ((props &
~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_PROFILING_ENABLE |
CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT)) != 0u ||
// Fails for invalid value combinations
((props & CL_QUEUE_ON_DEVICE) != 0u &&
(props & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) == 0u) ||
((props & CL_QUEUE_ON_DEVICE_DEFAULT) != 0u &&
(props & CL_QUEUE_ON_DEVICE) == 0u))
{
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
break;
}
case CL_QUEUE_SIZE:
{
cl_uint maxSize = 0u;
if (static_cast<Device *>(device)->getInfoUInt(DeviceInfo::QueueOnDeviceMaxSize,
&maxSize) != CL_SUCCESS ||
*properties > maxSize)
{
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
++properties;
break;
}
default:
ANGLE_ERROR_RETURN(CL_INVALID_VALUE, false);
}
}
}
return true; return true;
} }
......
...@@ -465,6 +465,7 @@ libangle_cl_headers = [ ...@@ -465,6 +465,7 @@ libangle_cl_headers = [
"src/libANGLE/CLRefPointer.h", "src/libANGLE/CLRefPointer.h",
"src/libANGLE/CLSampler.h", "src/libANGLE/CLSampler.h",
"src/libANGLE/CLtypes.h", "src/libANGLE/CLtypes.h",
"src/libANGLE/renderer/CLCommandQueueImpl.h",
"src/libANGLE/renderer/CLContextImpl.h", "src/libANGLE/renderer/CLContextImpl.h",
"src/libANGLE/renderer/CLDeviceImpl.h", "src/libANGLE/renderer/CLDeviceImpl.h",
"src/libANGLE/renderer/CLPlatformImpl.h", "src/libANGLE/renderer/CLPlatformImpl.h",
...@@ -483,6 +484,7 @@ libangle_cl_sources = [ ...@@ -483,6 +484,7 @@ libangle_cl_sources = [
"src/libANGLE/CLPlatform.cpp", "src/libANGLE/CLPlatform.cpp",
"src/libANGLE/CLProgram.cpp", "src/libANGLE/CLProgram.cpp",
"src/libANGLE/CLSampler.cpp", "src/libANGLE/CLSampler.cpp",
"src/libANGLE/renderer/CLCommandQueueImpl.cpp",
"src/libANGLE/renderer/CLContextImpl.cpp", "src/libANGLE/renderer/CLContextImpl.cpp",
"src/libANGLE/renderer/CLDeviceImpl.cpp", "src/libANGLE/renderer/CLDeviceImpl.cpp",
"src/libANGLE/renderer/CLPlatformImpl.cpp", "src/libANGLE/renderer/CLPlatformImpl.cpp",
......
...@@ -173,20 +173,20 @@ cl_command_queue CreateCommandQueueWithProperties(cl_context context, ...@@ -173,20 +173,20 @@ cl_command_queue CreateCommandQueueWithProperties(cl_context context,
const cl_queue_properties *properties, const cl_queue_properties *properties,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateCommandQueueWithProperties); return static_cast<Context *>(context)->createCommandQueueWithProperties(device, properties,
return 0; errcode_ret);
} }
cl_int RetainCommandQueue(cl_command_queue command_queue) cl_int RetainCommandQueue(cl_command_queue command_queue)
{ {
WARN_NOT_SUPPORTED(RetainCommandQueue); static_cast<CommandQueue *>(command_queue)->retain();
return 0; return CL_SUCCESS;
} }
cl_int ReleaseCommandQueue(cl_command_queue command_queue) cl_int ReleaseCommandQueue(cl_command_queue command_queue)
{ {
WARN_NOT_SUPPORTED(ReleaseCommandQueue); static_cast<CommandQueue *>(command_queue)->release();
return 0; return CL_SUCCESS;
} }
cl_int GetCommandQueueInfo(cl_command_queue command_queue, cl_int GetCommandQueueInfo(cl_command_queue command_queue,
...@@ -1063,8 +1063,8 @@ cl_int SetCommandQueueProperty(cl_command_queue command_queue, ...@@ -1063,8 +1063,8 @@ cl_int SetCommandQueueProperty(cl_command_queue command_queue,
cl_bool enable, cl_bool enable,
cl_command_queue_properties *old_properties) cl_command_queue_properties *old_properties)
{ {
WARN_NOT_SUPPORTED(SetCommandQueueProperty); return static_cast<CommandQueue *>(command_queue)
return 0; ->setProperty(properties, enable, old_properties);
} }
cl_mem CreateImage2D(cl_context context, cl_mem CreateImage2D(cl_context context,
...@@ -1137,8 +1137,7 @@ cl_command_queue CreateCommandQueue(cl_context context, ...@@ -1137,8 +1137,7 @@ cl_command_queue CreateCommandQueue(cl_context context,
cl_command_queue_properties properties, cl_command_queue_properties properties,
cl_int *errcode_ret) cl_int *errcode_ret)
{ {
WARN_NOT_SUPPORTED(CreateCommandQueue); return static_cast<Context *>(context)->createCommandQueue(device, properties, errcode_ret);
return 0;
} }
cl_sampler CreateSampler(cl_context context, cl_sampler CreateSampler(cl_context context,
......
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