Commit 076974a9 by John Plate Committed by Angle LUCI CQ

CL: event creation for front end & passthrough

Add event object to back end and implement creation and info query. Bug: angleproject:6001 Change-Id: Id4951b726b66afa289fafe1a716a7cfdb6f5826d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2925477 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent d7aa0130
...@@ -29,6 +29,8 @@ using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo, ...@@ -29,6 +29,8 @@ using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo,
size_t cb, size_t cb,
void *user_data); void *user_data);
using EventCB = void(CL_CALLBACK *)(cl_event event, cl_int event_command_status, void *user_data);
template <typename CLObjectType> template <typename CLObjectType>
struct Dispatch struct Dispatch
{ {
......
...@@ -20,7 +20,8 @@ cl_mem Buffer::createSubBuffer(MemFlags flags, ...@@ -20,7 +20,8 @@ cl_mem Buffer::createSubBuffer(MemFlags flags,
cl_int &errorCode) cl_int &errorCode)
{ {
const cl_buffer_region &region = *static_cast<const cl_buffer_region *>(createInfo); const cl_buffer_region &region = *static_cast<const cl_buffer_region *>(createInfo);
return mContext->createMemory(new Buffer(*this, flags, region.origin, region.size, errorCode)); return mContext->createMemory(new Buffer(*this, flags, region.origin, region.size, errorCode),
errorCode);
} }
Buffer::Buffer(Context &context, Buffer::Buffer(Context &context,
......
...@@ -50,7 +50,7 @@ inline cl_mem_object_type Buffer::getType() const ...@@ -50,7 +50,7 @@ inline cl_mem_object_type Buffer::getType() const
inline bool Buffer::isSubBuffer() const inline bool Buffer::isSubBuffer() const
{ {
return mParent.isValid(); return mParent != nullptr;
} }
inline bool Buffer::isRegionValid(const cl_buffer_region &region) const inline bool Buffer::isRegionValid(const cl_buffer_region &region) const
......
...@@ -85,7 +85,7 @@ cl_command_queue Context::createCommandQueue(cl_device_id device, ...@@ -85,7 +85,7 @@ cl_command_queue Context::createCommandQueue(cl_device_id device,
cl_int &errorCode) cl_int &errorCode)
{ {
return createCommandQueue( return createCommandQueue(
new CommandQueue(*this, *static_cast<Device *>(device), properties, errorCode)); new CommandQueue(*this, *static_cast<Device *>(device), properties, errorCode), errorCode);
} }
cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device, cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
...@@ -116,7 +116,8 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device, ...@@ -116,7 +116,8 @@ cl_command_queue Context::createCommandQueueWithProperties(cl_device_id device,
propArray.insert(propArray.cend(), properties, propIt); propArray.insert(propArray.cend(), properties, propIt);
} }
return createCommandQueue(new CommandQueue(*this, *static_cast<Device *>(device), return createCommandQueue(new CommandQueue(*this, *static_cast<Device *>(device),
std::move(propArray), props, size, errorCode)); std::move(propArray), props, size, errorCode),
errorCode);
} }
cl_mem Context::createBuffer(const cl_mem_properties *properties, cl_mem Context::createBuffer(const cl_mem_properties *properties,
...@@ -125,7 +126,7 @@ cl_mem Context::createBuffer(const cl_mem_properties *properties, ...@@ -125,7 +126,7 @@ cl_mem Context::createBuffer(const cl_mem_properties *properties,
void *hostPtr, void *hostPtr,
cl_int &errorCode) cl_int &errorCode)
{ {
return createMemory(new Buffer(*this, {}, flags, size, hostPtr, errorCode)); return createMemory(new Buffer(*this, {}, flags, size, hostPtr, errorCode), errorCode);
} }
cl_mem Context::createImage(const cl_mem_properties *properties, cl_mem Context::createImage(const cl_mem_properties *properties,
...@@ -140,7 +141,8 @@ cl_mem Context::createImage(const cl_mem_properties *properties, ...@@ -140,7 +141,8 @@ cl_mem Context::createImage(const cl_mem_properties *properties,
desc->image_depth, desc->image_array_size, desc->image_row_pitch, desc->image_depth, desc->image_array_size, desc->image_row_pitch,
desc->image_slice_pitch, desc->num_mip_levels, desc->num_samples}; desc->image_slice_pitch, desc->num_mip_levels, desc->num_samples};
return createMemory(new Image(*this, {}, flags, *format, imageDesc, return createMemory(new Image(*this, {}, flags, *format, imageDesc,
static_cast<Memory *>(desc->buffer), hostPtr, errorCode)); static_cast<Memory *>(desc->buffer), hostPtr, errorCode),
errorCode);
} }
cl_mem Context::createImage2D(MemFlags flags, cl_mem Context::createImage2D(MemFlags flags,
...@@ -154,7 +156,7 @@ cl_mem Context::createImage2D(MemFlags flags, ...@@ -154,7 +156,7 @@ cl_mem Context::createImage2D(MemFlags flags,
const ImageDescriptor imageDesc = { const ImageDescriptor imageDesc = {
CL_MEM_OBJECT_IMAGE2D, width, height, 0u, 0u, rowPitch, 0u, 0u, 0u}; CL_MEM_OBJECT_IMAGE2D, width, height, 0u, 0u, rowPitch, 0u, 0u, 0u};
return createMemory( return createMemory(
new Image(*this, {}, flags, *format, imageDesc, nullptr, hostPtr, errorCode)); new Image(*this, {}, flags, *format, imageDesc, nullptr, hostPtr, errorCode), errorCode);
} }
cl_mem Context::createImage3D(MemFlags flags, cl_mem Context::createImage3D(MemFlags flags,
...@@ -170,7 +172,7 @@ cl_mem Context::createImage3D(MemFlags flags, ...@@ -170,7 +172,7 @@ cl_mem Context::createImage3D(MemFlags flags,
const ImageDescriptor imageDesc = { const ImageDescriptor imageDesc = {
CL_MEM_OBJECT_IMAGE3D, width, height, depth, 0u, rowPitch, slicePitch, 0u, 0u}; CL_MEM_OBJECT_IMAGE3D, width, height, depth, 0u, rowPitch, slicePitch, 0u, 0u};
return createMemory( return createMemory(
new Image(*this, {}, flags, *format, imageDesc, nullptr, hostPtr, errorCode)); new Image(*this, {}, flags, *format, imageDesc, nullptr, hostPtr, errorCode), errorCode);
} }
cl_sampler Context::createSampler(cl_bool normalizedCoords, cl_sampler Context::createSampler(cl_bool normalizedCoords,
...@@ -179,7 +181,7 @@ cl_sampler Context::createSampler(cl_bool normalizedCoords, ...@@ -179,7 +181,7 @@ cl_sampler Context::createSampler(cl_bool normalizedCoords,
cl_int &errorCode) cl_int &errorCode)
{ {
return createSampler( return createSampler(
new Sampler(*this, {}, normalizedCoords, addressingMode, filterMode, errorCode)); new Sampler(*this, {}, normalizedCoords, addressingMode, filterMode, errorCode), errorCode);
} }
cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *properties, cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *properties,
...@@ -215,7 +217,8 @@ cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *pro ...@@ -215,7 +217,8 @@ cl_sampler Context::createSamplerWithProperties(const cl_sampler_properties *pro
} }
return createSampler(new Sampler(*this, std::move(propArray), normalizedCoords, addressingMode, return createSampler(new Sampler(*this, std::move(propArray), normalizedCoords, addressingMode,
filterMode, errorCode)); filterMode, errorCode),
errorCode);
} }
cl_program Context::createProgramWithSource(cl_uint count, cl_program Context::createProgramWithSource(cl_uint count,
...@@ -246,12 +249,12 @@ cl_program Context::createProgramWithSource(cl_uint count, ...@@ -246,12 +249,12 @@ cl_program Context::createProgramWithSource(cl_uint count,
++lengths; ++lengths;
} }
} }
return createProgram(new Program(*this, std::move(source), errorCode)); return createProgram(new Program(*this, std::move(source), errorCode), errorCode);
} }
cl_program Context::createProgramWithIL(const void *il, size_t length, cl_int &errorCode) cl_program Context::createProgramWithIL(const void *il, size_t length, cl_int &errorCode)
{ {
return createProgram(new Program(*this, il, length, errorCode)); return createProgram(new Program(*this, il, length, errorCode), errorCode);
} }
cl_program Context::createProgramWithBinary(cl_uint numDevices, cl_program Context::createProgramWithBinary(cl_uint numDevices,
...@@ -270,7 +273,8 @@ cl_program Context::createProgramWithBinary(cl_uint numDevices, ...@@ -270,7 +273,8 @@ cl_program Context::createProgramWithBinary(cl_uint numDevices,
std::memcpy(binaryVec.back().data(), *binaries++, binaryVec.back().size()); std::memcpy(binaryVec.back().data(), *binaries++, binaryVec.back().size());
} }
return createProgram( return createProgram(
new Program(*this, std::move(refDevices), std::move(binaryVec), binaryStatus, errorCode)); new Program(*this, std::move(refDevices), std::move(binaryVec), binaryStatus, errorCode),
errorCode);
} }
cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices, cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices,
...@@ -283,7 +287,24 @@ cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices, ...@@ -283,7 +287,24 @@ cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices,
{ {
refDevices.emplace_back(static_cast<Device *>(*devices++)); refDevices.emplace_back(static_cast<Device *>(*devices++));
} }
return createProgram(new Program(*this, std::move(refDevices), kernelNames, errorCode)); return createProgram(new Program(*this, std::move(refDevices), kernelNames, errorCode),
errorCode);
}
cl_event Context::createUserEvent(cl_int &errorCode)
{
return createEvent(new Event(*this, errorCode), errorCode);
}
cl_int Context::waitForEvents(cl_uint numEvents, const cl_event *eventList)
{
EventRefs events;
events.reserve(numEvents);
while (numEvents-- != 0u)
{
events.emplace_back(static_cast<Event *>(*eventList++));
}
return mImpl->waitForEvents(events);
} }
bool Context::IsValid(const _cl_context *context) bool Context::IsValid(const _cl_context *context)
...@@ -348,10 +369,10 @@ Context::Context(Platform &platform, ...@@ -348,10 +369,10 @@ Context::Context(Platform &platform,
mDevices(mImpl ? mImpl->getDevices(errorCode) : DeviceRefs{}) mDevices(mImpl ? mImpl->getDevices(errorCode) : DeviceRefs{})
{} {}
cl_command_queue Context::createCommandQueue(CommandQueue *commandQueue) cl_command_queue Context::createCommandQueue(CommandQueue *commandQueue, cl_int errorCode)
{ {
mCommandQueues.emplace_back(commandQueue); mCommandQueues.emplace_back(commandQueue);
if (!mCommandQueues.back()->mImpl) if (errorCode != CL_SUCCESS)
{ {
mCommandQueues.back()->release(); mCommandQueues.back()->release();
return nullptr; return nullptr;
...@@ -359,10 +380,10 @@ cl_command_queue Context::createCommandQueue(CommandQueue *commandQueue) ...@@ -359,10 +380,10 @@ cl_command_queue Context::createCommandQueue(CommandQueue *commandQueue)
return mCommandQueues.back().get(); return mCommandQueues.back().get();
} }
cl_mem Context::createMemory(Memory *memory) cl_mem Context::createMemory(Memory *memory, cl_int errorCode)
{ {
mMemories.emplace_back(memory); mMemories.emplace_back(memory);
if (!mMemories.back()->mImpl || mMemories.back()->mSize == 0u) if (errorCode != CL_SUCCESS)
{ {
mMemories.back()->release(); mMemories.back()->release();
return nullptr; return nullptr;
...@@ -370,10 +391,10 @@ cl_mem Context::createMemory(Memory *memory) ...@@ -370,10 +391,10 @@ cl_mem Context::createMemory(Memory *memory)
return mMemories.back().get(); return mMemories.back().get();
} }
cl_sampler Context::createSampler(Sampler *sampler) cl_sampler Context::createSampler(Sampler *sampler, cl_int errorCode)
{ {
mSamplers.emplace_back(sampler); mSamplers.emplace_back(sampler);
if (!mSamplers.back()->mImpl) if (errorCode != CL_SUCCESS)
{ {
mSamplers.back()->release(); mSamplers.back()->release();
return nullptr; return nullptr;
...@@ -381,10 +402,10 @@ cl_sampler Context::createSampler(Sampler *sampler) ...@@ -381,10 +402,10 @@ cl_sampler Context::createSampler(Sampler *sampler)
return mSamplers.back().get(); return mSamplers.back().get();
} }
cl_program Context::createProgram(Program *program) cl_program Context::createProgram(Program *program, cl_int errorCode)
{ {
mPrograms.emplace_back(program); mPrograms.emplace_back(program);
if (!mPrograms.back()->mImpl) if (errorCode != CL_SUCCESS)
{ {
mPrograms.back()->release(); mPrograms.back()->release();
return nullptr; return nullptr;
...@@ -392,6 +413,17 @@ cl_program Context::createProgram(Program *program) ...@@ -392,6 +413,17 @@ cl_program Context::createProgram(Program *program)
return mPrograms.back().get(); return mPrograms.back().get();
} }
cl_event Context::createEvent(Event *event, cl_int errorCode)
{
mEvents.emplace_back(event);
if (errorCode != CL_SUCCESS)
{
mEvents.back()->release();
return nullptr;
}
return mEvents.back().get();
}
void Context::destroyCommandQueue(CommandQueue *commandQueue) void Context::destroyCommandQueue(CommandQueue *commandQueue)
{ {
auto commandQueueIt = mCommandQueues.cbegin(); auto commandQueueIt = mCommandQueues.cbegin();
...@@ -460,4 +492,21 @@ void Context::destroyProgram(Program *program) ...@@ -460,4 +492,21 @@ void Context::destroyProgram(Program *program)
} }
} }
void Context::destroyEvent(Event *event)
{
auto eventIt = mEvents.cbegin();
while (eventIt != mEvents.cend() && eventIt->get() != event)
{
++eventIt;
}
if (eventIt != mEvents.cend())
{
mEvents.erase(eventIt);
}
else
{
ERR() << "Event not found";
}
}
} // namespace cl } // namespace cl
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLEvent.h"
#include "libANGLE/CLMemory.h" #include "libANGLE/CLMemory.h"
#include "libANGLE/CLProgram.h" #include "libANGLE/CLProgram.h"
#include "libANGLE/CLSampler.h" #include "libANGLE/CLSampler.h"
...@@ -40,6 +41,9 @@ class Context final : public _cl_context, public Object ...@@ -40,6 +41,9 @@ class Context final : public _cl_context, public Object
bool hasSampler(const _cl_sampler *sampler) const; bool hasSampler(const _cl_sampler *sampler) const;
bool hasProgram(const _cl_program *program) const; bool hasProgram(const _cl_program *program) const;
bool hasKernel(const _cl_kernel *kernel) const; bool hasKernel(const _cl_kernel *kernel) const;
bool hasEvent(const _cl_event *event) const;
EventRefPtr findEvent(const EventPredicate &eventPredicate) const;
void retain() noexcept; void retain() noexcept;
bool release(); bool release();
...@@ -112,6 +116,10 @@ class Context final : public _cl_context, public Object ...@@ -112,6 +116,10 @@ class Context final : public _cl_context, public Object
const char *kernelNames, const char *kernelNames,
cl_int &errorCode); cl_int &errorCode);
cl_event createUserEvent(cl_int &errorCode);
cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
static bool IsValid(const _cl_context *context); static bool IsValid(const _cl_context *context);
static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor); static bool IsValidAndVersionOrNewer(const _cl_context *context, cl_uint major, cl_uint minor);
...@@ -137,15 +145,17 @@ class Context final : public _cl_context, public Object ...@@ -137,15 +145,17 @@ class Context final : public _cl_context, public Object
bool userSync, bool userSync,
cl_int &errorCode); cl_int &errorCode);
cl_command_queue createCommandQueue(CommandQueue *commandQueue); cl_command_queue createCommandQueue(CommandQueue *commandQueue, cl_int errorCode);
cl_mem createMemory(Memory *memory); cl_mem createMemory(Memory *memory, cl_int errorCode);
cl_sampler createSampler(Sampler *sampler); cl_sampler createSampler(Sampler *sampler, cl_int errorCode);
cl_program createProgram(Program *program); cl_program createProgram(Program *program, cl_int errorCode);
cl_event createEvent(Event *event, cl_int errorCode);
void destroyCommandQueue(CommandQueue *commandQueue); void destroyCommandQueue(CommandQueue *commandQueue);
void destroyMemory(Memory *memory); void destroyMemory(Memory *memory);
void destroySampler(Sampler *sampler); void destroySampler(Sampler *sampler);
void destroyProgram(Program *program); void destroyProgram(Program *program);
void destroyEvent(Event *event);
Platform &mPlatform; Platform &mPlatform;
const PropArray mProperties; const PropArray mProperties;
...@@ -158,9 +168,11 @@ class Context final : public _cl_context, public Object ...@@ -158,9 +168,11 @@ class Context final : public _cl_context, public Object
Memory::PtrList mMemories; Memory::PtrList mMemories;
Sampler::PtrList mSamplers; Sampler::PtrList mSamplers;
Program::PtrList mPrograms; Program::PtrList mPrograms;
Event::PtrList mEvents;
friend class Buffer; friend class Buffer;
friend class CommandQueue; friend class CommandQueue;
friend class Event;
friend class Memory; friend class Memory;
friend class Platform; friend class Platform;
friend class Program; friend class Program;
...@@ -240,6 +252,18 @@ inline bool Context::hasKernel(const _cl_kernel *kernel) const ...@@ -240,6 +252,18 @@ inline bool Context::hasKernel(const _cl_kernel *kernel) const
}) != mPrograms.cend(); }) != mPrograms.cend();
} }
inline bool Context::hasEvent(const _cl_event *event) const
{
return std::find_if(mEvents.cbegin(), mEvents.cend(),
[=](const EventPtr &ptr) { return ptr.get() == event; }) != mEvents.cend();
}
inline EventRefPtr Context::findEvent(const EventPredicate &eventPredicate) const
{
const auto eventIt = std::find_if(mEvents.cbegin(), mEvents.cend(), eventPredicate);
return EventRefPtr(eventIt != mEvents.cend() ? eventIt->get() : nullptr);
}
inline void Context::retain() noexcept inline void Context::retain() noexcept
{ {
addRef(); addRef();
......
...@@ -7,9 +7,143 @@ ...@@ -7,9 +7,143 @@
#include "libANGLE/CLEvent.h" #include "libANGLE/CLEvent.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLPlatform.h"
#include <cstring>
namespace cl namespace cl
{ {
Event::Event(const cl_icd_dispatch &dispatch) : _cl_event(dispatch) {} Event::~Event() = default;
bool Event::release()
{
const bool released = removeRef();
if (released)
{
mContext->destroyEvent(this);
}
return released;
}
void Event::callback(cl_int commandStatus)
{
ASSERT(commandStatus >= 0 && commandStatus < 3);
for (const CallbackData &data : mCallbacks[commandStatus])
{
data.first(this, commandStatus, data.second);
}
}
cl_int Event::setUserEventStatus(cl_int executionStatus)
{
const cl_int errorCode = mImpl->setUserEventStatus(executionStatus);
if (errorCode == CL_SUCCESS)
{
mStatusWasChanged = true;
}
return errorCode;
}
cl_int Event::getInfo(EventInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
cl_int execStatus = 0;
void *valPointer = nullptr;
const void *copyValue = nullptr;
size_t copySize = 0u;
switch (name)
{
case EventInfo::CommandQueue:
valPointer = static_cast<cl_command_queue>(mCommandQueue.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
case EventInfo::CommandType:
copyValue = &mCommandType;
copySize = sizeof(mCommandType);
break;
case EventInfo::ReferenceCount:
copyValue = getRefCountPtr();
copySize = sizeof(*getRefCountPtr());
break;
case EventInfo::CommandExecutionStatus:
{
const cl_int errorCode = mImpl->getCommandExecutionStatus(execStatus);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
copyValue = &execStatus;
copySize = sizeof(execStatus);
break;
}
case EventInfo::Context:
valPointer = static_cast<cl_context>(mContext.get());
copyValue = &valPointer;
copySize = sizeof(valPointer);
break;
default:
return CL_INVALID_VALUE;
}
if (value != nullptr)
{
// CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
// as described in the Event Queries table and param_value is not NULL.
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 Event::setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData)
{
// Only when required register a single callback with the back end for each callback type.
if (mCallbacks[commandExecCallbackType].empty())
{
const cl_int errorCode = mImpl->setCallback(commandExecCallbackType);
if (errorCode != CL_SUCCESS)
{
return errorCode;
}
}
mCallbacks[commandExecCallbackType].emplace_back(pfnNotify, userData);
return CL_SUCCESS;
}
bool Event::IsValid(const _cl_event *event)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->hasEvent(event);
}) != platforms.cend();
}
bool Event::IsValidAndVersionOrNewer(const _cl_event *event, cl_uint major, cl_uint minor)
{
const Platform::PtrList &platforms = Platform::GetPlatforms();
return std::find_if(platforms.cbegin(), platforms.cend(), [=](const PlatformPtr &platform) {
return platform->isVersionOrNewer(major, minor) && platform->hasEvent(event);
}) != platforms.cend();
}
Event::Event(Context &context, cl_int &errorCode)
: _cl_event(context.getDispatch()),
mContext(&context),
mImpl(context.mImpl->createUserEvent(*this, errorCode)),
mCommandType(CL_COMMAND_USER)
{}
} // namespace cl } // namespace cl
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#define LIBANGLE_CLEVENT_H_ #define LIBANGLE_CLEVENT_H_
#include "libANGLE/CLObject.h" #include "libANGLE/CLObject.h"
#include "libANGLE/renderer/CLEventImpl.h"
#include <array>
namespace cl namespace cl
{ {
...@@ -17,10 +20,89 @@ namespace cl ...@@ -17,10 +20,89 @@ namespace cl
class Event final : public _cl_event, public Object class Event final : public _cl_event, public Object
{ {
public: public:
Event(const cl_icd_dispatch &dispatch); using PtrList = std::list<EventPtr>;
~Event() override = default;
~Event() override;
Context &getContext();
const Context &getContext() const;
const CommandQueueRefPtr &getCommandQueue() const;
cl_command_type getCommandType() const;
bool wasStatusChanged() const;
template <typename T>
T &getImpl() const;
void retain() noexcept;
bool release();
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);
static bool IsValid(const _cl_event *event);
static bool IsValidAndVersionOrNewer(const _cl_event *event, cl_uint major, cl_uint minor);
private:
using CallbackData = std::pair<EventCB, void *>;
Event(Context &context, cl_int &errorCode);
const ContextRefPtr mContext;
const CommandQueueRefPtr mCommandQueue;
const rx::CLEventImpl::Ptr mImpl;
const cl_command_type mCommandType;
bool mStatusWasChanged = false;
// Create separate storage for each possible callback type.
static_assert(CL_COMPLETE == 0 && CL_RUNNING == 1 && CL_SUBMITTED == 2,
"OpenCL command execution status values are not as assumed");
std::array<std::vector<CallbackData>, 3u> mCallbacks;
friend class Context;
}; };
inline Context &Event::getContext()
{
return *mContext;
}
inline const Context &Event::getContext() const
{
return *mContext;
}
inline const CommandQueueRefPtr &Event::getCommandQueue() const
{
return mCommandQueue;
}
inline cl_command_type Event::getCommandType() const
{
return mCommandType;
}
inline bool Event::wasStatusChanged() const
{
return mStatusWasChanged;
}
template <typename T>
inline T &Event::getImpl() const
{
return static_cast<T &>(*mImpl);
}
inline void Event::retain() noexcept
{
addRef();
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLEVENT_H_ #endif // LIBANGLE_CLEVENT_H_
...@@ -212,9 +212,10 @@ cl_context Platform::CreateContext(const cl_context_properties *properties, ...@@ -212,9 +212,10 @@ cl_context Platform::CreateContext(const cl_context_properties *properties,
{ {
refDevices.emplace_back(static_cast<Device *>(*devices++)); refDevices.emplace_back(static_cast<Device *>(*devices++));
} }
return platform->createContext(new Context(*platform, std::move(propArray), return platform->createContext(
std::move(refDevices), notify, userData, userSync, new Context(*platform, std::move(propArray), std::move(refDevices), notify, userData,
errorCode)); userSync, errorCode),
errorCode);
} }
cl_context Platform::CreateContextFromType(const cl_context_properties *properties, cl_context Platform::CreateContextFromType(const cl_context_properties *properties,
...@@ -228,7 +229,8 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti ...@@ -228,7 +229,8 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti
Context::PropArray propArray = ParseContextProperties(properties, platform, userSync); Context::PropArray propArray = ParseContextProperties(properties, platform, userSync);
ASSERT(platform != nullptr); ASSERT(platform != nullptr);
return platform->createContext(new Context(*platform, std::move(propArray), deviceType, notify, return platform->createContext(new Context(*platform, std::move(propArray), deviceType, notify,
userData, userSync, errorCode)); userData, userSync, errorCode),
errorCode);
} }
Platform::Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc) Platform::Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc)
...@@ -238,10 +240,10 @@ Platform::Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &create ...@@ -238,10 +240,10 @@ Platform::Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &create
mDevices(mImpl->createDevices(*this)) mDevices(mImpl->createDevices(*this))
{} {}
cl_context Platform::createContext(Context *context) cl_context Platform::createContext(Context *context, cl_int errorCode)
{ {
mContexts.emplace_back(context); mContexts.emplace_back(context);
if (!mContexts.back()->mImpl || mContexts.back()->mDevices.empty()) if (errorCode != CL_SUCCESS)
{ {
mContexts.back()->release(); mContexts.back()->release();
return nullptr; return nullptr;
......
...@@ -37,6 +37,9 @@ class Platform final : public _cl_platform_id, public Object ...@@ -37,6 +37,9 @@ class Platform final : public _cl_platform_id, public Object
bool hasSampler(const _cl_sampler *sampler) const; bool hasSampler(const _cl_sampler *sampler) const;
bool hasProgram(const _cl_program *program) const; bool hasProgram(const _cl_program *program) const;
bool hasKernel(const _cl_kernel *kernel) const; bool hasKernel(const _cl_kernel *kernel) const;
bool hasEvent(const _cl_event *event) const;
EventRefPtr findEvent(const EventPredicate &eventPredicate) const;
cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const; cl_int getInfo(PlatformInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
...@@ -71,12 +74,14 @@ class Platform final : public _cl_platform_id, public Object ...@@ -71,12 +74,14 @@ class Platform final : public _cl_platform_id, public Object
static bool IsValid(const _cl_platform_id *platform); static bool IsValid(const _cl_platform_id *platform);
static bool IsValidOrDefault(const _cl_platform_id *platform); static bool IsValidOrDefault(const _cl_platform_id *platform);
static EventRefPtr FindEvent(const EventPredicate &eventPredicate);
static constexpr const char *GetVendor(); static constexpr const char *GetVendor();
private: private:
Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc); Platform(const cl_icd_dispatch &dispatch, const CreateImplFunc &createImplFunc);
cl_context createContext(Context *context); cl_context createContext(Context *context, cl_int errorCode);
void destroyContext(Context *context); void destroyContext(Context *context);
static PtrList &GetList(); static PtrList &GetList();
...@@ -157,6 +162,24 @@ inline bool Platform::hasKernel(const _cl_kernel *kernel) const ...@@ -157,6 +162,24 @@ inline bool Platform::hasKernel(const _cl_kernel *kernel) const
}) != mContexts.cend(); }) != mContexts.cend();
} }
inline bool Platform::hasEvent(const _cl_event *event) const
{
return std::find_if(mContexts.cbegin(), mContexts.cend(), [=](const ContextPtr &ptr) {
return ptr->hasEvent(event);
}) != mContexts.cend();
}
inline EventRefPtr Platform::findEvent(const EventPredicate &eventPredicate) const
{
EventRefPtr event;
auto contextIt = mContexts.cbegin();
while (contextIt != mContexts.cend() && event == nullptr)
{
event = (*contextIt++)->findEvent(eventPredicate);
}
return event;
}
inline Platform::PtrList &Platform::GetList() inline Platform::PtrList &Platform::GetList()
{ {
static angle::base::NoDestructor<PtrList> sList; static angle::base::NoDestructor<PtrList> sList;
...@@ -193,6 +216,17 @@ inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform) ...@@ -193,6 +216,17 @@ inline bool Platform::IsValidOrDefault(const _cl_platform_id *platform)
return platform != nullptr ? IsValid(platform) : GetDefault() != nullptr; return platform != nullptr ? IsValid(platform) : GetDefault() != nullptr;
} }
inline EventRefPtr Platform::FindEvent(const EventPredicate &eventPredicate)
{
EventRefPtr event;
auto platformIt = GetPlatforms().cbegin();
while (platformIt != GetPlatforms().cend() && event == nullptr)
{
event = (*platformIt++)->findEvent(eventPredicate);
}
return event;
}
constexpr const char *Platform::GetVendor() constexpr const char *Platform::GetVendor()
{ {
return kVendor; return kVendor;
......
...@@ -135,13 +135,13 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t ...@@ -135,13 +135,13 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t
cl_kernel Program::createKernel(const char *kernel_name, cl_int &errorCode) cl_kernel Program::createKernel(const char *kernel_name, cl_int &errorCode)
{ {
return createKernel(new Kernel(*this, kernel_name, errorCode)); return createKernel(new Kernel(*this, kernel_name, errorCode), errorCode);
} }
cl_int Program::createKernel(const Kernel::CreateImplFunc &createImplFunc) cl_int Program::createKernel(const Kernel::CreateImplFunc &createImplFunc)
{ {
cl_int errorCode = CL_SUCCESS; cl_int errorCode = CL_SUCCESS;
createKernel(new Kernel(*this, createImplFunc, errorCode)); createKernel(new Kernel(*this, createImplFunc, errorCode), errorCode);
return errorCode; return errorCode;
} }
...@@ -220,10 +220,10 @@ Program::Program(Context &context, DeviceRefs &&devices, const char *kernelNames ...@@ -220,10 +220,10 @@ Program::Program(Context &context, DeviceRefs &&devices, const char *kernelNames
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{}) mSource(mImpl ? mImpl->getSource(errorCode) : std::string{})
{} {}
cl_kernel Program::createKernel(Kernel *kernel) cl_kernel Program::createKernel(Kernel *kernel, cl_int errorCode)
{ {
mKernels.emplace_back(kernel); mKernels.emplace_back(kernel);
if (!mKernels.back()->mImpl) if (errorCode != CL_SUCCESS)
{ {
mKernels.back()->release(); mKernels.back()->release();
return nullptr; return nullptr;
......
...@@ -51,7 +51,7 @@ class Program final : public _cl_program, public Object ...@@ -51,7 +51,7 @@ class Program final : public _cl_program, public Object
Program(Context &context, DeviceRefs &&devices, const char *kernelNames, cl_int &errorCode); Program(Context &context, DeviceRefs &&devices, const char *kernelNames, cl_int &errorCode);
cl_kernel createKernel(Kernel *kernel); cl_kernel createKernel(Kernel *kernel, cl_int errorCode);
void destroyKernel(Kernel *kernel); void destroyKernel(Kernel *kernel);
......
...@@ -41,10 +41,10 @@ class RefPointer ...@@ -41,10 +41,10 @@ class RefPointer
return *this; return *this;
} }
RefPointer(RefPointer &&other) noexcept : mCLObject(nullptr) { other.swap(*this); } RefPointer(RefPointer &&other) noexcept : mCLObject(nullptr) { this->swap(other); }
RefPointer &operator=(RefPointer &&other) RefPointer &operator=(RefPointer &&other)
{ {
other.swap(this); this->swap(other);
return *this; return *this;
} }
...@@ -72,7 +72,6 @@ class RefPointer ...@@ -72,7 +72,6 @@ class RefPointer
T *operator->() const { return mCLObject; } T *operator->() const { return mCLObject; }
T &operator*() const { return *mCLObject; } T &operator*() const { return *mCLObject; }
bool isValid() const { return mCLObject != nullptr; }
T *get() const { return mCLObject; } T *get() const { return mCLObject; }
explicit operator bool() const { return mCLObject != nullptr; } explicit operator bool() const { return mCLObject != nullptr; }
...@@ -104,6 +103,30 @@ void swap(RefPointer<T> &left, RefPointer<T> &right) ...@@ -104,6 +103,30 @@ void swap(RefPointer<T> &left, RefPointer<T> &right)
left.swap(right); left.swap(right);
} }
template <typename T>
bool operator==(const RefPointer<T> &ptr, nullptr_t) noexcept
{
return ptr.get() == nullptr;
}
template <typename T>
bool operator==(nullptr_t, const RefPointer<T> &ptr) noexcept
{
return ptr.get() == nullptr;
}
template <typename T>
bool operator!=(const RefPointer<T> &ptr, nullptr_t) noexcept
{
return ptr.get() != nullptr;
}
template <typename T>
bool operator!=(nullptr_t, const RefPointer<T> &ptr) noexcept
{
return ptr.get() != nullptr;
}
} // namespace cl } // namespace cl
#endif // LIBANGLE_CLREFPOINTER_H_ #endif // LIBANGLE_CLREFPOINTER_H_
...@@ -49,17 +49,23 @@ using PlatformPtr = std::unique_ptr<Platform>; ...@@ -49,17 +49,23 @@ 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 ContextRefPtr = RefPointer<Context>; using CommandQueueRefPtr = RefPointer<CommandQueue>;
using DeviceRefPtr = RefPointer<Device>; using ContextRefPtr = RefPointer<Context>;
using MemoryRefPtr = RefPointer<Memory>; using DeviceRefPtr = RefPointer<Device>;
using ProgramRefPtr = RefPointer<Program>; using EventRefPtr = RefPointer<Event>;
using MemoryRefPtr = RefPointer<Memory>;
using ProgramRefPtr = RefPointer<Program>;
using DevicePtrList = std::list<DevicePtr>; using DevicePtrList = std::list<DevicePtr>;
using DeviceRefs = std::vector<DeviceRefPtr>;
using DeviceRefs = std::vector<DeviceRefPtr>;
using EventRefs = std::vector<EventRefPtr>;
using Binary = std::vector<unsigned char>; using Binary = std::vector<unsigned char>;
using Binaries = std::vector<Binary>; using Binaries = std::vector<Binary>;
using EventPredicate = std::function<bool(const EventPtr &)>;
struct ImageDescriptor struct ImageDescriptor
{ {
cl_mem_object_type type; cl_mem_object_type type;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "libANGLE/renderer/CLCommandQueueImpl.h" #include "libANGLE/renderer/CLCommandQueueImpl.h"
#include "libANGLE/renderer/CLDeviceImpl.h" #include "libANGLE/renderer/CLDeviceImpl.h"
#include "libANGLE/renderer/CLEventImpl.h"
#include "libANGLE/renderer/CLMemoryImpl.h" #include "libANGLE/renderer/CLMemoryImpl.h"
#include "libANGLE/renderer/CLProgramImpl.h" #include "libANGLE/renderer/CLProgramImpl.h"
#include "libANGLE/renderer/CLSamplerImpl.h" #include "libANGLE/renderer/CLSamplerImpl.h"
...@@ -61,6 +62,10 @@ class CLContextImpl : angle::NonCopyable ...@@ -61,6 +62,10 @@ class CLContextImpl : angle::NonCopyable
const char *kernel_names, const char *kernel_names,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
virtual CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) = 0;
virtual cl_int waitForEvents(const cl::EventRefs &events) = 0;
protected: protected:
const cl::Context &mContext; const cl::Context &mContext;
}; };
......
//
// 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.
//
// CLEventImpl.cpp: Implements the class methods for CLEventImpl.
#include "libANGLE/renderer/CLEventImpl.h"
namespace rx
{
CLEventImpl::CLEventImpl(const cl::Event &event) : mEvent(event) {}
CLEventImpl::~CLEventImpl() = 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.
//
// CLEventImpl.h: Defines the abstract rx::CLEventImpl class.
#ifndef LIBANGLE_RENDERER_CLEVENTIMPL_H_
#define LIBANGLE_RENDERER_CLEVENTIMPL_H_
#include "libANGLE/renderer/CLtypes.h"
namespace rx
{
class CLEventImpl : angle::NonCopyable
{
public:
using Ptr = std::unique_ptr<CLEventImpl>;
CLEventImpl(const cl::Event &event);
virtual ~CLEventImpl();
virtual cl_int getCommandExecutionStatus(cl_int &executionStatus) = 0;
virtual cl_int setUserEventStatus(cl_int executionStatus) = 0;
virtual cl_int setCallback(cl_int commandExecCallbackType) = 0;
protected:
const cl::Event &mEvent;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_CLEVENTIMPL_H_
...@@ -15,6 +15,8 @@ _cl_backend_sources = [ ...@@ -15,6 +15,8 @@ _cl_backend_sources = [
"CLContextCL.h", "CLContextCL.h",
"CLDeviceCL.cpp", "CLDeviceCL.cpp",
"CLDeviceCL.h", "CLDeviceCL.h",
"CLEventCL.cpp",
"CLEventCL.h",
"CLKernelCL.cpp", "CLKernelCL.cpp",
"CLKernelCL.h", "CLKernelCL.h",
"CLMemoryCL.cpp", "CLMemoryCL.cpp",
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/cl/CLCommandQueueCL.h" #include "libANGLE/renderer/cl/CLCommandQueueCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h" #include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/renderer/cl/CLEventCL.h"
#include "libANGLE/renderer/cl/CLMemoryCL.h" #include "libANGLE/renderer/cl/CLMemoryCL.h"
#include "libANGLE/renderer/cl/CLProgramCL.h" #include "libANGLE/renderer/cl/CLProgramCL.h"
#include "libANGLE/renderer/cl/CLSamplerCL.h" #include "libANGLE/renderer/cl/CLSamplerCL.h"
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
#include "libANGLE/CLCommandQueue.h" #include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h" #include "libANGLE/CLContext.h"
#include "libANGLE/CLDevice.h" #include "libANGLE/CLDevice.h"
#include "libANGLE/CLEvent.h"
#include "libANGLE/CLImage.h" #include "libANGLE/CLImage.h"
#include "libANGLE/CLMemory.h" #include "libANGLE/CLMemory.h"
#include "libANGLE/CLPlatform.h" #include "libANGLE/CLPlatform.h"
...@@ -270,4 +272,22 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithBuiltInKernels(const cl::Progra ...@@ -270,4 +272,22 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithBuiltInKernels(const cl::Progra
: nullptr); : nullptr);
} }
CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &errorCode)
{
const cl_event nativeEvent = mNative->getDispatch().clCreateUserEvent(mNative, &errorCode);
return CLEventImpl::Ptr(nativeEvent != nullptr ? new CLEventCL(event, nativeEvent) : nullptr);
}
cl_int CLContextCL::waitForEvents(const cl::EventRefs &events)
{
std::vector<cl_event> nativeEvents;
nativeEvents.reserve(events.size());
for (const cl::EventRefPtr &event : events)
{
nativeEvents.emplace_back(event->getImpl<CLEventCL>().getNative());
}
return mNative->getDispatch().clWaitForEvents(static_cast<cl_uint>(nativeEvents.size()),
nativeEvents.data());
}
} // namespace rx } // namespace rx
...@@ -57,6 +57,10 @@ class CLContextCL : public CLContextImpl ...@@ -57,6 +57,10 @@ class CLContextCL : public CLContextImpl
const char *kernel_names, const char *kernel_names,
cl_int &errorCode) override; cl_int &errorCode) override;
CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) override;
cl_int waitForEvents(const cl::EventRefs &events) override;
private: private:
const cl_context mNative; const cl_context mNative;
}; };
......
//
// 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.
//
// CLEventCL.cpp: Implements the class methods for CLEventCL.
#include "libANGLE/renderer/cl/CLEventCL.h"
#include "libANGLE/CLPlatform.h"
#include "libANGLE/Debug.h"
namespace rx
{
CLEventCL::CLEventCL(const cl::Event &event, cl_event native) : CLEventImpl(event), mNative(native)
{}
CLEventCL::~CLEventCL()
{
if (mNative->getDispatch().clReleaseEvent(mNative) != CL_SUCCESS)
{
ERR() << "Error while releasing CL event";
}
}
cl_int CLEventCL::getCommandExecutionStatus(cl_int &executionStatus)
{
return mNative->getDispatch().clGetEventInfo(mNative, CL_EVENT_COMMAND_EXECUTION_STATUS,
sizeof(executionStatus), &executionStatus,
nullptr);
}
cl_int CLEventCL::setUserEventStatus(cl_int executionStatus)
{
return mNative->getDispatch().clSetUserEventStatus(mNative, executionStatus);
}
cl_int CLEventCL::setCallback(cl_int commandExecCallbackType)
{
return mNative->getDispatch().clSetEventCallback(mNative, commandExecCallbackType, Callback,
nullptr);
}
void CLEventCL::Callback(cl_event event, cl_int commandStatus, void *userData)
{
const cl::EventRefPtr evt = cl::Platform::FindEvent(
[=](const cl::EventPtr &ptr) { return ptr->getImpl<CLEventCL>().getNative() == event; });
if (evt)
{
evt->callback(commandStatus);
}
else
{
WARN() << "Callback event not found";
}
}
} // 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.
//
// CLEventCL.h: Defines the class interface for CLEventCL, implementing CLEventImpl.
#ifndef LIBANGLE_RENDERER_CL_CLEVENTCL_H_
#define LIBANGLE_RENDERER_CL_CLEVENTCL_H_
#include "libANGLE/renderer/cl/cl_types.h"
#include "libANGLE/renderer/CLEventImpl.h"
namespace rx
{
class CLEventCL : public CLEventImpl
{
public:
CLEventCL(const cl::Event &event, cl_event native);
~CLEventCL() override;
cl_event getNative();
cl_int getCommandExecutionStatus(cl_int &executionStatus) override;
cl_int setUserEventStatus(cl_int executionStatus) override;
cl_int setCallback(cl_int commandExecCallbackType) override;
private:
static void CL_CALLBACK Callback(cl_event event, cl_int commandStatus, void *userData);
const cl_event mNative;
};
inline cl_event CLEventCL::getNative()
{
return mNative;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLEVENTCL_H_
...@@ -111,6 +111,8 @@ if (angle_enable_cl) { ...@@ -111,6 +111,8 @@ if (angle_enable_cl) {
"CLContextVk.h", "CLContextVk.h",
"CLDeviceVk.cpp", "CLDeviceVk.cpp",
"CLDeviceVk.h", "CLDeviceVk.h",
"CLEventVk.cpp",
"CLEventVk.h",
"CLKernelVk.cpp", "CLKernelVk.cpp",
"CLKernelVk.h", "CLKernelVk.h",
"CLMemoryVk.cpp", "CLMemoryVk.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.
//
// CLEventVk.cpp: Implements the class methods for CLEventVk.
#include "libANGLE/renderer/vulkan/CLEventVk.h"
namespace rx
{
CLEventVk::CLEventVk(const cl::Event &event) : CLEventImpl(event) {}
CLEventVk::~CLEventVk() = 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.
//
// CLEventVk.h: Defines the class interface for CLEventVk, implementing CLEventImpl.
#ifndef LIBANGLE_RENDERER_VULKAN_CLEVENTVK_H_
#define LIBANGLE_RENDERER_VULKAN_CLEVENTVK_H_
#include "libANGLE/renderer/vulkan/cl_types.h"
#include "libANGLE/renderer/CLEventImpl.h"
namespace rx
{
class CLEventVk : public CLEventImpl
{
public:
CLEventVk(const cl::Event &event);
~CLEventVk() override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_CLEVENTVK_H_
...@@ -1004,6 +1004,33 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel, ...@@ -1004,6 +1004,33 @@ cl_int ValidateGetKernelWorkGroupInfo(cl_kernel kernel,
cl_int ValidateWaitForEvents(cl_uint num_events, const cl_event *event_list) cl_int ValidateWaitForEvents(cl_uint num_events, const cl_event *event_list)
{ {
// CL_INVALID_VALUE if num_events is zero or event_list is NULL.
if (num_events == 0u || event_list == nullptr)
{
return CL_INVALID_VALUE;
}
const Context *context = nullptr;
while (num_events-- != 0u)
{
// CL_INVALID_EVENT if event objects specified in event_list are not valid event objects.
if (!Event::IsValid(*event_list))
{
return CL_INVALID_EVENT;
}
// CL_INVALID_CONTEXT if events specified in event_list do not belong to the same context.
const Context *eventContext = &static_cast<const Event *>(*event_list++)->getContext();
if (context == nullptr)
{
context = eventContext;
}
else if (context != eventContext)
{
return CL_INVALID_CONTEXT;
}
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1013,17 +1040,39 @@ cl_int ValidateGetEventInfo(cl_event event, ...@@ -1013,17 +1040,39 @@ cl_int ValidateGetEventInfo(cl_event event,
const void *param_value, const void *param_value,
const size_t *param_value_size_ret) const size_t *param_value_size_ret)
{ {
// CL_INVALID_EVENT if event is a not a valid event object.
if (!Event::IsValid(event))
{
return CL_INVALID_EVENT;
}
// CL_INVALID_VALUE if param_name is not valid.
const cl_version version =
static_cast<const Event *>(event)->getContext().getPlatform().getInfo().mVersion;
switch (param_name)
{
case EventInfo::Context:
ANGLE_VALIDATE_VERSION(1, 1);
break;
case EventInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
break;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
cl_int ValidateRetainEvent(cl_event event) cl_int ValidateRetainEvent(cl_event event)
{ {
return CL_SUCCESS; // CL_INVALID_EVENT if event is not a valid event object.
return Event::IsValid(event) ? CL_SUCCESS : CL_INVALID_EVENT;
} }
cl_int ValidateReleaseEvent(cl_event event) cl_int ValidateReleaseEvent(cl_event event)
{ {
return CL_SUCCESS; // CL_INVALID_EVENT if event is not a valid event object.
return Event::IsValid(event) ? CL_SUCCESS : CL_INVALID_EVENT;
} }
cl_int ValidateGetEventProfilingInfo(cl_event event, cl_int ValidateGetEventProfilingInfo(cl_event event,
...@@ -1443,11 +1492,36 @@ cl_int ValidateSetMemObjectDestructorCallback(cl_mem memobj, ...@@ -1443,11 +1492,36 @@ cl_int ValidateSetMemObjectDestructorCallback(cl_mem memobj,
cl_int ValidateCreateUserEvent(cl_context context) cl_int ValidateCreateUserEvent(cl_context context)
{ {
return CL_SUCCESS; // CL_INVALID_CONTEXT if context is not a valid context.
return Context::IsValidAndVersionOrNewer(context, 1u, 1u) ? CL_SUCCESS : CL_INVALID_CONTEXT;
} }
cl_int ValidateSetUserEventStatus(cl_event event, cl_int execution_status) cl_int ValidateSetUserEventStatus(cl_event event, cl_int execution_status)
{ {
// CL_INVALID_EVENT if event is not a valid user event object.
if (!Event::IsValidAndVersionOrNewer(event, 1u, 1u))
{
return CL_INVALID_EVENT;
}
const Event &evt = *static_cast<Event *>(event);
if (evt.getCommandType() != CL_COMMAND_USER)
{
return CL_INVALID_EVENT;
}
// CL_INVALID_VALUE if the execution_status is not CL_COMPLETE or a negative integer value.
if (execution_status != CL_COMPLETE && execution_status >= 0)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_OPERATION if the execution_status for event has already been changed
// by a previous call to clSetUserEventStatus.
if (evt.wasStatusChanged())
{
return CL_INVALID_OPERATION;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
...@@ -1458,6 +1532,21 @@ cl_int ValidateSetEventCallback(cl_event event, ...@@ -1458,6 +1532,21 @@ cl_int ValidateSetEventCallback(cl_event event,
void *user_data), void *user_data),
const void *user_data) const void *user_data)
{ {
// CL_INVALID_EVENT if event is not a valid event object.
if (!Event::IsValidAndVersionOrNewer(event, 1u, 1u))
{
return CL_INVALID_EVENT;
}
// CL_INVALID_VALUE if pfn_event_notify is NULL
// or if command_exec_callback_type is not CL_SUBMITTED, CL_RUNNING, or CL_COMPLETE.
if (pfn_notify == nullptr ||
(command_exec_callback_type != CL_SUBMITTED && command_exec_callback_type != CL_RUNNING &&
command_exec_callback_type != CL_COMPLETE))
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS; return CL_SUCCESS;
} }
......
...@@ -472,6 +472,7 @@ libangle_cl_headers = [ ...@@ -472,6 +472,7 @@ libangle_cl_headers = [
"src/libANGLE/renderer/CLCommandQueueImpl.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/CLEventImpl.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",
...@@ -499,6 +500,7 @@ libangle_cl_sources = [ ...@@ -499,6 +500,7 @@ libangle_cl_sources = [
"src/libANGLE/renderer/CLCommandQueueImpl.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/CLEventImpl.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",
......
...@@ -601,8 +601,7 @@ cl_int GetKernelSubGroupInfo(cl_kernel kernel, ...@@ -601,8 +601,7 @@ cl_int GetKernelSubGroupInfo(cl_kernel kernel,
cl_int WaitForEvents(cl_uint num_events, const cl_event *event_list) cl_int WaitForEvents(cl_uint num_events, const cl_event *event_list)
{ {
WARN_NOT_SUPPORTED(WaitForEvents); return static_cast<Event *>(*event_list)->getContext().waitForEvents(num_events, event_list);
return 0;
} }
cl_int GetEventInfo(cl_event event, cl_int GetEventInfo(cl_event event,
...@@ -611,32 +610,30 @@ cl_int GetEventInfo(cl_event event, ...@@ -611,32 +610,30 @@ cl_int GetEventInfo(cl_event event,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetEventInfo); return static_cast<Event *>(event)->getInfo(param_name, param_value_size, param_value,
return 0; param_value_size_ret);
} }
cl_event CreateUserEvent(cl_context context, cl_int &errorCode) cl_event CreateUserEvent(cl_context context, cl_int &errorCode)
{ {
WARN_NOT_SUPPORTED(CreateUserEvent); return static_cast<Context *>(context)->createUserEvent(errorCode);
return 0;
} }
cl_int RetainEvent(cl_event event) cl_int RetainEvent(cl_event event)
{ {
WARN_NOT_SUPPORTED(RetainEvent); static_cast<Event *>(event)->retain();
return 0; return CL_SUCCESS;
} }
cl_int ReleaseEvent(cl_event event) cl_int ReleaseEvent(cl_event event)
{ {
WARN_NOT_SUPPORTED(ReleaseEvent); static_cast<Event *>(event)->release();
return 0; return CL_SUCCESS;
} }
cl_int SetUserEventStatus(cl_event event, cl_int execution_status) cl_int SetUserEventStatus(cl_event event, cl_int execution_status)
{ {
WARN_NOT_SUPPORTED(SetUserEventStatus); return static_cast<Event *>(event)->setUserEventStatus(execution_status);
return 0;
} }
cl_int SetEventCallback(cl_event event, cl_int SetEventCallback(cl_event event,
...@@ -646,8 +643,8 @@ cl_int SetEventCallback(cl_event event, ...@@ -646,8 +643,8 @@ cl_int SetEventCallback(cl_event event,
void *user_data), void *user_data),
void *user_data) void *user_data)
{ {
WARN_NOT_SUPPORTED(SetEventCallback); return static_cast<Event *>(event)->setCallback(command_exec_callback_type, pfn_notify,
return 0; user_data);
} }
cl_int GetEventProfilingInfo(cl_event event, cl_int GetEventProfilingInfo(cl_event event,
......
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