Commit a1e5f582 by Jamie Madill Committed by Commit Bot

Vulkan: Clean up QueryHelper uses.

Makes the wrapper classes take boxed query handles. Also cleans up some repeated code patterns. It also encapsulates the QueryHelper class more so that the pool indexes and handles are hidden from the user of the class. Fixed while working on GPU trace event timing. Bug: angleproject:4433 Change-Id: Ib6cba9c52ec956ebede9b411b70261ea5b877d7d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2081378 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent 80f55e97
......@@ -1593,13 +1593,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
commandBuffer.waitEvents(1, cpuReady.get().ptr(), VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, nullptr, 0, nullptr, 0,
nullptr);
commandBuffer.resetQueryPool(timestampQuery.getQueryPool()->getHandle(),
timestampQuery.getQuery(), 1);
commandBuffer.writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
timestampQuery.getQueryPool()->getHandle(),
timestampQuery.getQuery());
timestampQuery.writeTimestamp(&commandBuffer);
commandBuffer.setEvent(gpuDone.get().getHandle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
ANGLE_VK_TRY(this, commandBuffer.end());
......@@ -1643,12 +1637,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
// Get the query results
ANGLE_TRY(finishToSerial(getLastSubmittedQueueSerial()));
constexpr VkQueryResultFlags queryFlags = VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT;
uint64_t gpuTimestampCycles = 0;
ANGLE_VK_TRY(this, timestampQuery.getQueryPool()->getResults(
device, timestampQuery.getQuery(), 1, sizeof(gpuTimestampCycles),
&gpuTimestampCycles, sizeof(gpuTimestampCycles), queryFlags));
ANGLE_TRY(timestampQuery.getUint64Result(this, &gpuTimestampCycles));
// Use the first timestamp queried as origin.
if (mGpuEventTimestampOrigin == 0)
......@@ -1696,11 +1686,11 @@ angle::Result ContextVk::traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuff
ANGLE_TRY(mGpuEventQueryPool.allocateQuery(this, &event.queryPoolIndex, &event.queryIndex));
commandBuffer->resetQueryPool(
mGpuEventQueryPool.getQueryPool(event.queryPoolIndex)->getHandle(), event.queryIndex, 1);
commandBuffer->writeTimestamp(
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
mGpuEventQueryPool.getQueryPool(event.queryPoolIndex)->getHandle(), event.queryIndex);
const vk::QueryPool &queryPool = mGpuEventQueryPool.getQueryPool(event.queryPoolIndex);
commandBuffer->resetQueryPool(queryPool, event.queryIndex, 1);
commandBuffer->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool,
event.queryIndex);
mInFlightGpuEventQueries.push_back(std::move(event));
......@@ -1727,11 +1717,11 @@ angle::Result ContextVk::checkCompletedGpuEvents()
}
// See if the results are available.
uint64_t gpuTimestampCycles = 0;
VkResult result = mGpuEventQueryPool.getQueryPool(eventQuery.queryPoolIndex)
->getResults(getDevice(), eventQuery.queryIndex, 1,
sizeof(gpuTimestampCycles), &gpuTimestampCycles,
sizeof(gpuTimestampCycles), VK_QUERY_RESULT_64_BIT);
uint64_t gpuTimestampCycles = 0;
const vk::QueryPool &queryPool = mGpuEventQueryPool.getQueryPool(eventQuery.queryPoolIndex);
VkResult result = queryPool.getResults(getDevice(), eventQuery.queryIndex, 1,
sizeof(gpuTimestampCycles), &gpuTimestampCycles,
sizeof(gpuTimestampCycles), VK_QUERY_RESULT_64_BIT);
if (result == VK_NOT_READY)
{
break;
......@@ -3805,13 +3795,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
beginInfo.pInheritanceInfo = nullptr;
ANGLE_VK_TRY(this, commandBuffer.begin(beginInfo));
commandBuffer.resetQueryPool(timestampQuery.getQueryPool()->getHandle(),
timestampQuery.getQuery(), 1);
commandBuffer.writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
timestampQuery.getQueryPool()->getHandle(),
timestampQuery.getQuery());
timestampQuery.writeTimestamp(&commandBuffer);
ANGLE_VK_TRY(this, commandBuffer.end());
// Create fence for the submission
......@@ -3842,12 +3826,7 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
ANGLE_VK_TRY(this, fence.get().wait(device, mRenderer->getMaxFenceWaitTimeNs()));
// Get the query results
constexpr VkQueryResultFlags queryFlags = VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT;
ANGLE_VK_TRY(this, timestampQuery.getQueryPool()->getResults(
device, timestampQuery.getQuery(), 1, sizeof(*timestampOut),
timestampOut, sizeof(*timestampOut), queryFlags));
ANGLE_TRY(timestampQuery.getUint64Result(this, timestampOut));
timestampQueryPool.get().freeQuery(this, &timestampQuery);
// Convert results to nanoseconds.
......
......@@ -53,7 +53,7 @@ angle::Result QueryVk::begin(const gl::Context *context)
return angle::Result::Continue;
}
if (!mQueryHelper.getQueryPool())
if (!mQueryHelper.valid())
{
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
}
......@@ -61,13 +61,13 @@ angle::Result QueryVk::begin(const gl::Context *context)
// Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
if (getType() == gl::QueryType::TimeElapsed)
{
if (!mQueryHelperTimeElapsedBegin.getQueryPool())
if (!mQueryHelperTimeElapsedBegin.valid())
{
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(
contextVk, &mQueryHelperTimeElapsedBegin));
}
ANGLE_TRY(mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk));
ANGLE_TRY(mQueryHelperTimeElapsedBegin.flushAndWriteTimestamp(contextVk));
}
else
{
......@@ -98,7 +98,7 @@ angle::Result QueryVk::end(const gl::Context *context)
}
else if (getType() == gl::QueryType::TimeElapsed)
{
ANGLE_TRY(mQueryHelper.writeTimestamp(contextVk));
ANGLE_TRY(mQueryHelper.flushAndWriteTimestamp(contextVk));
}
else
{
......@@ -114,14 +114,14 @@ angle::Result QueryVk::queryCounter(const gl::Context *context)
mCachedResultValid = false;
if (!mQueryHelper.getQueryPool())
if (!mQueryHelper.valid())
{
ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
}
ASSERT(getType() == gl::QueryType::Timestamp);
return mQueryHelper.writeTimestamp(contextVk);
return mQueryHelper.flushAndWriteTimestamp(contextVk);
}
angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
......@@ -159,19 +159,20 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
ANGLE_TRY(contextVk->finishToSerial(mQueryHelper.getStoredQueueSerial()));
}
VkQueryResultFlags flags = (wait ? VK_QUERY_RESULT_WAIT_BIT : 0) | VK_QUERY_RESULT_64_BIT;
VkResult result = mQueryHelper.getQueryPool()->getResults(
contextVk->getDevice(), mQueryHelper.getQuery(), 1, sizeof(mCachedResult), &mCachedResult,
sizeof(mCachedResult), flags);
// If the results are not ready, do nothing. mCachedResultValid remains false.
if (result == VK_NOT_READY)
if (wait)
{
// If VK_QUERY_RESULT_WAIT_BIT was given, VK_NOT_READY cannot have been returned.
ASSERT(!wait);
return angle::Result::Continue;
ANGLE_TRY(mQueryHelper.getUint64Result(contextVk, &mCachedResult));
}
else
{
bool available = false;
ANGLE_TRY(mQueryHelper.getUint64ResultNonBlocking(contextVk, &mCachedResult, &available));
if (!available)
{
// If the results are not ready, do nothing. mCachedResultValid remains false.
return angle::Result::Continue;
}
}
ANGLE_VK_TRY(contextVk, result);
double timestampPeriod = renderer->getPhysicalDeviceProperties().limits.timestampPeriod;
......@@ -190,13 +191,9 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
{
uint64_t timeElapsedEnd = mCachedResult;
result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
contextVk->getDevice(), mQueryHelperTimeElapsedBegin.getQuery(), 1,
sizeof(mCachedResult), &mCachedResult, sizeof(mCachedResult), flags);
// Since the result of the end query of time-elapsed is already available, the
// result of begin query must be available too.
ASSERT(result != VK_NOT_READY);
ANGLE_VK_TRY(contextVk, result);
ANGLE_TRY(mQueryHelperTimeElapsedBegin.getUint64Result(contextVk, &mCachedResult));
mCachedResult = timeElapsedEnd - mCachedResult;
mCachedResult = static_cast<uint64_t>(mCachedResult * timestampPeriod);
......
......@@ -931,7 +931,7 @@ void DynamicQueryPool::destroy(VkDevice device)
angle::Result DynamicQueryPool::allocateQuery(ContextVk *contextVk, QueryHelper *queryOut)
{
ASSERT(!queryOut->getQueryPool());
ASSERT(!queryOut->valid());
size_t poolIndex = 0;
uint32_t queryIndex = 0;
......@@ -944,12 +944,12 @@ angle::Result DynamicQueryPool::allocateQuery(ContextVk *contextVk, QueryHelper
void DynamicQueryPool::freeQuery(ContextVk *contextVk, QueryHelper *query)
{
if (query->getQueryPool())
if (query->valid())
{
size_t poolIndex = query->getQueryPoolIndex();
ASSERT(query->getQueryPool()->valid());
size_t poolIndex = query->mQueryPoolIndex;
ASSERT(getQueryPool(poolIndex).valid());
freeQuery(contextVk, poolIndex, query->getQuery());
freeQuery(contextVk, poolIndex, query->mQuery);
query->deinit();
}
......@@ -1023,7 +1023,7 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->flushAndGetPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
const QueryPool &queryPool = getQueryPool();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->beginQuery(queryPool, mQuery, 0);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
......@@ -1034,23 +1034,27 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk)
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->flushAndGetPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->endQuery(queryPool, mQuery);
primaryCommands->endQuery(getQueryPool(), mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue;
}
angle::Result QueryHelper::writeTimestamp(ContextVk *contextVk)
angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk)
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->flushAndGetPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery);
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(contextVk->flushAndGetPrimaryCommandBuffer(&primary));
writeTimestamp(primary);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue;
}
void QueryHelper::writeTimestamp(vk::PrimaryCommandBuffer *primary)
{
const QueryPool &queryPool = getQueryPool();
primary->resetQueryPool(queryPool, mQuery, 1);
primary->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery);
}
bool QueryHelper::hasPendingWork(ContextVk *contextVk)
{
// If the renderer has a queue serial higher than the stored one, the command buffers that
......@@ -1058,6 +1062,39 @@ bool QueryHelper::hasPendingWork(ContextVk *contextVk)
return mMostRecentSerial == contextVk->getCurrentQueueSerial();
}
angle::Result QueryHelper::getUint64ResultNonBlocking(ContextVk *contextVk,
uint64_t *resultOut,
bool *availableOut)
{
ASSERT(valid());
VkDevice device = contextVk->getDevice();
constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT;
VkResult result = getQueryPool().getResults(device, mQuery, 1, sizeof(uint64_t), resultOut,
sizeof(uint64_t), kFlags);
if (result == VK_NOT_READY)
{
*availableOut = false;
return angle::Result::Continue;
}
else
{
ANGLE_VK_TRY(contextVk, result);
*availableOut = true;
}
return angle::Result::Continue;
}
angle::Result QueryHelper::getUint64Result(ContextVk *contextVk, uint64_t *resultOut)
{
ASSERT(valid());
VkDevice device = contextVk->getDevice();
constexpr VkQueryResultFlags kFlags = VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT;
ANGLE_VK_TRY(contextVk, getQueryPool().getResults(device, mQuery, 1, sizeof(uint64_t),
resultOut, sizeof(uint64_t), kFlags));
return angle::Result::Continue;
}
// DynamicSemaphorePool implementation
DynamicSemaphorePool::DynamicSemaphorePool() = default;
......
......@@ -286,7 +286,7 @@ class DynamicQueryPool final : public DynamicallyGrowingPool<QueryPool>
angle::Result allocateQuery(ContextVk *contextVk, size_t *poolIndex, uint32_t *queryIndex);
void freeQuery(ContextVk *contextVk, size_t poolIndex, uint32_t queryIndex);
const QueryPool *getQueryPool(size_t index) const { return &mPools[index]; }
const QueryPool &getQueryPool(size_t index) const { return mPools[index]; }
private:
angle::Result allocateNewPool(ContextVk *contextVk);
......@@ -315,23 +315,30 @@ class QueryHelper final
uint32_t query);
void deinit();
const QueryPool *getQueryPool() const
{
return mDynamicQueryPool ? mDynamicQueryPool->getQueryPool(mQueryPoolIndex) : nullptr;
}
uint32_t getQuery() const { return mQuery; }
// Used only by DynamicQueryPool.
size_t getQueryPoolIndex() const { return mQueryPoolIndex; }
bool valid() const { return mDynamicQueryPool != nullptr; }
angle::Result beginQuery(ContextVk *contextVk);
angle::Result endQuery(ContextVk *contextVk);
angle::Result writeTimestamp(ContextVk *contextVk);
angle::Result flushAndWriteTimestamp(ContextVk *contextVk);
void writeTimestamp(vk::PrimaryCommandBuffer *primary);
Serial getStoredQueueSerial() { return mMostRecentSerial; }
bool hasPendingWork(ContextVk *contextVk);
angle::Result getUint64ResultNonBlocking(ContextVk *contextVk,
uint64_t *resultOut,
bool *availableOut);
angle::Result getUint64Result(ContextVk *contextVk, uint64_t *resultOut);
private:
friend class DynamicQueryPool;
const QueryPool &getQueryPool() const
{
ASSERT(valid());
return mDynamicQueryPool->getQueryPool(mQueryPoolIndex);
}
const DynamicQueryPool *mDynamicQueryPool;
size_t mQueryPoolIndex;
uint32_t mQuery;
......
......@@ -188,7 +188,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
VkResult begin(const VkCommandBufferBeginInfo &info);
void beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);
void beginQuery(const QueryPool &queryPool, uint32_t query, VkQueryControlFlags flags);
void beginRenderPass(const VkRenderPassBeginInfo &beginInfo, VkSubpassContents subpassContents);
......@@ -294,7 +294,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t stride);
VkResult end();
void endQuery(VkQueryPool queryPool, uint32_t query);
void endQuery(const QueryPool &queryPool, uint32_t query);
void endRenderPass();
void executeCommands(uint32_t commandBufferCount, const CommandBuffer *commandBuffers);
......@@ -338,7 +338,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
VkResult reset();
void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
void resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
void resetQueryPool(const QueryPool &queryPool, uint32_t firstQuery, uint32_t queryCount);
void resolveImage(const Image &srcImage,
VkImageLayout srcImageLayout,
const Image &dstImage,
......@@ -357,7 +357,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
const VkImageMemoryBarrier *imageMemoryBarriers);
void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
VkQueryPool queryPool,
const QueryPool &queryPool,
uint32_t query);
// VK_EXT_transform_feedback
......@@ -916,12 +916,12 @@ ANGLE_INLINE void CommandBuffer::waitEvents(uint32_t eventCount,
imageMemoryBarrierCount, imageMemoryBarriers);
}
ANGLE_INLINE void CommandBuffer::resetQueryPool(VkQueryPool queryPool,
ANGLE_INLINE void CommandBuffer::resetQueryPool(const QueryPool &queryPool,
uint32_t firstQuery,
uint32_t queryCount)
{
ASSERT(valid());
vkCmdResetQueryPool(mHandle, queryPool, firstQuery, queryCount);
ASSERT(valid() && queryPool.valid());
vkCmdResetQueryPool(mHandle, queryPool.getHandle(), firstQuery, queryCount);
}
ANGLE_INLINE void CommandBuffer::resolveImage(const Image &srcImage,
......@@ -936,26 +936,26 @@ ANGLE_INLINE void CommandBuffer::resolveImage(const Image &srcImage,
dstImageLayout, regionCount, regions);
}
ANGLE_INLINE void CommandBuffer::beginQuery(VkQueryPool queryPool,
ANGLE_INLINE void CommandBuffer::beginQuery(const QueryPool &queryPool,
uint32_t query,
VkQueryControlFlags flags)
{
ASSERT(valid());
vkCmdBeginQuery(mHandle, queryPool, query, flags);
ASSERT(valid() && queryPool.valid());
vkCmdBeginQuery(mHandle, queryPool.getHandle(), query, flags);
}
ANGLE_INLINE void CommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
ANGLE_INLINE void CommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
{
ASSERT(valid());
vkCmdEndQuery(mHandle, queryPool, query);
ASSERT(valid() && queryPool.valid());
vkCmdEndQuery(mHandle, queryPool.getHandle(), query);
}
ANGLE_INLINE void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
VkQueryPool queryPool,
const QueryPool &queryPool,
uint32_t query)
{
ASSERT(valid());
vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool, query);
vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool.getHandle(), query);
}
ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount,
......
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