aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Annestrand <a.annestrand@samsung.com>2024-03-28 18:05:00 -0500
committerAngle LUCI CQ <angle-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-04-18 22:16:15 +0000
commitcc770518b07ce9ef45cd1c283e9f69b3711d304e (patch)
treecb4c12da9cd5b777b63f94b18d943841f766b1b0
parentc75b03ad1ca99d11cf0adf1efe5188a55acaa7cf (diff)
downloadangle-cc770518b07ce9ef45cd1c283e9f69b3711d304e.tar.gz
CL/VK: Implement flush & finish
Bug: angleproject:8632 Change-Id: I139e463c0b1c947cee68e65c40503e52f01e988b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5406615 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Austin Annestrand <a.annestrand@samsung.com> Reviewed-by: Geoff Lang <geofflang@chromium.org>
-rw-r--r--src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp140
-rw-r--r--src/libANGLE/renderer/vulkan/CLCommandQueueVk.h3
2 files changed, 132 insertions, 11 deletions
diff --git a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
index 33f0de41f4..f461da52f3 100644
--- a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
+++ b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
@@ -26,12 +26,31 @@
namespace rx
{
+class CLAsyncFinishTask : public angle::Closure
+{
+ public:
+ CLAsyncFinishTask(CLCommandQueueVk *queueVk) : mQueueVk(queueVk) {}
+
+ void operator()() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "CLCommandQueueVk::finish (async)");
+ if (IsError(mQueueVk->finish()))
+ {
+ ERR() << "Async finish (clFlush) failed for queue (" << mQueueVk << ")!";
+ }
+ }
+
+ private:
+ CLCommandQueueVk *mQueueVk;
+};
+
CLCommandQueueVk::CLCommandQueueVk(const cl::CommandQueue &commandQueue)
: CLCommandQueueImpl(commandQueue),
mContext(&commandQueue.getContext().getImpl<CLContextVk>()),
mDevice(&commandQueue.getDevice().getImpl<CLDeviceVk>()),
mComputePassCommands(nullptr),
- mCurrentQueueSerialIndex(kInvalidQueueSerialIndex)
+ mCurrentQueueSerialIndex(kInvalidQueueSerialIndex),
+ mHasAnyCommandsPendingSubmission(false)
{}
angle::Result CLCommandQueueVk::init()
@@ -391,14 +410,26 @@ angle::Result CLCommandQueueVk::enqueueBarrier()
angle::Result CLCommandQueueVk::flush()
{
- UNIMPLEMENTED();
- ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
+ ANGLE_TRACE_EVENT0("gpu.angle", "CLCommandQueueVk::flush");
+
+ // Non-blocking finish
+ // TODO: Ideally we should try to find better impl. to avoid spawning a submit-thread/Task here
+ // https://anglebug.com/8669
+ std::shared_ptr<angle::WaitableEvent> asyncEvent =
+ getPlatform()->postMultiThreadWorkerTask(std::make_shared<CLAsyncFinishTask>(this));
+ ASSERT(asyncEvent != nullptr);
+
+ return angle::Result::Continue;
}
angle::Result CLCommandQueueVk::finish()
{
- UNIMPLEMENTED();
- ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
+ std::scoped_lock<std::mutex> sl(mCommandQueueMutex);
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "CLCommandQueueVk::finish");
+
+ // Blocking finish
+ return finishInternal();
}
angle::Result CLCommandQueueVk::processKernelResources(CLKernelVk &kernelVk,
@@ -527,8 +558,22 @@ angle::Result CLCommandQueueVk::processKernelResources(CLKernelVk &kernelVk,
angle::Result CLCommandQueueVk::flushComputePassCommands()
{
- UNIMPLEMENTED();
- ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
+ mLastFlushedQueueSerial = mComputePassCommands->getQueueSerial();
+
+ // Here, we flush our compute cmds to RendererVk's primary command buffer
+ ANGLE_TRY(mContext->getRenderer()->flushOutsideRPCommands(
+ mContext, getProtectionType(), egl::ContextPriority::Medium, &mComputePassCommands));
+
+ mHasAnyCommandsPendingSubmission = true;
+
+ mContext->getPerfCounters().flushedOutsideRenderPassCommandBuffers++;
+
+ // Generate new serial for next batch of cmds
+ mComputePassCommands->setQueueSerial(
+ mCurrentQueueSerialIndex,
+ mContext->getRenderer()->generateQueueSerial(mCurrentQueueSerialIndex));
+
+ return angle::Result::Continue;
}
angle::Result CLCommandQueueVk::processWaitlist(const cl::EventPtrs &waitEvents)
@@ -567,8 +612,22 @@ angle::Result CLCommandQueueVk::processWaitlist(const cl::EventPtrs &waitEvents)
angle::Result CLCommandQueueVk::submitCommands()
{
- UNIMPLEMENTED();
- ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
+ ANGLE_TRACE_EVENT0("gpu.angle", "CLCommandQueueVk::submitCommands()");
+
+ // Kick off renderer submit
+ ANGLE_TRY(mContext->getRenderer()->submitCommands(mContext, getProtectionType(),
+ egl::ContextPriority::Medium, nullptr,
+ nullptr, mLastFlushedQueueSerial));
+
+ mLastSubmittedQueueSerial = mLastFlushedQueueSerial;
+
+ // Now that we have submitted commands, some of pending garbage may no longer pending
+ // and should be moved to garbage list.
+ mContext->getRenderer()->cleanupPendingSubmissionGarbage();
+
+ mHasAnyCommandsPendingSubmission = false;
+
+ return angle::Result::Continue;
}
angle::Result CLCommandQueueVk::createEvent(CLEventImpl::CreateFunc *createFunc)
@@ -596,8 +655,67 @@ angle::Result CLCommandQueueVk::createEvent(CLEventImpl::CreateFunc *createFunc)
angle::Result CLCommandQueueVk::finishInternal()
{
- UNIMPLEMENTED();
- ANGLE_CL_RETURN_ERROR(CL_OUT_OF_RESOURCES);
+ for (cl::EventPtr event : mAssociatedEvents)
+ {
+ ANGLE_TRY(event->getImpl<CLEventVk>().setStatusAndExecuteCallback(CL_SUBMITTED));
+ }
+
+ if (!mComputePassCommands->empty())
+ {
+ // If we still have dependant events, handle them now
+ if (!mDependantEvents.empty())
+ {
+ for (const auto &depEvent : mDependantEvents)
+ {
+ if (depEvent->getImpl<CLEventVk>().isUserEvent())
+ {
+ // We just wait here for user to set the event object
+ cl_int status = CL_QUEUED;
+ ANGLE_TRY(depEvent->getImpl<CLEventVk>().waitForUserEventStatus());
+ ANGLE_TRY(depEvent->getImpl<CLEventVk>().getCommandExecutionStatus(status));
+ if (status < 0)
+ {
+ ERR() << "Invalid dependant user-event (" << depEvent.get()
+ << ") status encountered!";
+ mComputePassCommands->getCommandBuffer().reset();
+ ANGLE_CL_RETURN_ERROR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
+ }
+ }
+ else
+ {
+ // Otherwise, we just need to submit/finish for dependant event queues
+ // here that are not associated with this queue
+ ANGLE_TRY(depEvent->getCommandQueue()->finish());
+ }
+ }
+ mDependantEvents.clear();
+ }
+
+ ANGLE_TRY(flushComputePassCommands());
+ }
+
+ for (cl::EventPtr event : mAssociatedEvents)
+ {
+ ANGLE_TRY(event->getImpl<CLEventVk>().setStatusAndExecuteCallback(CL_RUNNING));
+ }
+
+ if (mHasAnyCommandsPendingSubmission)
+ {
+ // Submit and wait for fence
+ ANGLE_TRY(submitCommands());
+ ANGLE_TRY(mContext->getRenderer()->finishQueueSerial(mContext, mLastSubmittedQueueSerial));
+ }
+
+ for (cl::EventPtr event : mAssociatedEvents)
+ {
+ ANGLE_TRY(event->getImpl<CLEventVk>().setStatusAndExecuteCallback(CL_COMPLETE));
+ }
+
+ mMemoryCaptures.clear();
+ mAssociatedEvents.clear();
+ mDependencyTracker.clear();
+
+ return angle::Result::Continue;
}
} // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.h b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.h
index 0238a98545..44a387b278 100644
--- a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.h
+++ b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.h
@@ -261,6 +261,9 @@ class CLCommandQueueVk : public CLCommandQueueImpl
// Resource reference capturing during execution
cl::MemoryPtrs mMemoryCaptures;
+
+ // Check to see if flush/finish can be skipped
+ bool mHasAnyCommandsPendingSubmission;
};
} // namespace rx