1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLEvent.cpp: Implements the cl::Event class.
7
8 #include "libANGLE/CLEvent.h"
9
10 #include "libANGLE/CLCommandQueue.h"
11 #include "libANGLE/CLContext.h"
12
13 #include <cstring>
14
15 namespace cl
16 {
17
setUserEventStatus(cl_int executionStatus)18 cl_int Event::setUserEventStatus(cl_int executionStatus)
19 {
20 const cl_int errorCode = mImpl->setUserEventStatus(executionStatus);
21 if (errorCode == CL_SUCCESS)
22 {
23 mStatusWasChanged = true;
24 }
25 return errorCode;
26 }
27
getInfo(EventInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const28 cl_int Event::getInfo(EventInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
29 {
30 cl_int execStatus = 0;
31 cl_uint valUInt = 0u;
32 void *valPointer = nullptr;
33 const void *copyValue = nullptr;
34 size_t copySize = 0u;
35
36 switch (name)
37 {
38 case EventInfo::CommandQueue:
39 valPointer = CommandQueue::CastNative(mCommandQueue.get());
40 copyValue = &valPointer;
41 copySize = sizeof(valPointer);
42 break;
43 case EventInfo::CommandType:
44 copyValue = &mCommandType;
45 copySize = sizeof(mCommandType);
46 break;
47 case EventInfo::ReferenceCount:
48 valUInt = getRefCount();
49 copyValue = &valUInt;
50 copySize = sizeof(valUInt);
51 break;
52 case EventInfo::CommandExecutionStatus:
53 {
54 const cl_int errorCode = mImpl->getCommandExecutionStatus(execStatus);
55 if (errorCode != CL_SUCCESS)
56 {
57 return errorCode;
58 }
59 copyValue = &execStatus;
60 copySize = sizeof(execStatus);
61 break;
62 }
63 case EventInfo::Context:
64 valPointer = mContext->getNative();
65 copyValue = &valPointer;
66 copySize = sizeof(valPointer);
67 break;
68 default:
69 return CL_INVALID_VALUE;
70 }
71
72 if (value != nullptr)
73 {
74 // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
75 // as described in the Event Queries table and param_value is not NULL.
76 if (valueSize < copySize)
77 {
78 return CL_INVALID_VALUE;
79 }
80 if (copyValue != nullptr)
81 {
82 std::memcpy(value, copyValue, copySize);
83 }
84 }
85 if (valueSizeRet != nullptr)
86 {
87 *valueSizeRet = copySize;
88 }
89 return CL_SUCCESS;
90 }
91
setCallback(cl_int commandExecCallbackType,EventCB pfnNotify,void * userData)92 cl_int Event::setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData)
93 {
94 auto callbacks = mCallbacks.synchronize();
95 // Only when required register a single callback with the back end for each callback type.
96 if ((*callbacks)[commandExecCallbackType].empty())
97 {
98 ANGLE_CL_TRY(mImpl->setCallback(*this, commandExecCallbackType));
99 // This event has to be retained until the callback is called.
100 retain();
101 }
102 (*callbacks)[commandExecCallbackType].emplace_back(pfnNotify, userData);
103 return CL_SUCCESS;
104 }
105
getProfilingInfo(ProfilingInfo name,size_t valueSize,void * value,size_t * valueSizeRet)106 cl_int Event::getProfilingInfo(ProfilingInfo name,
107 size_t valueSize,
108 void *value,
109 size_t *valueSizeRet)
110 {
111 return mImpl->getProfilingInfo(name, valueSize, value, valueSizeRet);
112 }
113
114 Event::~Event() = default;
115
callback(cl_int commandStatus)116 void Event::callback(cl_int commandStatus)
117 {
118 ASSERT(commandStatus >= 0 && commandStatus < 3);
119 const Callbacks callbacks = std::move(mCallbacks->at(commandStatus));
120 for (const CallbackData &data : callbacks)
121 {
122 data.first(this, commandStatus, data.second);
123 }
124 // This event can be released after the callback was called.
125 if (release())
126 {
127 delete this;
128 }
129 }
130
Cast(cl_uint numEvents,const cl_event * eventList)131 EventPtrs Event::Cast(cl_uint numEvents, const cl_event *eventList)
132 {
133 EventPtrs events;
134 events.reserve(numEvents);
135 while (numEvents-- != 0u)
136 {
137 events.emplace_back(&(*eventList++)->cast<Event>());
138 }
139 return events;
140 }
141
Event(Context & context,cl_int & errorCode)142 Event::Event(Context &context, cl_int &errorCode)
143 : mContext(&context),
144 mCommandType(CL_COMMAND_USER),
145 mImpl(context.getImpl().createUserEvent(*this, errorCode))
146 {}
147
Event(CommandQueue & queue,cl_command_type commandType,const rx::CLEventImpl::CreateFunc & createFunc,cl_int & errorCode)148 Event::Event(CommandQueue &queue,
149 cl_command_type commandType,
150 const rx::CLEventImpl::CreateFunc &createFunc,
151 cl_int &errorCode)
152 : mContext(&queue.getContext()),
153 mCommandQueue(&queue),
154 mCommandType(commandType),
155 mImpl(createFunc(*this))
156 {}
157
158 } // namespace cl
159