Commit cdf280c0 by Jamie Madill Committed by Commit Bot

Vulkan: Fix serial handling for queries

Previous serial mechanism wasn't reliable. QueryHelper is now a vk::Resource and uses the vk::Resource lifecycle. Also added some utility methods to QueryVk to deal with stashed queries. Any question we want to ask about mQueryHelper we want to ask about the stashed queries as well. Bug: b/169055809 Bug: b/169788986 Bug: b/170312581 Change-Id: Ia34a7a433e61a2543cfb09491ebab55b054a26c9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2537718Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
parent d3a14089
...@@ -1638,6 +1638,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime() ...@@ -1638,6 +1638,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
vk::DeviceScoped<vk::PrimaryCommandBuffer> commandBatch(device); vk::DeviceScoped<vk::PrimaryCommandBuffer> commandBatch(device);
vk::PrimaryCommandBuffer &commandBuffer = commandBatch.get(); vk::PrimaryCommandBuffer &commandBuffer = commandBatch.get();
vk::ResourceUseList scratchResourceUseList;
ANGLE_TRY(mRenderer->getCommandBufferOneOff(this, &commandBuffer)); ANGLE_TRY(mRenderer->getCommandBufferOneOff(this, &commandBuffer));
commandBuffer.setEvent(gpuReady.get().getHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT); commandBuffer.setEvent(gpuReady.get().getHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
...@@ -1645,6 +1647,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime() ...@@ -1645,6 +1647,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, nullptr, 0, nullptr, 0, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, nullptr, 0, nullptr, 0,
nullptr); nullptr);
timestampQuery.writeTimestampToPrimary(this, &commandBuffer); timestampQuery.writeTimestampToPrimary(this, &commandBuffer);
timestampQuery.retain(&scratchResourceUseList);
commandBuffer.setEvent(gpuDone.get().getHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT); commandBuffer.setEvent(gpuDone.get().getHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
ANGLE_VK_TRY(this, commandBuffer.end()); ANGLE_VK_TRY(this, commandBuffer.end());
...@@ -1652,6 +1656,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime() ...@@ -1652,6 +1656,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
Serial throwAwaySerial; Serial throwAwaySerial;
ANGLE_TRY(mRenderer->queueSubmitOneOff(this, std::move(commandBuffer), mContextPriority, ANGLE_TRY(mRenderer->queueSubmitOneOff(this, std::move(commandBuffer), mContextPriority,
nullptr, &throwAwaySerial)); nullptr, &throwAwaySerial));
scratchResourceUseList.releaseResourceUsesAndUpdateSerials(throwAwaySerial);
// Wait for GPU to be ready. This is a short busy wait. // Wait for GPU to be ready. This is a short busy wait.
VkResult result = VK_EVENT_RESET; VkResult result = VK_EVENT_RESET;
...@@ -1753,7 +1758,7 @@ angle::Result ContextVk::checkCompletedGpuEvents() ...@@ -1753,7 +1758,7 @@ angle::Result ContextVk::checkCompletedGpuEvents()
for (GpuEventQuery &eventQuery : mInFlightGpuEventQueries) for (GpuEventQuery &eventQuery : mInFlightGpuEventQueries)
{ {
// Only check the timestamp query if the submission has finished. // Only check the timestamp query if the submission has finished.
if (eventQuery.queryHelper.getStoredQueueSerial() > lastCompletedSerial) if (eventQuery.queryHelper.usedInRunningCommands(lastCompletedSerial))
{ {
break; break;
} }
...@@ -4183,6 +4188,8 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut) ...@@ -4183,6 +4188,8 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
ANGLE_TRY(timestampQueryPool.get().init(this, VK_QUERY_TYPE_TIMESTAMP, 1)); ANGLE_TRY(timestampQueryPool.get().init(this, VK_QUERY_TYPE_TIMESTAMP, 1));
ANGLE_TRY(timestampQueryPool.get().allocateQuery(this, &timestampQuery)); ANGLE_TRY(timestampQueryPool.get().allocateQuery(this, &timestampQuery));
vk::ResourceUseList scratchResourceUseList;
// Record the command buffer // Record the command buffer
vk::DeviceScoped<vk::PrimaryCommandBuffer> commandBatch(device); vk::DeviceScoped<vk::PrimaryCommandBuffer> commandBatch(device);
vk::PrimaryCommandBuffer &commandBuffer = commandBatch.get(); vk::PrimaryCommandBuffer &commandBuffer = commandBatch.get();
...@@ -4190,6 +4197,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut) ...@@ -4190,6 +4197,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
ANGLE_TRY(mRenderer->getCommandBufferOneOff(this, &commandBuffer)); ANGLE_TRY(mRenderer->getCommandBufferOneOff(this, &commandBuffer));
timestampQuery.writeTimestampToPrimary(this, &commandBuffer); timestampQuery.writeTimestampToPrimary(this, &commandBuffer);
timestampQuery.retain(&scratchResourceUseList);
ANGLE_VK_TRY(this, commandBuffer.end()); ANGLE_VK_TRY(this, commandBuffer.end());
// Create fence for the submission // Create fence for the submission
...@@ -4218,6 +4226,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut) ...@@ -4218,6 +4226,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
// Wait for the submission to finish. Given no semaphores, there is hope that it would execute // Wait for the submission to finish. Given no semaphores, there is hope that it would execute
// in parallel with what's already running on the GPU. // in parallel with what's already running on the GPU.
ANGLE_VK_TRY(this, fence.get().wait(device, mRenderer->getMaxFenceWaitTimeNs())); ANGLE_VK_TRY(this, fence.get().wait(device, mRenderer->getMaxFenceWaitTimeNs()));
scratchResourceUseList.releaseResourceUsesAndUpdateSerials(throwAwaySerial);
// Get the query results // Get the query results
ANGLE_TRY(timestampQuery.getUint64Result(this, timestampOut)); ANGLE_TRY(timestampQuery.getUint64Result(this, timestampOut));
......
...@@ -42,7 +42,7 @@ void QueryVk::onDestroy(const gl::Context *context) ...@@ -42,7 +42,7 @@ void QueryVk::onDestroy(const gl::Context *context)
angle::Result QueryVk::stashQueryHelper(ContextVk *contextVk) angle::Result QueryVk::stashQueryHelper(ContextVk *contextVk)
{ {
ASSERT(isOcclusionQuery()); ASSERT(isOcclusionQuery());
mStashedQueryHelpers.emplace_back(mQueryHelper); mStashedQueryHelpers.emplace_back(std::move(mQueryHelper));
mQueryHelper.deinit(); mQueryHelper.deinit();
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper)); ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
return angle::Result::Continue; return angle::Result::Continue;
...@@ -86,7 +86,7 @@ angle::Result QueryVk::begin(const gl::Context *context) ...@@ -86,7 +86,7 @@ angle::Result QueryVk::begin(const gl::Context *context)
// For pathological usage case where begin/end is called back to back without flush and get // 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 // result, we have to force flush so that the same mQueryHelper will not encoded in the same
// renderpass twice without resetting it. // renderpass twice without resetting it.
if (mQueryHelper.hasPendingWork(contextVk)) if (mQueryHelper.usedInRecordedCommands())
{ {
ANGLE_TRY(contextVk->flushImpl(nullptr)); ANGLE_TRY(contextVk->flushImpl(nullptr));
// As soon as beginQuery is called, previous query's result will not retrievable by API. // As soon as beginQuery is called, previous query's result will not retrievable by API.
...@@ -166,6 +166,63 @@ angle::Result QueryVk::queryCounter(const gl::Context *context) ...@@ -166,6 +166,63 @@ angle::Result QueryVk::queryCounter(const gl::Context *context)
return mQueryHelper.flushAndWriteTimestamp(contextVk); return mQueryHelper.flushAndWriteTimestamp(contextVk);
} }
bool QueryVk::isUsedInRecordedCommands() const
{
if (mQueryHelper.usedInRecordedCommands())
{
return true;
}
for (const vk::QueryHelper &query : mStashedQueryHelpers)
{
if (query.usedInRecordedCommands())
{
return true;
}
}
return false;
}
bool QueryVk::isCurrentlyInUse(Serial lastCompletedSerial) const
{
if (mQueryHelper.isCurrentlyInUse(lastCompletedSerial))
{
return true;
}
for (const vk::QueryHelper &query : mStashedQueryHelpers)
{
if (query.isCurrentlyInUse(lastCompletedSerial))
{
return true;
}
}
return false;
}
angle::Result QueryVk::finishRunningCommands(ContextVk *contextVk)
{
Serial lastCompletedSerial = contextVk->getLastCompletedQueueSerial();
if (mQueryHelper.usedInRunningCommands(lastCompletedSerial))
{
ANGLE_TRY(mQueryHelper.finishRunningCommands(contextVk));
lastCompletedSerial = contextVk->getLastCompletedQueueSerial();
}
for (vk::QueryHelper &query : mStashedQueryHelpers)
{
if (query.usedInRunningCommands(lastCompletedSerial))
{
ANGLE_TRY(query.finishRunningCommands(contextVk));
lastCompletedSerial = contextVk->getLastCompletedQueueSerial();
}
}
return angle::Result::Continue;
}
angle::Result QueryVk::getResult(const gl::Context *context, bool wait) angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
{ {
ANGLE_TRACE_EVENT0("gpu.angle", "QueryVk::getResult"); ANGLE_TRACE_EVENT0("gpu.angle", "QueryVk::getResult");
...@@ -182,19 +239,13 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -182,19 +239,13 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
// finite time. // finite time.
// Note regarding time-elapsed: end should have been called after begin, so flushing when end // Note regarding time-elapsed: end should have been called after begin, so flushing when end
// has pending work should flush begin too. // has pending work should flush begin too.
// TODO: https://issuetracker.google.com/169788986 - can't guarantee hasPendingWork() works when
// using threaded worker if (isUsedInRecordedCommands())
if (mQueryHelper.hasPendingWork(contextVk))
{ {
ANGLE_TRY(contextVk->flushImpl(nullptr)); ANGLE_TRY(contextVk->flushImpl(nullptr));
if (renderer->getFeatures().asyncCommandQueue.enabled)
{
// TODO: https://issuetracker.google.com/170312581 - For now just stalling here
ANGLE_TRY(renderer->waitForCommandProcessorIdle(contextVk));
}
ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(contextVk)); ASSERT(!mQueryHelperTimeElapsedBegin.usedInRecordedCommands());
ASSERT(!mQueryHelper.hasPendingWork(contextVk)); ASSERT(!mQueryHelper.usedInRecordedCommands());
} }
ANGLE_TRY(contextVk->checkCompletedCommands()); ANGLE_TRY(contextVk->checkCompletedCommands());
...@@ -203,7 +254,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -203,7 +254,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
// command may not have been performed by the GPU yet. To avoid a race condition in this // command may not have been performed by the GPU yet. To avoid a race condition in this
// case, wait for the batch to finish first before querying (or return not-ready if not // case, wait for the batch to finish first before querying (or return not-ready if not
// waiting). // waiting).
if (contextVk->isSerialInUse(mQueryHelper.getStoredQueueSerial())) if (isCurrentlyInUse(contextVk->getLastCompletedQueueSerial()))
{ {
if (!wait) if (!wait)
{ {
...@@ -211,7 +262,10 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -211,7 +262,10 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
} }
ANGLE_PERF_WARNING(contextVk->getDebug(), GL_DEBUG_SEVERITY_HIGH, ANGLE_PERF_WARNING(contextVk->getDebug(), GL_DEBUG_SEVERITY_HIGH,
"GPU stall due to waiting on uncompleted query"); "GPU stall due to waiting on uncompleted query");
ANGLE_TRY(contextVk->finishToSerial(mQueryHelper.getStoredQueueSerial()));
// Assert that the work has been sent to the GPU
ASSERT(!isUsedInRecordedCommands());
ANGLE_TRY(finishRunningCommands(contextVk));
} }
if (wait) if (wait)
......
...@@ -42,6 +42,10 @@ class QueryVk : public QueryImpl ...@@ -42,6 +42,10 @@ class QueryVk : public QueryImpl
private: private:
angle::Result getResult(const gl::Context *context, bool wait); angle::Result getResult(const gl::Context *context, bool wait);
bool isUsedInRecordedCommands() const;
bool isCurrentlyInUse(Serial lastCompletedSerial) const;
angle::Result finishRunningCommands(ContextVk *contextVk);
// Used for AnySamples, AnySamplesConservative, Timestamp and TimeElapsed (end). // Used for AnySamples, AnySamplesConservative, Timestamp and TimeElapsed (end).
vk::QueryHelper mQueryHelper; vk::QueryHelper mQueryHelper;
// Used for occlusion query that we may end up with multiple outstanding query helper objects. // Used for occlusion query that we may end up with multiple outstanding query helper objects.
......
...@@ -2335,6 +2335,26 @@ QueryHelper::QueryHelper() : mDynamicQueryPool(nullptr), mQueryPoolIndex(0), mQu ...@@ -2335,6 +2335,26 @@ QueryHelper::QueryHelper() : mDynamicQueryPool(nullptr), mQueryPoolIndex(0), mQu
QueryHelper::~QueryHelper() {} QueryHelper::~QueryHelper() {}
// Move constructor
QueryHelper::QueryHelper(QueryHelper &&rhs)
: Resource(std::move(rhs)),
mDynamicQueryPool(rhs.mDynamicQueryPool),
mQueryPoolIndex(rhs.mQueryPoolIndex),
mQuery(rhs.mQuery)
{
rhs.mDynamicQueryPool = nullptr;
rhs.mQueryPoolIndex = 0;
rhs.mQuery = 0;
}
QueryHelper &QueryHelper::operator=(QueryHelper &&rhs)
{
std::swap(mDynamicQueryPool, rhs.mDynamicQueryPool);
std::swap(mQueryPoolIndex, rhs.mQueryPoolIndex);
std::swap(mQuery, rhs.mQuery);
return *this;
}
void QueryHelper::init(const DynamicQueryPool *dynamicQueryPool, void QueryHelper::init(const DynamicQueryPool *dynamicQueryPool,
const size_t queryPoolIndex, const size_t queryPoolIndex,
uint32_t query) uint32_t query)
...@@ -2349,7 +2369,8 @@ void QueryHelper::deinit() ...@@ -2349,7 +2369,8 @@ void QueryHelper::deinit()
mDynamicQueryPool = nullptr; mDynamicQueryPool = nullptr;
mQueryPoolIndex = 0; mQueryPoolIndex = 0;
mQuery = 0; mQuery = 0;
mMostRecentSerial = Serial(); mUse.release();
mUse.init();
} }
void QueryHelper::resetQueryPool(ContextVk *contextVk, void QueryHelper::resetQueryPool(ContextVk *contextVk,
...@@ -2371,7 +2392,7 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk) ...@@ -2371,7 +2392,7 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
const QueryPool &queryPool = getQueryPool(); const QueryPool &queryPool = getQueryPool();
commandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1); commandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1);
commandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0); commandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2385,7 +2406,11 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk) ...@@ -2385,7 +2406,11 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk)
vk::CommandBuffer *commandBuffer; vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer)); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer({}, &commandBuffer));
commandBuffer->endQuery(getQueryPool().getHandle(), mQuery); commandBuffer->endQuery(getQueryPool().getHandle(), mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
// 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());
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2394,13 +2419,15 @@ void QueryHelper::beginOcclusionQuery(ContextVk *contextVk, CommandBuffer *rende ...@@ -2394,13 +2419,15 @@ void QueryHelper::beginOcclusionQuery(ContextVk *contextVk, CommandBuffer *rende
const QueryPool &queryPool = getQueryPool(); const QueryPool &queryPool = getQueryPool();
renderPassCommandBuffer->queueResetQueryPool(queryPool.getHandle(), mQuery, 1); renderPassCommandBuffer->queueResetQueryPool(queryPool.getHandle(), mQuery, 1);
renderPassCommandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0); renderPassCommandBuffer->beginQuery(queryPool.getHandle(), mQuery, 0);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
} }
void QueryHelper::endOcclusionQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer) void QueryHelper::endOcclusionQuery(ContextVk *contextVk, CommandBuffer *renderPassCommandBuffer)
{ {
renderPassCommandBuffer->endQuery(getQueryPool().getHandle(), mQuery); renderPassCommandBuffer->endQuery(getQueryPool().getHandle(), mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
// 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)
...@@ -2423,7 +2450,6 @@ void QueryHelper::writeTimestampToPrimary(ContextVk *contextVk, PrimaryCommandBu ...@@ -2423,7 +2450,6 @@ void QueryHelper::writeTimestampToPrimary(ContextVk *contextVk, PrimaryCommandBu
const QueryPool &queryPool = getQueryPool(); const QueryPool &queryPool = getQueryPool();
primary->resetQueryPool(queryPool, mQuery, 1); primary->resetQueryPool(queryPool, mQuery, 1);
primary->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery); primary->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
} }
void QueryHelper::writeTimestamp(ContextVk *contextVk, CommandBuffer *commandBuffer) void QueryHelper::writeTimestamp(ContextVk *contextVk, CommandBuffer *commandBuffer)
...@@ -2432,15 +2458,9 @@ void QueryHelper::writeTimestamp(ContextVk *contextVk, CommandBuffer *commandBuf ...@@ -2432,15 +2458,9 @@ void QueryHelper::writeTimestamp(ContextVk *contextVk, CommandBuffer *commandBuf
commandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1); commandBuffer->resetQueryPool(queryPool.getHandle(), mQuery, 1);
commandBuffer->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool.getHandle(), commandBuffer->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool.getHandle(),
mQuery); mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial(); // timestamp results are available immediately, 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());
bool QueryHelper::hasPendingWork(ContextVk *contextVk)
{
// TODO: https://issuetracker.google.com/169788986 - this is not a valid statement with
// CommandProcessor: If the renderer has a queue serial higher than the stored one, the command
// buffers that recorded this query have already been submitted, so there is no pending work.
return mMostRecentSerial.valid() && (mMostRecentSerial == contextVk->getCurrentQueueSerial());
} }
angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk, angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk,
...@@ -2452,7 +2472,7 @@ angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk, ...@@ -2452,7 +2472,7 @@ angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk,
// Ensure that we only wait if we have inserted a query in command buffer. Otherwise you will // Ensure that we only wait if we have inserted a query in command buffer. Otherwise you will
// wait forever and trigger GPU timeout. // wait forever and trigger GPU timeout.
if (mMostRecentSerial.valid()) if (mUse.getSerial().valid())
{ {
VkDevice device = contextVk->getDevice(); VkDevice device = contextVk->getDevice();
constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT; constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT;
...@@ -2481,7 +2501,7 @@ angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk, ...@@ -2481,7 +2501,7 @@ angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk,
angle::Result QueryHelper::getUint64Result(ContextVk *contextVk, uint64_t *resultOut) angle::Result QueryHelper::getUint64Result(ContextVk *contextVk, uint64_t *resultOut)
{ {
ASSERT(valid()); ASSERT(valid());
if (mMostRecentSerial.valid()) if (mUse.getSerial().valid())
{ {
VkDevice device = contextVk->getDevice(); VkDevice device = contextVk->getDevice();
constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT; constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT;
......
...@@ -415,12 +415,13 @@ class DynamicQueryPool final : public DynamicallyGrowingPool<QueryPool> ...@@ -415,12 +415,13 @@ class DynamicQueryPool final : public DynamicallyGrowingPool<QueryPool>
// of a fixed size as needed and allocates indices within those pools. // of a fixed size as needed and allocates indices within those pools.
// //
// The QueryHelper class below keeps the pool and index pair together. // The QueryHelper class below keeps the pool and index pair together.
class QueryHelper final class QueryHelper final : public vk::Resource
{ {
public: public:
QueryHelper(); QueryHelper();
~QueryHelper(); ~QueryHelper() override;
QueryHelper(QueryHelper &&rhs);
QueryHelper &operator=(QueryHelper &&rhs);
void init(const DynamicQueryPool *dynamicQueryPool, void init(const DynamicQueryPool *dynamicQueryPool,
const size_t queryPoolIndex, const size_t queryPoolIndex,
uint32_t query); uint32_t query);
...@@ -443,9 +444,6 @@ class QueryHelper final ...@@ -443,9 +444,6 @@ class QueryHelper final
// All other timestamp accesses should be made on outsideRenderPassCommandBuffer // All other timestamp accesses should be made on outsideRenderPassCommandBuffer
void writeTimestamp(ContextVk *contextVk, CommandBuffer *outsideRenderPassCommandBuffer); void writeTimestamp(ContextVk *contextVk, CommandBuffer *outsideRenderPassCommandBuffer);
Serial getStoredQueueSerial() { return mMostRecentSerial; }
bool hasPendingWork(ContextVk *contextVk);
angle::Result getUint64ResultNonBlocking(ContextVk *contextVk, angle::Result getUint64ResultNonBlocking(ContextVk *contextVk,
uint64_t *resultOut, uint64_t *resultOut,
bool *availableOut); bool *availableOut);
...@@ -462,7 +460,6 @@ class QueryHelper final ...@@ -462,7 +460,6 @@ class QueryHelper final
const DynamicQueryPool *mDynamicQueryPool; const DynamicQueryPool *mDynamicQueryPool;
size_t mQueryPoolIndex; size_t mQueryPoolIndex;
uint32_t mQuery; uint32_t mQuery;
Serial mMostRecentSerial;
}; };
// DynamicSemaphorePool allocates semaphores as needed. It uses a std::vector // DynamicSemaphorePool allocates semaphores as needed. It uses a std::vector
......
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