Commit 2c8bc1b7 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Clean up render pass query code

In preparation for support of primitives generated queries. Bug: angleproject:5404 Change-Id: Ic123aaff33f8903994ff8fcc9158954ac023ec13 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2562126 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com>
parent dfdf90a7
...@@ -39,20 +39,8 @@ class QueryImpl : angle::NonCopyable ...@@ -39,20 +39,8 @@ class QueryImpl : angle::NonCopyable
gl::QueryType getType() const { return mType; } gl::QueryType getType() const { return mType; }
// Convenience functions
bool isOcclusionQuery() const { return isAnySamplesQuery() || isAnySamplesConservativeQuery(); }
bool isAnySamplesQuery() const { return mType == gl::QueryType::AnySamples; }
bool isAnySamplesConservativeQuery() const
{
return mType == gl::QueryType::AnySamplesConservative;
}
bool isTransformFeedbackQuery() const
{
return mType == gl::QueryType::TransformFeedbackPrimitivesWritten;
}
protected: protected:
const gl::QueryType mType; gl::QueryType mType;
}; };
} // namespace rx } // namespace rx
......
...@@ -364,7 +364,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -364,7 +364,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mCurrentWindowSurface(nullptr), mCurrentWindowSurface(nullptr),
mCurrentRotationDrawFramebuffer(SurfaceRotation::Identity), mCurrentRotationDrawFramebuffer(SurfaceRotation::Identity),
mCurrentRotationReadFramebuffer(SurfaceRotation::Identity), mCurrentRotationReadFramebuffer(SurfaceRotation::Identity),
mRenderPassQueries{}, mActiveRenderPassQueries{},
mVertexArray(nullptr), mVertexArray(nullptr),
mDrawFramebuffer(nullptr), mDrawFramebuffer(nullptr),
mProgram(nullptr), mProgram(nullptr),
...@@ -4515,7 +4515,7 @@ angle::Result ContextVk::startRenderPass(gl::Rectangle renderArea, ...@@ -4515,7 +4515,7 @@ angle::Result ContextVk::startRenderPass(gl::Rectangle renderArea,
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, renderArea, &mRenderPassCommandBuffer)); ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, renderArea, &mRenderPassCommandBuffer));
resumeRenderPassQueryIfActive(); ANGLE_TRY(resumeRenderPassQueriesIfActive());
const gl::DepthStencilState &dsState = mState.getDepthStencilState(); const gl::DepthStencilState &dsState = mState.getDepthStencilState();
vk::ResourceAccess depthAccess = GetDepthAccess(dsState); vk::ResourceAccess depthAccess = GetDepthAccess(dsState);
...@@ -4582,7 +4582,7 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass() ...@@ -4582,7 +4582,7 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass()
return angle::Result::Continue; return angle::Result::Continue;
} }
ANGLE_TRY(pauseRenderPassQueryIfActive()); ANGLE_TRY(pauseRenderPassQueriesIfActive());
mCurrentTransformFeedbackBuffers.clear(); mCurrentTransformFeedbackBuffers.clear();
mCurrentIndirectBuffer = nullptr; mCurrentIndirectBuffer = nullptr;
...@@ -4739,40 +4739,48 @@ angle::Result ContextVk::flushOutsideRenderPassCommands() ...@@ -4739,40 +4739,48 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
return angle::Result::Continue; return angle::Result::Continue;
} }
void ContextVk::beginRenderPassQuery(QueryVk *queryVk) angle::Result ContextVk::beginRenderPassQuery(QueryVk *queryVk)
{ {
// To avoid complexity, we always start and end occlusion query inside renderpass. if renderpass // To avoid complexity, we always start and end these queries inside the render pass. If the
// not yet started, we just remember it and defer the start call. // render pass has not yet started, the query is deferred until it does.
if (mRenderPassCommands->started()) if (mRenderPassCommandBuffer)
{ {
queryVk->getQueryHelper()->beginRenderPassQuery(this, mRenderPassCommandBuffer); ANGLE_TRY(queryVk->getQueryHelper()->beginRenderPassQuery(this));
} }
mRenderPassQueries[queryVk->getType()] = queryVk; gl::QueryType type = queryVk->getType();
ASSERT(mActiveRenderPassQueries[type] == nullptr);
mActiveRenderPassQueries[type] = queryVk;
return angle::Result::Continue;
} }
void ContextVk::endRenderPassQuery(QueryVk *queryVk) void ContextVk::endRenderPassQuery(QueryVk *queryVk)
{ {
if (mRenderPassCommands->started() && mRenderPassCommandBuffer) if (mRenderPassCommandBuffer)
{ {
queryVk->getQueryHelper()->endRenderPassQuery(this, mRenderPassCommandBuffer); queryVk->getQueryHelper()->endRenderPassQuery(this);
} }
mRenderPassQueries[queryVk->getType()] = nullptr; gl::QueryType type = queryVk->getType();
ASSERT(mActiveRenderPassQueries[type] == queryVk);
mActiveRenderPassQueries[type] = nullptr;
} }
angle::Result ContextVk::pauseRenderPassQueryIfActive() angle::Result ContextVk::pauseRenderPassQueriesIfActive()
{ {
if (mRenderPassCommandBuffer == nullptr) if (mRenderPassCommandBuffer == nullptr)
{ {
return angle::Result::Continue; return angle::Result::Continue;
} }
for (QueryVk *activeQuery : mRenderPassQueries) for (QueryVk *activeQuery : mActiveRenderPassQueries)
{ {
if (activeQuery) if (activeQuery)
{ {
activeQuery->getQueryHelper()->endRenderPassQuery(this, mRenderPassCommandBuffer); activeQuery->getQueryHelper()->endRenderPassQuery(this);
ANGLE_TRY(activeQuery->stashQueryHelper(this)); ANGLE_TRY(activeQuery->stashQueryHelper(this));
} }
} }
...@@ -4780,15 +4788,17 @@ angle::Result ContextVk::pauseRenderPassQueryIfActive() ...@@ -4780,15 +4788,17 @@ angle::Result ContextVk::pauseRenderPassQueryIfActive()
return angle::Result::Continue; return angle::Result::Continue;
} }
void ContextVk::resumeRenderPassQueryIfActive() angle::Result ContextVk::resumeRenderPassQueriesIfActive()
{ {
for (QueryVk *activeQuery : mRenderPassQueries) for (QueryVk *activeQuery : mActiveRenderPassQueries)
{ {
if (activeQuery) if (activeQuery)
{ {
activeQuery->getQueryHelper()->beginRenderPassQuery(this, mRenderPassCommandBuffer); ANGLE_TRY(activeQuery->getQueryHelper()->beginRenderPassQuery(this));
} }
} }
return angle::Result::Continue;
} }
bool ContextVk::isRobustResourceInitEnabled() const bool ContextVk::isRobustResourceInitEnabled() const
......
...@@ -536,11 +536,11 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -536,11 +536,11 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
bool isRobustResourceInitEnabled() const; bool isRobustResourceInitEnabled() const;
// occlusion query // occlusion query
void beginRenderPassQuery(QueryVk *queryVk); angle::Result beginRenderPassQuery(QueryVk *queryVk);
void endRenderPassQuery(QueryVk *queryVk); void endRenderPassQuery(QueryVk *queryVk);
angle::Result pauseRenderPassQueryIfActive(); angle::Result pauseRenderPassQueriesIfActive();
void resumeRenderPassQueryIfActive(); angle::Result resumeRenderPassQueriesIfActive();
void updateOverlayOnPresent(); void updateOverlayOnPresent();
void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer); void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer);
...@@ -895,8 +895,11 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -895,8 +895,11 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
angle::PackedEnumMap<PipelineType, vk::DynamicDescriptorPool> mDriverUniformsDescriptorPools; angle::PackedEnumMap<PipelineType, vk::DynamicDescriptorPool> mDriverUniformsDescriptorPools;
gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools; gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools;
// Saved queries run in the RenderPass. // Queries that need to be closed and reopened with the render pass:
gl::QueryTypeMap<QueryVk *> mRenderPassQueries; //
// - Occlusion queries
// - Transform feedback queries, if not emulated
gl::QueryTypeMap<QueryVk *> mActiveRenderPassQueries;
// Dirty bits. // Dirty bits.
DirtyBits mGraphicsDirtyBits; DirtyBits mGraphicsDirtyBits;
......
...@@ -19,6 +19,29 @@ ...@@ -19,6 +19,29 @@
namespace rx namespace rx
{ {
namespace
{
bool IsRenderPassQuery(ContextVk *contextVk, gl::QueryType type)
{
switch (type)
{
case gl::QueryType::AnySamples:
case gl::QueryType::AnySamplesConservative:
return true;
case gl::QueryType::TransformFeedbackPrimitivesWritten:
return contextVk->getFeatures().supportsTransformFeedbackExtension.enabled;
default:
return false;
}
}
bool IsEmulatedTransformFeedbackQuery(ContextVk *contextVk, gl::QueryType type)
{
return type == gl::QueryType::TransformFeedbackPrimitivesWritten &&
contextVk->getFeatures().emulateTransformFeedback.enabled;
}
} // anonymous namespace
QueryVk::QueryVk(gl::QueryType type) QueryVk::QueryVk(gl::QueryType type)
: QueryImpl(type), : QueryImpl(type),
mTransformFeedbackPrimitivesDrawn(0), mTransformFeedbackPrimitivesDrawn(0),
...@@ -31,9 +54,9 @@ QueryVk::~QueryVk() = default; ...@@ -31,9 +54,9 @@ QueryVk::~QueryVk() = default;
void QueryVk::onDestroy(const gl::Context *context) void QueryVk::onDestroy(const gl::Context *context)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
if (getType() != gl::QueryType::TransformFeedbackPrimitivesWritten) if (mType != gl::QueryType::TransformFeedbackPrimitivesWritten)
{ {
vk::DynamicQueryPool *queryPool = contextVk->getQueryPool(getType()); vk::DynamicQueryPool *queryPool = contextVk->getQueryPool(mType);
queryPool->freeQuery(contextVk, &mQueryHelper); queryPool->freeQuery(contextVk, &mQueryHelper);
queryPool->freeQuery(contextVk, &mQueryHelperTimeElapsedBegin); queryPool->freeQuery(contextVk, &mQueryHelperTimeElapsedBegin);
} }
...@@ -41,10 +64,10 @@ void QueryVk::onDestroy(const gl::Context *context) ...@@ -41,10 +64,10 @@ void QueryVk::onDestroy(const gl::Context *context)
angle::Result QueryVk::stashQueryHelper(ContextVk *contextVk) angle::Result QueryVk::stashQueryHelper(ContextVk *contextVk)
{ {
ASSERT(isRenderPassQuery(contextVk)); ASSERT(IsRenderPassQuery(contextVk, mType));
mStashedQueryHelpers.emplace_back(std::move(mQueryHelper)); mStashedQueryHelpers.emplace_back(std::move(mQueryHelper));
mQueryHelper.deinit(); mQueryHelper.deinit();
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper)); ANGLE_TRY(contextVk->getQueryPool(mType)->allocateQuery(contextVk, &mQueryHelper));
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -66,53 +89,55 @@ angle::Result QueryVk::begin(const gl::Context *context) ...@@ -66,53 +89,55 @@ angle::Result QueryVk::begin(const gl::Context *context)
mCachedResultValid = false; mCachedResultValid = false;
if (isTransformFeedbackQuery()) // Transform feedback query is a handled by a CPU-calculated value when emulated.
if (IsEmulatedTransformFeedbackQuery(contextVk, mType))
{ {
ASSERT(!contextVk->getFeatures().supportsTransformFeedbackExtension.enabled);
mTransformFeedbackPrimitivesDrawn = 0; mTransformFeedbackPrimitivesDrawn = 0;
// Transform feedback query is a handled by a CPU-calculated value when emulated. return angle::Result::Continue;
if (contextVk->getFeatures().emulateTransformFeedback.enabled)
{
ASSERT(!contextVk->getFeatures().supportsTransformFeedbackExtension.enabled);
return angle::Result::Continue;
}
} }
if (!mQueryHelper.valid()) if (!mQueryHelper.valid())
{ {
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper)); ANGLE_TRY(contextVk->getQueryPool(mType)->allocateQuery(contextVk, &mQueryHelper));
}
if (isRenderPassQuery(contextVk))
{
// For pathological usage case where begin/end is called back to back without flush and get
// result, we have to force flush so that the same mQueryHelper will not encoded in the same
// renderpass twice without resetting it.
if (mQueryHelper.usedInRecordedCommands())
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
// As soon as beginQuery is called, previous query's result will not retrievable by API.
// We must clear it so that it will not count against current beginQuery call.
mStashedQueryHelpers.clear();
mQueryHelper.deinit();
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
}
contextVk->beginRenderPassQuery(this);
} }
else if (getType() == gl::QueryType::TimeElapsed)
{
// Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
if (!mQueryHelperTimeElapsedBegin.valid())
{
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(
contextVk, &mQueryHelperTimeElapsedBegin));
}
ANGLE_TRY(mQueryHelperTimeElapsedBegin.flushAndWriteTimestamp(contextVk)); switch (mType)
}
else
{ {
ANGLE_TRY(mQueryHelper.beginQuery(contextVk)); case gl::QueryType::AnySamples:
case gl::QueryType::AnySamplesConservative:
case gl::QueryType::TransformFeedbackPrimitivesWritten:
// For pathological usage case where begin/end is called back to back without flush and
// get result, we have to force flush so that the same mQueryHelper will not encoded in
// the same renderpass twice without resetting it.
if (mQueryHelper.usedInRecordedCommands())
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
// As soon as beginQuery is called, previous query's result will not retrievable by
// API. We must clear it so that it will not count against current beginQuery call.
mStashedQueryHelpers.clear();
mQueryHelper.deinit();
ANGLE_TRY(contextVk->getQueryPool(mType)->allocateQuery(contextVk, &mQueryHelper));
}
ANGLE_TRY(contextVk->beginRenderPassQuery(this));
break;
case gl::QueryType::Timestamp:
ANGLE_TRY(mQueryHelper.beginQuery(contextVk));
break;
case gl::QueryType::TimeElapsed:
// Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
if (!mQueryHelperTimeElapsedBegin.valid())
{
ANGLE_TRY(contextVk->getQueryPool(mType)->allocateQuery(
contextVk, &mQueryHelperTimeElapsedBegin));
}
ANGLE_TRY(mQueryHelperTimeElapsedBegin.flushAndWriteTimestamp(contextVk));
break;
default:
UNREACHABLE();
break;
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -122,13 +147,9 @@ angle::Result QueryVk::end(const gl::Context *context) ...@@ -122,13 +147,9 @@ angle::Result QueryVk::end(const gl::Context *context)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
if (isRenderPassQuery(contextVk)) // Transform feedback query is a handled by a CPU-calculated value when emulated.
{ if (IsEmulatedTransformFeedbackQuery(contextVk, mType))
contextVk->endRenderPassQuery(this);
}
else if (isTransformFeedbackQuery())
{ {
// Transform feedback query is a handled by a CPU-calculated value when emulated.
ASSERT(contextVk->getFeatures().emulateTransformFeedback.enabled); ASSERT(contextVk->getFeatures().emulateTransformFeedback.enabled);
mCachedResult = mTransformFeedbackPrimitivesDrawn; mCachedResult = mTransformFeedbackPrimitivesDrawn;
...@@ -141,14 +162,26 @@ angle::Result QueryVk::end(const gl::Context *context) ...@@ -141,14 +162,26 @@ angle::Result QueryVk::end(const gl::Context *context)
mCachedResult += transformFeedback->getPrimitivesDrawn(); mCachedResult += transformFeedback->getPrimitivesDrawn();
} }
mCachedResultValid = true; mCachedResultValid = true;
return angle::Result::Continue;
} }
else if (getType() == gl::QueryType::TimeElapsed)
{ switch (mType)
ANGLE_TRY(mQueryHelper.flushAndWriteTimestamp(contextVk));
}
else
{ {
ANGLE_TRY(mQueryHelper.endQuery(contextVk)); case gl::QueryType::AnySamples:
case gl::QueryType::AnySamplesConservative:
case gl::QueryType::TransformFeedbackPrimitivesWritten:
contextVk->endRenderPassQuery(this);
break;
case gl::QueryType::Timestamp:
ANGLE_TRY(mQueryHelper.endQuery(contextVk));
break;
case gl::QueryType::TimeElapsed:
ANGLE_TRY(mQueryHelper.flushAndWriteTimestamp(contextVk));
break;
default:
UNREACHABLE();
break;
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -156,14 +189,14 @@ angle::Result QueryVk::end(const gl::Context *context) ...@@ -156,14 +189,14 @@ angle::Result QueryVk::end(const gl::Context *context)
angle::Result QueryVk::queryCounter(const gl::Context *context) angle::Result QueryVk::queryCounter(const gl::Context *context)
{ {
ASSERT(getType() == gl::QueryType::Timestamp); ASSERT(mType == gl::QueryType::Timestamp);
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
mCachedResultValid = false; mCachedResultValid = false;
if (!mQueryHelper.valid()) if (!mQueryHelper.valid())
{ {
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper)); ANGLE_TRY(contextVk->getQueryPool(mType)->allocateQuery(contextVk, &mQueryHelper));
} }
return mQueryHelper.flushAndWriteTimestamp(contextVk); return mQueryHelper.flushAndWriteTimestamp(contextVk);
...@@ -293,7 +326,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -293,7 +326,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
double timestampPeriod = renderer->getPhysicalDeviceProperties().limits.timestampPeriod; double timestampPeriod = renderer->getPhysicalDeviceProperties().limits.timestampPeriod;
// Fix up the results to what OpenGL expects. // Fix up the results to what OpenGL expects.
switch (getType()) switch (mType)
{ {
case gl::QueryType::AnySamples: case gl::QueryType::AnySamples:
case gl::QueryType::AnySamplesConservative: case gl::QueryType::AnySamplesConservative:
...@@ -367,15 +400,14 @@ void QueryVk::onTransformFeedbackEnd(GLsizeiptr primitivesDrawn) ...@@ -367,15 +400,14 @@ void QueryVk::onTransformFeedbackEnd(GLsizeiptr primitivesDrawn)
mTransformFeedbackPrimitivesDrawn += primitivesDrawn; mTransformFeedbackPrimitivesDrawn += primitivesDrawn;
} }
bool QueryVk::isRenderPassQuery(ContextVk *contextVk) const
{
return isOcclusionQuery() ||
(isTransformFeedbackQuery() &&
contextVk->getFeatures().supportsTransformFeedbackExtension.enabled);
}
uint32_t QueryVk::getQueryResultCount() const uint32_t QueryVk::getQueryResultCount() const
{ {
return isTransformFeedbackQuery() ? 2 : 1; switch (mType)
{
case gl::QueryType::TransformFeedbackPrimitivesWritten:
return 2;
default:
return 1;
}
} }
} // namespace rx } // namespace rx
...@@ -38,8 +38,6 @@ class QueryVk : public QueryImpl ...@@ -38,8 +38,6 @@ class QueryVk : public QueryImpl
vk::QueryHelper *getQueryHelper() { return &mQueryHelper; } vk::QueryHelper *getQueryHelper() { return &mQueryHelper; }
angle::Result stashQueryHelper(ContextVk *contextVk); angle::Result stashQueryHelper(ContextVk *contextVk);
bool isRenderPassQuery(ContextVk *contextVk) const;
private: private:
angle::Result getResult(const gl::Context *context, bool wait); angle::Result getResult(const gl::Context *context, bool wait);
...@@ -49,9 +47,10 @@ class QueryVk : public QueryImpl ...@@ -49,9 +47,10 @@ class QueryVk : public QueryImpl
uint32_t getQueryResultCount() const; uint32_t getQueryResultCount() const;
angle::Result accumulateStashedQueryResult(ContextVk *contextVk, vk::QueryResult *result); angle::Result accumulateStashedQueryResult(ContextVk *contextVk, vk::QueryResult *result);
// Used for AnySamples, AnySamplesConservative, Timestamp and TimeElapsed (end). // Used for all queries, except TimeElapsed (begin) or those that are emulated.
vk::QueryHelper mQueryHelper; vk::QueryHelper mQueryHelper;
// Used for occlusion query that we may end up with multiple outstanding query helper objects. // Used for queries that may end up with multiple outstanding query helper objects as they end
// and begin again with render passes.
std::vector<vk::QueryHelper> mStashedQueryHelpers; std::vector<vk::QueryHelper> mStashedQueryHelpers;
// An additional query used for TimeElapsed (begin), as it is implemented using Timestamp. // An additional query used for TimeElapsed (begin), as it is implemented using Timestamp.
vk::QueryHelper mQueryHelperTimeElapsedBegin; vk::QueryHelper mQueryHelperTimeElapsedBegin;
......
...@@ -136,16 +136,6 @@ ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command) ...@@ -136,16 +136,6 @@ ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command)
command->size); command->size);
} }
// Add any queued resetQueryPool commands to the given cmdBuffer
void SecondaryCommandBuffer::executeQueuedResetQueryPoolCommands(VkCommandBuffer cmdBuffer)
{
for (const ResetQueryPoolParams &queryParams : mResetQueryQueue)
{
vkCmdResetQueryPool(cmdBuffer, queryParams.queryPool, queryParams.firstQuery,
queryParams.queryCount);
}
}
// Parse the cmds in this cmd buffer into given primary cmd buffer // Parse the cmds in this cmd buffer into given primary cmd buffer
void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer) void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer)
{ {
......
...@@ -670,9 +670,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable ...@@ -670,9 +670,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable
// Parse the cmds in this cmd buffer into given primary cmd buffer for execution // Parse the cmds in this cmd buffer into given primary cmd buffer for execution
void executeCommands(VkCommandBuffer cmdBuffer); void executeCommands(VkCommandBuffer cmdBuffer);
// If resetQueryPoolCommands are queued, call this to execute them all
// This should only be called on a cmdBuffer without an active renderPass
void executeQueuedResetQueryPoolCommands(VkCommandBuffer cmdBuffer);
// Calculate memory usage of this command buffer for diagnostics. // Calculate memory usage of this command buffer for diagnostics.
void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const; void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;
...@@ -704,7 +701,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable ...@@ -704,7 +701,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable
{ {
mCommands.clear(); mCommands.clear();
initialize(mAllocator); initialize(mAllocator);
mResetQueryQueue.clear();
} }
// This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator // This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator
...@@ -821,9 +817,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable ...@@ -821,9 +817,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable
uint8_t *mCurrentWritePointer; uint8_t *mCurrentWritePointer;
size_t mCurrentBytesRemaining; size_t mCurrentBytesRemaining;
// resetQueryPool command must be executed outside RP so we queue them up for
// an inside RenderPass command buffer and pre-prend them to the commands
std::vector<ResetQueryPoolParams> mResetQueryQueue;
}; };
ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer() ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer()
...@@ -1357,13 +1350,6 @@ ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineSt ...@@ -1357,13 +1350,6 @@ ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineSt
paramStruct->stageMask = stageMask; paramStruct->stageMask = stageMask;
} }
ANGLE_INLINE void SecondaryCommandBuffer::queueResetQueryPool(VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount)
{
mResetQueryQueue.push_back({queryPool, firstQuery, queryCount});
}
ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(VkQueryPool queryPool, ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(VkQueryPool queryPool,
uint32_t firstQuery, uint32_t firstQuery,
uint32_t queryCount) uint32_t queryCount)
......
...@@ -1598,10 +1598,10 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -1598,10 +1598,10 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
sizeof(shaderParams), commandBuffer)); sizeof(shaderParams), commandBuffer));
// Make sure this draw call doesn't count towards occlusion query results. // Make sure this draw call doesn't count towards occlusion query results.
ANGLE_TRY(contextVk->pauseRenderPassQueryIfActive()); ANGLE_TRY(contextVk->pauseRenderPassQueriesIfActive());
commandBuffer->setScissor(0, 1, &scissor); commandBuffer->setScissor(0, 1, &scissor);
commandBuffer->draw(3, 0); commandBuffer->draw(3, 0);
contextVk->resumeRenderPassQueryIfActive(); ANGLE_TRY(contextVk->resumeRenderPassQueriesIfActive());
// Make sure what's bound here is correctly reverted on the next draw. // Make sure what's bound here is correctly reverted on the next draw.
contextVk->invalidateGraphicsPipelineAndDescriptorSets(); contextVk->invalidateGraphicsPipelineAndDescriptorSets();
......
...@@ -1353,7 +1353,6 @@ angle::Result CommandBufferHelper::flushToPrimary(const angle::FeaturesVk &featu ...@@ -1353,7 +1353,6 @@ angle::Result CommandBufferHelper::flushToPrimary(const angle::FeaturesVk &featu
if (mIsRenderPassCommandBuffer) if (mIsRenderPassCommandBuffer)
{ {
mCommandBuffer.executeQueuedResetQueryPoolCommands(primary->getHandle());
ASSERT(renderPass != nullptr); ASSERT(renderPass != nullptr);
VkRenderPassBeginInfo beginInfo = {}; VkRenderPassBeginInfo beginInfo = {};
...@@ -2435,11 +2434,22 @@ void QueryHelper::deinit() ...@@ -2435,11 +2434,22 @@ void QueryHelper::deinit()
mUse.init(); mUse.init();
} }
void QueryHelper::resetQueryPool(ContextVk *contextVk, void QueryHelper::beginQueryImpl(ContextVk *contextVk,
CommandBuffer *outsideRenderPassCommandBuffer) CommandBuffer *resetCommandBuffer,
CommandBuffer *commandBuffer)
{ {
const QueryPool &queryPool = getQueryPool(); const QueryPool &queryPool = getQueryPool();
outsideRenderPassCommandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1); resetCommandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1);
commandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0);
}
void QueryHelper::endQueryImpl(ContextVk *contextVk, CommandBuffer *commandBuffer)
{
commandBuffer->endQuery(getQueryPool().getHandle(), mQuery);
// Query results are available after endQuery, retain this query so that we get its serial
// updated which is used to indicate that query results are (or will be) available.
retain(&contextVk->getResourceUseList());
} }
angle::Result QueryHelper::beginQuery(ContextVk *contextVk) angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
...@@ -2449,11 +2459,10 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk) ...@@ -2449,11 +2459,10 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass()); ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
} }
vk::CommandBuffer *commandBuffer; CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer)); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
const QueryPool &queryPool = getQueryPool();
commandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1); beginQueryImpl(contextVk, commandBuffer, commandBuffer);
commandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2465,31 +2474,30 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk) ...@@ -2465,31 +2474,30 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk)
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass()); ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
} }
vk::CommandBuffer *commandBuffer; CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer)); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
commandBuffer->endQuery(getQueryPool().getHandle(), mQuery);
// Query results are available after endQuery, retain this query so that we get its serial endQueryImpl(contextVk, commandBuffer);
// updated which is used to indicate that query results are (or will be) available.
retain(&contextVk->getResourceUseList());
return angle::Result::Continue; return angle::Result::Continue;
} }
void QueryHelper::beginRenderPassQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer) angle::Result QueryHelper::beginRenderPassQuery(ContextVk *contextVk)
{ {
const QueryPool &queryPool = getQueryPool(); CommandBuffer *outsideRenderPassCommandBuffer;
renderPassCommandBuffer->queueResetQueryPool(queryPool.getHandle(), mQuery, 1); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &outsideRenderPassCommandBuffer));
renderPassCommandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0);
CommandBuffer *renderPassCommandBuffer =
&contextVk->getStartedRenderPassCommands().getCommandBuffer();
beginQueryImpl(contextVk, outsideRenderPassCommandBuffer, renderPassCommandBuffer);
return angle::Result::Continue;
} }
void QueryHelper::endRenderPassQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer) void QueryHelper::endRenderPassQuery(ContextVk *contextVk)
{ {
renderPassCommandBuffer->endQuery(getQueryPool().getHandle(), mQuery); endQueryImpl(contextVk, &contextVk->getStartedRenderPassCommands().getCommandBuffer());
// Query results are available after endQuery, retain this query so that we get its serial
// updated which is used to indicate that query results are (or will be) available.
retain(&contextVk->getResourceUseList());
} }
angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk) angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk)
...@@ -2499,7 +2507,7 @@ angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk) ...@@ -2499,7 +2507,7 @@ angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk)
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass()); ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
} }
vk::CommandBuffer *commandBuffer; CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer)); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
writeTimestamp(contextVk, commandBuffer); writeTimestamp(contextVk, commandBuffer);
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -451,14 +451,12 @@ class QueryHelper final : public Resource ...@@ -451,14 +451,12 @@ class QueryHelper final : public Resource
bool valid() const { return mDynamicQueryPool != nullptr; } bool valid() const { return mDynamicQueryPool != nullptr; }
// Begin/end queries. These functions break the render pass.
angle::Result beginQuery(ContextVk *contextVk); angle::Result beginQuery(ContextVk *contextVk);
angle::Result endQuery(ContextVk *contextVk); angle::Result endQuery(ContextVk *contextVk);
// Begin/end queries within a started render pass.
// for occlusion query angle::Result beginRenderPassQuery(ContextVk *contextVk);
// Must resetQueryPool outside of RenderPass before beginning occlusion query. void endRenderPassQuery(ContextVk *contextVk);
void resetQueryPool(ContextVk *contextVk, CommandBuffer *outsideRenderPassCommandBuffer);
void beginRenderPassQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer);
void endRenderPassQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer);
angle::Result flushAndWriteTimestamp(ContextVk *contextVk); angle::Result flushAndWriteTimestamp(ContextVk *contextVk);
// When syncing gpu/cpu time, main thread accesses primary directly // When syncing gpu/cpu time, main thread accesses primary directly
...@@ -479,6 +477,13 @@ class QueryHelper final : public Resource ...@@ -479,6 +477,13 @@ class QueryHelper final : public Resource
return mDynamicQueryPool->getQueryPool(mQueryPoolIndex); return mDynamicQueryPool->getQueryPool(mQueryPoolIndex);
} }
// Reset needs to always be done outside a render pass, which may be different from the
// passed-in command buffer (which could be the render pass').
void beginQueryImpl(ContextVk *contextVk,
CommandBuffer *resetCommandBuffer,
CommandBuffer *commandBuffer);
void endQueryImpl(ContextVk *contextVk, CommandBuffer *commandBuffer);
const DynamicQueryPool *mDynamicQueryPool; const DynamicQueryPool *mDynamicQueryPool;
size_t mQueryPoolIndex; size_t mQueryPoolIndex;
uint32_t mQuery; uint32_t mQuery;
......
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