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 // CLEventVk.cpp: Implements the class methods for CLEventVk.
7
8 #include "libANGLE/renderer/vulkan/CLEventVk.h"
9 #include "libANGLE/renderer/vulkan/CLCommandQueueVk.h"
10
11 #include "libANGLE/cl_utils.h"
12
13 namespace rx
14 {
15
CLEventVk(const cl::Event & event)16 CLEventVk::CLEventVk(const cl::Event &event)
17 : CLEventImpl(event), mStatus(isUserEvent() ? CL_SUBMITTED : CL_QUEUED)
18 {}
19
~CLEventVk()20 CLEventVk::~CLEventVk() {}
21
getCommandExecutionStatus(cl_int & executionStatus)22 angle::Result CLEventVk::getCommandExecutionStatus(cl_int &executionStatus)
23 {
24 executionStatus = *mStatus;
25 return angle::Result::Continue;
26 }
27
setUserEventStatus(cl_int executionStatus)28 angle::Result CLEventVk::setUserEventStatus(cl_int executionStatus)
29 {
30 ASSERT(isUserEvent());
31
32 // Not much to do here other than storing the user supplied state.
33 // Error checking and single call enforcement is responsibility of the front end.
34 ANGLE_TRY(setStatusAndExecuteCallback(executionStatus));
35
36 // User event set and callback(s) finished - notify those waiting
37 mUserEventCondition.notify_all();
38
39 return angle::Result::Continue;
40 }
41
setCallback(cl::Event & event,cl_int commandExecCallbackType)42 angle::Result CLEventVk::setCallback(cl::Event &event, cl_int commandExecCallbackType)
43 {
44 ASSERT(commandExecCallbackType >= CL_COMPLETE);
45 ASSERT(commandExecCallbackType < CL_QUEUED);
46
47 // Not much to do, acknowledge the presence of callback and returns
48 mHaveCallbacks->at(commandExecCallbackType) = true;
49
50 return angle::Result::Continue;
51 }
52
getProfilingInfo(cl::ProfilingInfo name,size_t valueSize,void * value,size_t * valueSizeRet)53 angle::Result CLEventVk::getProfilingInfo(cl::ProfilingInfo name,
54 size_t valueSize,
55 void *value,
56 size_t *valueSizeRet)
57 {
58 UNIMPLEMENTED();
59 ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
60 }
61
waitForUserEventStatus()62 angle::Result CLEventVk::waitForUserEventStatus()
63 {
64 ASSERT(isUserEvent());
65
66 cl_int status = CL_QUEUED;
67 std::unique_lock<std::mutex> ul(mUserEventMutex);
68 ANGLE_TRY(getCommandExecutionStatus(status));
69 if (status > CL_COMPLETE)
70 {
71 // User is responsible for setting the user-event object, we need to wait for that event
72 // (We dont care what the outcome is, just need to wait until that event triggers)
73 INFO() << "Waiting for user-event (" << &mEvent
74 << ") to be set! (aka clSetUserEventStatus)";
75 mUserEventCondition.wait(ul);
76 }
77
78 return angle::Result::Continue;
79 }
80
setStatusAndExecuteCallback(cl_int status)81 angle::Result CLEventVk::setStatusAndExecuteCallback(cl_int status)
82 {
83 *mStatus = status;
84
85 if (status >= CL_COMPLETE && status < CL_QUEUED && mHaveCallbacks->at(status))
86 {
87 auto haveCallbacks = mHaveCallbacks.synchronize();
88
89 // Sanity check, callback(s) only from this exec status should be outstanding
90 ASSERT(std::count(haveCallbacks->begin() + status, haveCallbacks->end(), true) == 1);
91
92 getFrontendObject().callback(status);
93 haveCallbacks->at(status) = false;
94 }
95
96 return angle::Result::Continue;
97 }
98
99 } // namespace rx
100