Commit 1fcbf77c by Ian Elliott Committed by Angle LUCI CQ

Vulkan: Fix AGI hierarchy for query commands

Treat glBeginQuery* and glEndQuery* commands the same as glDraw* commands, generating a hierarchy. This results in vkCmdBeginQuery and vkCmdEndQuery commands being nested under gl*Query*, instead of being a peer of glDraw* commands. This change necessitated plumbing some of the existing "end" path to return angle::Result. Bug: b/190512191 Change-Id: I898d3fdd9b4b7d86e76dfae2ffc5d6f7316a55ef Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2950926Reviewed-by: 's avatarMark Lobodzinski <mark@lunarg.com> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 29227eef
......@@ -440,6 +440,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mEmulateSeamfulCubeMapSampling(false),
mOutsideRenderPassCommands(nullptr),
mRenderPassCommands(nullptr),
mQueryEventType(QueryEventCmdBuf::NotInQueryCmd),
mGpuEventsEnabled(false),
mEGLSyncObjectPendingFlush(false),
mHasDeferredFlush(false),
......@@ -3039,6 +3040,33 @@ void ContextVk::endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineT
mOutsideRenderPassCommands->getCommandBuffer().endDebugUtilsLabelEXT();
}
}
void ContextVk::endEventLogForQuery()
{
ASSERT(mQueryEventType == QueryEventCmdBuf::InOutsideCmdBufQueryCmd ||
mQueryEventType == QueryEventCmdBuf::InRenderPassCmdBufQueryCmd);
if (!mRenderer->angleDebuggerMode())
{
return;
}
vk::CommandBuffer *commandBuffer = nullptr;
switch (mQueryEventType)
{
case QueryEventCmdBuf::InOutsideCmdBufQueryCmd:
ASSERT(mOutsideRenderPassCommands);
commandBuffer = &mOutsideRenderPassCommands->getCommandBuffer();
break;
case QueryEventCmdBuf::InRenderPassCmdBufQueryCmd:
ASSERT(mRenderPassCommands);
commandBuffer = &mRenderPassCommands->getCommandBuffer();
break;
default:
UNREACHABLE();
}
commandBuffer->endDebugUtilsLabelEXT();
mQueryEventType = QueryEventCmdBuf::NotInQueryCmd;
}
angle::Result ContextVk::handleNoopDrawEvent()
{
......@@ -3051,6 +3079,33 @@ angle::Result ContextVk::handleMidRenderPassClearEvent()
return handleDirtyEventLogImpl(mRenderPassCommandBuffer);
}
angle::Result ContextVk::handleQueryEvent(QueryEventCmdBuf queryEventType)
{
ASSERT(mQueryEventType == QueryEventCmdBuf::NotInQueryCmd);
if (!mRenderer->angleDebuggerMode())
{
return angle::Result::Continue;
}
mQueryEventType = queryEventType;
vk::CommandBuffer *commandBuffer = nullptr;
switch (mQueryEventType)
{
case QueryEventCmdBuf::InOutsideCmdBufQueryCmd:
ASSERT(mOutsideRenderPassCommands);
commandBuffer = &mOutsideRenderPassCommands->getCommandBuffer();
break;
case QueryEventCmdBuf::InRenderPassCmdBufQueryCmd:
ASSERT(mRenderPassCommands);
commandBuffer = &mRenderPassCommands->getCommandBuffer();
break;
default:
UNREACHABLE();
}
return handleDirtyEventLogImpl(commandBuffer);
}
bool ContextVk::isViewportFlipEnabledForDrawFBO() const
{
return mFlipViewportForDrawFramebuffer && mFlipYForCurrentSurface;
......@@ -5642,6 +5697,9 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
angle::Result ContextVk::beginRenderPassQuery(QueryVk *queryVk)
{
// Emit debug-util markers before calling the query command.
ANGLE_TRY(handleQueryEvent(rx::QueryEventCmdBuf::InRenderPassCmdBufQueryCmd));
// To avoid complexity, we always start and end these queries inside the render pass. If the
// render pass has not yet started, the query is deferred until it does.
if (mRenderPassCommandBuffer)
......@@ -5657,8 +5715,11 @@ angle::Result ContextVk::beginRenderPassQuery(QueryVk *queryVk)
return angle::Result::Continue;
}
void ContextVk::endRenderPassQuery(QueryVk *queryVk)
angle::Result ContextVk::endRenderPassQuery(QueryVk *queryVk)
{
// Emit debug-util markers before calling the query command.
ANGLE_TRY(handleQueryEvent(rx::QueryEventCmdBuf::InRenderPassCmdBufQueryCmd));
if (mRenderPassCommandBuffer)
{
queryVk->getQueryHelper()->endRenderPassQuery(this);
......@@ -5668,6 +5729,8 @@ void ContextVk::endRenderPassQuery(QueryVk *queryVk)
ASSERT(mActiveRenderPassQueries[type] == queryVk);
mActiveRenderPassQueries[type] = nullptr;
return angle::Result::Continue;
}
void ContextVk::pauseRenderPassQueriesIfActive()
......
......@@ -53,6 +53,16 @@ struct ContextVkPerfCounters
ContextVkDescriptorSetList descriptorSetsAllocated;
};
enum class QueryEventCmdBuf
{
NotInQueryCmd = 0,
InOutsideCmdBufQueryCmd = 1,
InRenderPassCmdBufQueryCmd = 2,
InvalidEnum = 3,
EnumCount = 3,
};
class ContextVk : public ContextImpl, public vk::Context, public MultisampleTextureInitializer
{
public:
......@@ -209,6 +219,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
// Record GL API calls for debuggers
void logEvent(const char *eventString);
void endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineType);
void endEventLogForQuery();
bool isViewportFlipEnabledForDrawFBO() const;
bool isViewportFlipEnabledForReadFBO() const;
......@@ -573,7 +584,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
// Queries that begin and end automatically with render pass start and end
angle::Result beginRenderPassQuery(QueryVk *queryVk);
void endRenderPassQuery(QueryVk *queryVk);
angle::Result endRenderPassQuery(QueryVk *queryVk);
void pauseRenderPassQueriesIfActive();
angle::Result resumeRenderPassQueriesIfActive();
......@@ -617,6 +628,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
void onProgramExecutableReset(ProgramExecutableVk *executableVk);
angle::Result handleMidRenderPassClearEvent();
angle::Result handleQueryEvent(QueryEventCmdBuf queryEventType);
private:
// Dirty bits.
......@@ -1060,6 +1072,17 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
vk::CommandBufferHelper *mOutsideRenderPassCommands;
vk::CommandBufferHelper *mRenderPassCommands;
// The following is used when creating debug-util markers for graphics debuggers (e.g. AGI). A
// given gl{Begin|End}Query command may result in commands being submitted to the outside or
// render-pass command buffer. The ContextVk::handleQueryEvent() method records the
// appropriate command buffer for use by ContextVk::endEventLogForQuery(). The knowledge of
// which command buffer to use depends on the particular type of query (e.g. samples
// vs. timestamp), and is only known by the query code, which is what calls
// ContextVk::handleQueryEvent(). After all back-end processing of the gl*Query command is
// complete, the front-end calls ContextVk::endEventLogForQuery(), which needs to know which
// command buffer to call endDebugUtilsLabelEXT() for.
QueryEventCmdBuf mQueryEventType;
// Transform feedback buffers.
angle::FastUnorderedSet<const vk::BufferHelper *,
gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>
......
......@@ -48,6 +48,10 @@ void DebugAnnotatorVk::endEvent(gl::Context *context,
{
contextVk->endEventLog(entryPoint, PipelineType::Compute);
}
else if (isQueryEntryPoint(entryPoint))
{
contextVk->endEventLogForQuery();
}
}
}
......@@ -121,4 +125,20 @@ bool DebugAnnotatorVk::isDispatchEntryPoint(angle::EntryPoint entryPoint) const
}
}
bool DebugAnnotatorVk::isQueryEntryPoint(angle::EntryPoint entryPoint) const
{
switch (entryPoint)
{
case angle::EntryPoint::GLBeginQuery:
case angle::EntryPoint::GLBeginQueryEXT:
case angle::EntryPoint::GLBeginQueryIndexed:
case angle::EntryPoint::GLEndQuery:
case angle::EntryPoint::GLEndQueryEXT:
case angle::EntryPoint::GLEndQueryIndexed:
return true;
default:
return false;
}
}
} // namespace rx
......@@ -31,6 +31,7 @@ class DebugAnnotatorVk : public angle::LoggingAnnotator
private:
bool isDrawOrClearEntryPoint(angle::EntryPoint entryPoint) const;
bool isDispatchEntryPoint(angle::EntryPoint entryPoint) const;
bool isQueryEntryPoint(angle::EntryPoint entryPoint) const;
// Note: To avoid any race conditions between threads, this class has no private data; all
// events are stored in ContextVk.
......
......@@ -353,7 +353,7 @@ angle::Result QueryVk::end(const gl::Context *context)
QueryVk *shareQuery = GetShareQuery(contextVk, mType);
ASSERT(shareQuery == nullptr || &mQueryHelper.get() == &shareQuery->mQueryHelper.get());
contextVk->endRenderPassQuery(this);
ANGLE_TRY(contextVk->endRenderPassQuery(this));
// If another query shares its query helper with this one, its query has just ended!
// Make it stash its query and create a new one so it can continue.
......
......@@ -2800,6 +2800,8 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
ANGLE_TRY(contextVk->handleQueryEvent(rx::QueryEventCmdBuf::InOutsideCmdBufQueryCmd));
beginQueryImpl(contextVk, commandBuffer, commandBuffer);
return angle::Result::Continue;
......@@ -2815,6 +2817,8 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk)
CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
ANGLE_TRY(contextVk->handleQueryEvent(rx::QueryEventCmdBuf::InOutsideCmdBufQueryCmd));
endQueryImpl(contextVk, commandBuffer);
return angle::Result::Continue;
......
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