Skip to content

Commit

Permalink
Vulkan: Use QueryHelper for internal GPU timing.
Browse files Browse the repository at this point in the history
This cleans up the code. Using QueryHelper means we don't need to
duplicate the timestamp query/result code. It also means we don't need
special allocate/free functions in DynamicQueryPool.

Done while investigating timing GPU events for T-Rex.

Bug: angleproject:4433
Change-Id: I8512a5618e1dd00956942ae2d12d46d8193c4e51
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2081379
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
  • Loading branch information
null77 authored and Commit Bot committed Mar 3, 2020
1 parent 4fb2994 commit b84969a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 65 deletions.
46 changes: 18 additions & 28 deletions src/libANGLE/renderer/vulkan/ContextVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1678,22 +1678,14 @@ angle::Result ContextVk::traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuff
{
ASSERT(mGpuEventsEnabled);

GpuEventQuery event;
GpuEventQuery gpuEvent;
gpuEvent.name = name;
gpuEvent.phase = phase;
ANGLE_TRY(mGpuEventQueryPool.allocateQuery(this, &gpuEvent.queryHelper));

event.name = name;
event.phase = phase;
event.serial = getCurrentQueueSerial();

ANGLE_TRY(mGpuEventQueryPool.allocateQuery(this, &event.queryPoolIndex, &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));
gpuEvent.queryHelper.writeTimestamp(commandBuffer);

mInFlightGpuEventQueries.push_back(std::move(gpuEvent));
return angle::Result::Continue;
}

Expand All @@ -1711,31 +1703,29 @@ angle::Result ContextVk::checkCompletedGpuEvents()
for (GpuEventQuery &eventQuery : mInFlightGpuEventQueries)
{
// Only check the timestamp query if the submission has finished.
if (eventQuery.serial > lastCompletedSerial)
if (eventQuery.queryHelper.getStoredQueueSerial() > lastCompletedSerial)
{
break;
}

// See if the results are available.
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)
uint64_t gpuTimestampCycles = 0;
bool available = false;
ANGLE_TRY(eventQuery.queryHelper.getUint64ResultNonBlocking(this, &gpuTimestampCycles,
&available));
if (!available)
{
break;
}
ANGLE_VK_TRY(this, result);

mGpuEventQueryPool.freeQuery(this, eventQuery.queryPoolIndex, eventQuery.queryIndex);
mGpuEventQueryPool.freeQuery(this, &eventQuery.queryHelper);

GpuEvent event;
event.gpuTimestampCycles = gpuTimestampCycles;
event.name = eventQuery.name;
event.phase = eventQuery.phase;
GpuEvent gpuEvent;
gpuEvent.gpuTimestampCycles = gpuTimestampCycles;
gpuEvent.name = eventQuery.name;
gpuEvent.phase = eventQuery.phase;

mGpuEvents.emplace_back(event);
mGpuEvents.emplace_back(gpuEvent);

++finishedCount;
}
Expand Down
6 changes: 1 addition & 5 deletions src/libANGLE/renderer/vulkan/ContextVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,7 @@ class ContextVk : public ContextImpl, public vk::Context
{
const char *name;
char phase;

uint32_t queryIndex;
size_t queryPoolIndex;

Serial serial;
vk::QueryHelper queryHelper;
};

// Once a query result is available, the timestamp is read and a GpuEvent object is kept until
Expand Down
35 changes: 8 additions & 27 deletions src/libANGLE/renderer/vulkan/vk_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,11 +933,14 @@ angle::Result DynamicQueryPool::allocateQuery(ContextVk *contextVk, QueryHelper
{
ASSERT(!queryOut->valid());

size_t poolIndex = 0;
uint32_t queryIndex = 0;
ANGLE_TRY(allocateQuery(contextVk, &poolIndex, &queryIndex));
if (mCurrentFreeEntry >= mPoolSize)
{
// No more queries left in this pool, create another one.
ANGLE_TRY(allocateNewPool(contextVk));
}

queryOut->init(this, poolIndex, queryIndex);
uint32_t queryIndex = mCurrentFreeEntry++;
queryOut->init(this, mCurrentPool, queryIndex);

return angle::Result::Continue;
}
Expand All @@ -949,34 +952,12 @@ void DynamicQueryPool::freeQuery(ContextVk *contextVk, QueryHelper *query)
size_t poolIndex = query->mQueryPoolIndex;
ASSERT(getQueryPool(poolIndex).valid());

freeQuery(contextVk, poolIndex, query->mQuery);
onEntryFreed(contextVk, poolIndex);

query->deinit();
}
}

angle::Result DynamicQueryPool::allocateQuery(ContextVk *contextVk,
size_t *poolIndex,
uint32_t *queryIndex)
{
if (mCurrentFreeEntry >= mPoolSize)
{
// No more queries left in this pool, create another one.
ANGLE_TRY(allocateNewPool(contextVk));
}

*poolIndex = mCurrentPool;
*queryIndex = mCurrentFreeEntry++;

return angle::Result::Continue;
}

void DynamicQueryPool::freeQuery(ContextVk *contextVk, size_t poolIndex, uint32_t queryIndex)
{
ANGLE_UNUSED_VARIABLE(queryIndex);
onEntryFreed(contextVk, poolIndex);
}

angle::Result DynamicQueryPool::allocateNewPool(ContextVk *contextVk)
{
if (findFreeEntryPool(contextVk))
Expand Down
5 changes: 0 additions & 5 deletions src/libANGLE/renderer/vulkan/vk_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,6 @@ class DynamicQueryPool final : public DynamicallyGrowingPool<QueryPool>
angle::Result allocateQuery(ContextVk *contextVk, QueryHelper *queryOut);
void freeQuery(ContextVk *contextVk, QueryHelper *query);

// Special allocator that doesn't work with QueryHelper, which is a CommandGraphResource.
// Currently only used with RendererVk::GpuEventQuery.
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]; }

private:
Expand Down

0 comments on commit b84969a

Please sign in to comment.