Vulkan: Implement GL_EXT_disjoint_timer_query
- QueryVk::queryCounter() and relevant utils are implemented for the
sake of Timestamp queries.
- TimeElapsed queries are implemented using two Timestamp queries.
Bug: angleproject:2885
Change-Id: Id181bd97f5a24e7e96b3ea1b819483227e64daf0
Reviewed-on: https://chromium-review.googlesource.com/c/1276806
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp
index d6e11df..d6467fb 100644
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
@@ -27,6 +27,7 @@
{
ContextVk *contextVk = vk::GetImpl(context);
contextVk->getQueryPool(getType())->freeQuery(contextVk, &mQueryHelper);
+ contextVk->getQueryPool(getType())->freeQuery(contextVk, &mQueryHelperTimeElapsedBegin);
return gl::NoError();
}
@@ -35,11 +36,30 @@
{
ContextVk *contextVk = vk::GetImpl(context);
- ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
-
mCachedResultValid = false;
- mQueryHelper.beginQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+ if (!mQueryHelper.getQueryPool())
+ {
+ ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
+ }
+
+ // Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
+ if (getType() == gl::QueryType::TimeElapsed)
+ {
+ if (!mQueryHelperTimeElapsedBegin.getQueryPool())
+ {
+ ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(
+ contextVk, &mQueryHelperTimeElapsedBegin));
+ }
+
+ mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk,
+ mQueryHelperTimeElapsedBegin.getQueryPool(),
+ mQueryHelperTimeElapsedBegin.getQuery());
+ }
+ else
+ {
+ mQueryHelper.beginQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+ }
return gl::NoError();
}
@@ -48,15 +68,35 @@
{
ContextVk *contextVk = vk::GetImpl(context);
- mQueryHelper.endQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+ if (getType() == gl::QueryType::TimeElapsed)
+ {
+ mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(),
+ mQueryHelper.getQuery());
+ }
+ else
+ {
+ mQueryHelper.endQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+ }
return gl::NoError();
}
gl::Error QueryVk::queryCounter(const gl::Context *context)
{
- UNIMPLEMENTED();
- return gl::InternalError();
+ ContextVk *contextVk = vk::GetImpl(context);
+
+ mCachedResultValid = false;
+
+ if (!mQueryHelper.getQueryPool())
+ {
+ ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
+ }
+
+ ASSERT(getType() == gl::QueryType::Timestamp);
+
+ mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+
+ return gl::NoError();
}
angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
@@ -71,9 +111,13 @@
// glGetQueryObject* requires an implicit flush of the command buffers to guarantee execution in
// finite time.
+ // Note regarding time-elapsed: end should have been called after begin, so flushing when end
+ // has pending work should flush begin too.
if (mQueryHelper.hasPendingWork(renderer))
{
ANGLE_TRY_HANDLE(context, renderer->flush(contextVk));
+
+ ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(renderer));
ASSERT(!mQueryHelper.hasPendingWork(renderer));
}
@@ -113,6 +157,24 @@
// OpenGL query result in these cases is binary
mCachedResult = !!mCachedResult;
break;
+ case gl::QueryType::Timestamp:
+ break;
+ case gl::QueryType::TimeElapsed:
+ {
+ uint64_t timeElapsedEnd = mCachedResult;
+
+ result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
+ contextVk, mQueryHelperTimeElapsedBegin.getQuery(), 1, sizeof(mCachedResult),
+ &mCachedResult, sizeof(mCachedResult), flags);
+ ANGLE_TRY(result);
+
+ // Since the result of the end query of time-elapsed is already available, the
+ // result of begin query must be available too.
+ ASSERT(result != angle::Result::Incomplete());
+
+ mCachedResult = timeElapsedEnd - mCachedResult;
+ break;
+ }
default:
UNREACHABLE();
break;
@@ -121,7 +183,6 @@
mCachedResultValid = true;
return angle::Result::Continue();
}
-
gl::Error QueryVk::getResult(const gl::Context *context, GLint *params)
{
ANGLE_TRY(getResult(context, true));