Commit 18dd0c28 by Jamie Madill Committed by Commit Bot

Vulkan: Add command buffer performance counter.

Adds a counter for the secondary command buffers (non-RenderPass). We'll use this in an upcoming test that validates that ANGLE only issues a single barrier (CB) in some buffer read/write scenarios. Also adds a PerfCounters struct. Bug: angleproject:4429 Change-Id: Iaf75ca89da3d02753897cb4066e2c56db497417e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2334090Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent ea952ff3
...@@ -655,9 +655,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -655,9 +655,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mGpuEventsEnabled(false), mGpuEventsEnabled(false),
mGpuClockSync{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()}, mGpuClockSync{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()},
mGpuEventTimestampOrigin(0), mGpuEventTimestampOrigin(0),
mPrimaryBufferCounter(0), mPerfCounters{},
mRenderPassCounter(0),
mWriteDescriptorSetCounter(0),
mContextPriority(renderer->getDriverPriority(GetContextPriority(state))), mContextPriority(renderer->getDriverPriority(GetContextPriority(state))),
mCurrentIndirectBuffer(nullptr), mCurrentIndirectBuffer(nullptr),
mShareGroupVk(vk::GetImpl(state.getShareGroup())) mShareGroupVk(vk::GetImpl(state.getShareGroup()))
...@@ -904,9 +902,9 @@ angle::Result ContextVk::initialize() ...@@ -904,9 +902,9 @@ angle::Result ContextVk::initialize()
vk::kDefaultTimestampQueryPoolSize)); vk::kDefaultTimestampQueryPoolSize));
ANGLE_TRY(synchronizeCpuGpuTime()); ANGLE_TRY(synchronizeCpuGpuTime());
mPrimaryBufferCounter++; mPerfCounters.primaryBuffers++;
EventName eventName = GetTraceEventName("Primary", mPrimaryBufferCounter); EventName eventName = GetTraceEventName("Primary", mPerfCounters.primaryBuffers);
ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(), ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(),
TRACE_EVENT_PHASE_BEGIN, eventName)); TRACE_EVENT_PHASE_BEGIN, eventName));
} }
...@@ -1631,10 +1629,10 @@ void ContextVk::updateOverlayOnPresent() ...@@ -1631,10 +1629,10 @@ void ContextVk::updateOverlayOnPresent()
{ {
gl::RunningGraphWidget *writeDescriptorSetCount = gl::RunningGraphWidget *writeDescriptorSetCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount); mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount);
writeDescriptorSetCount->add(mWriteDescriptorSetCounter); writeDescriptorSetCount->add(mPerfCounters.writeDescriptorSets);
writeDescriptorSetCount->next(); writeDescriptorSetCount->next();
mWriteDescriptorSetCounter = 0; mPerfCounters.writeDescriptorSets = 0;
} }
} }
...@@ -4003,7 +4001,7 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore) ...@@ -4003,7 +4001,7 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
if (mGpuEventsEnabled) if (mGpuEventsEnabled)
{ {
EventName eventName = GetTraceEventName("Primary", mPrimaryBufferCounter); EventName eventName = GetTraceEventName("Primary", mPerfCounters.primaryBuffers);
ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(), ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(),
TRACE_EVENT_PHASE_END, eventName)); TRACE_EVENT_PHASE_END, eventName));
} }
...@@ -4042,17 +4040,18 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore) ...@@ -4042,17 +4040,18 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
ANGLE_TRY(startPrimaryCommandBuffer()); ANGLE_TRY(startPrimaryCommandBuffer());
mRenderPassCounter = 0; mPerfCounters.renderPasses = 0;
mWriteDescriptorSetCounter = 0; mPerfCounters.writeDescriptorSets = 0;
mPerfCounters.flushedOutsideRenderPassCommandBuffers = 0;
mWaitSemaphores.clear(); mWaitSemaphores.clear();
mWaitSemaphoreStageMasks.clear(); mWaitSemaphoreStageMasks.clear();
mPrimaryBufferCounter++; mPerfCounters.primaryBuffers++;
if (mGpuEventsEnabled) if (mGpuEventsEnabled)
{ {
EventName eventName = GetTraceEventName("Primary", mPrimaryBufferCounter); EventName eventName = GetTraceEventName("Primary", mPerfCounters.primaryBuffers);
ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(), ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(),
TRACE_EVENT_PHASE_BEGIN, eventName)); TRACE_EVENT_PHASE_BEGIN, eventName));
} }
...@@ -4480,11 +4479,11 @@ angle::Result ContextVk::endRenderPass() ...@@ -4480,11 +4479,11 @@ angle::Result ContextVk::endRenderPass()
onRenderPassFinished(); onRenderPassFinished();
mRenderPassCounter++; mPerfCounters.renderPasses++;
if (mGpuEventsEnabled) if (mGpuEventsEnabled)
{ {
EventName eventName = GetTraceEventName("RP", mRenderPassCounter); EventName eventName = GetTraceEventName("RP", mPerfCounters.renderPasses);
ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(), ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(),
TRACE_EVENT_PHASE_BEGIN, eventName)); TRACE_EVENT_PHASE_BEGIN, eventName));
ANGLE_TRY(flushOutsideRenderPassCommands()); ANGLE_TRY(flushOutsideRenderPassCommands());
...@@ -4508,7 +4507,7 @@ angle::Result ContextVk::endRenderPass() ...@@ -4508,7 +4507,7 @@ angle::Result ContextVk::endRenderPass()
if (mGpuEventsEnabled) if (mGpuEventsEnabled)
{ {
EventName eventName = GetTraceEventName("RP", mRenderPassCounter); EventName eventName = GetTraceEventName("RP", mPerfCounters.renderPasses);
ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(), ANGLE_TRY(traceGpuEvent(&mOutsideRenderPassCommands->getCommandBuffer(),
TRACE_EVENT_PHASE_END, eventName)); TRACE_EVENT_PHASE_END, eventName));
ANGLE_TRY(flushOutsideRenderPassCommands()); ANGLE_TRY(flushOutsideRenderPassCommands());
...@@ -4642,6 +4641,7 @@ angle::Result ContextVk::flushOutsideRenderPassCommands() ...@@ -4642,6 +4641,7 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
ANGLE_TRY(mOutsideRenderPassCommands->flushToPrimary(this, &mPrimaryCommands)); ANGLE_TRY(mOutsideRenderPassCommands->flushToPrimary(this, &mPrimaryCommands));
} }
mHasPrimaryCommands = true; mHasPrimaryCommands = true;
mPerfCounters.flushedOutsideRenderPassCommandBuffers++;
} }
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -4747,7 +4747,7 @@ VkDescriptorImageInfo *ContextVk::allocDescriptorImageInfos(size_t count) ...@@ -4747,7 +4747,7 @@ VkDescriptorImageInfo *ContextVk::allocDescriptorImageInfos(size_t count)
VkWriteDescriptorSet *ContextVk::allocWriteDescriptorSets(size_t count) VkWriteDescriptorSet *ContextVk::allocWriteDescriptorSets(size_t count)
{ {
mWriteDescriptorSetCounter += count; mPerfCounters.writeDescriptorSets += count;
size_t oldSize = mWriteDescriptorSets.size(); size_t oldSize = mWriteDescriptorSets.size();
size_t newSize = oldSize + count; size_t newSize = oldSize + count;
......
...@@ -596,8 +596,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -596,8 +596,7 @@ class ContextVk : public ContextImpl, public vk::Context
vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; } vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
vk::DynamicBuffer *getStagingBufferStorage() { return &mStagingBufferStorage; } vk::DynamicBuffer *getStagingBufferStorage() { return &mStagingBufferStorage; }
uint32_t getRenderPassCounter() const { return mRenderPassCounter; } const vk::PerfCounters &getPerfCounters() const { return mPerfCounters; }
uint32_t getWriteDescriptorSetCounter() const { return mWriteDescriptorSetCounter; }
private: private:
// Dirty bits. // Dirty bits.
...@@ -1048,10 +1047,8 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -1048,10 +1047,8 @@ class ContextVk : public ContextImpl, public vk::Context
// double. // double.
uint64_t mGpuEventTimestampOrigin; uint64_t mGpuEventTimestampOrigin;
// Used to count events for tracing. // A mix of per-frame and per-run counters.
uint32_t mPrimaryBufferCounter; vk::PerfCounters mPerfCounters;
uint32_t mRenderPassCounter;
uint32_t mWriteDescriptorSetCounter;
gl::State::DirtyBits mPipelineDirtyBitsMask; gl::State::DirtyBits mPipelineDirtyBitsMask;
......
...@@ -743,6 +743,15 @@ class ResourceSerialFactory final : angle::NonCopyable ...@@ -743,6 +743,15 @@ class ResourceSerialFactory final : angle::NonCopyable
// Kept atomic so it can be accessed from multiple Context threads at once. // Kept atomic so it can be accessed from multiple Context threads at once.
std::atomic<uint32_t> mCurrentUniqueSerial; std::atomic<uint32_t> mCurrentUniqueSerial;
}; };
// Performance and resource counters.
struct PerfCounters
{
uint32_t primaryBuffers;
uint32_t renderPasses;
uint32_t writeDescriptorSets;
uint32_t flushedOutsideRenderPassCommandBuffers;
};
} // namespace vk } // namespace vk
#if !defined(ANGLE_SHARED_LIBVULKAN) #if !defined(ANGLE_SHARED_LIBVULKAN)
......
...@@ -28,11 +28,11 @@ namespace ...@@ -28,11 +28,11 @@ namespace
class VulkanPerformanceCounterTest : public ANGLETest class VulkanPerformanceCounterTest : public ANGLETest
{ {
protected: protected:
rx::ContextVk *hackANGLE() const const rx::vk::PerfCounters &hackANGLE() const
{ {
// Hack the angle! // Hack the angle!
const gl::Context *context = static_cast<gl::Context *>(getEGLWindow()->getContext()); const gl::Context *context = static_cast<gl::Context *>(getEGLWindow()->getContext());
return rx::GetImplAs<rx::ContextVk>(context); return rx::GetImplAs<rx::ContextVk>(context)->getPerfCounters();
} }
}; };
...@@ -42,7 +42,7 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) ...@@ -42,7 +42,7 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass)
// TODO(jmadill): Fix test. http://anglebug.com/4911 // TODO(jmadill): Fix test. http://anglebug.com/4911
ANGLE_SKIP_TEST_IF(IsVulkan()); ANGLE_SKIP_TEST_IF(IsVulkan());
rx::ContextVk *contextVk = hackANGLE(); const rx::vk::PerfCounters &counters = hackANGLE();
GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow}; GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow};
...@@ -72,7 +72,7 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) ...@@ -72,7 +72,7 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass)
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
uint32_t expectedRenderPassCount = contextVk->getRenderPassCounter(); uint32_t expectedRenderPassCount = counters.renderPasses;
// Step 2: Introduce a new 2D Texture with the same Program and Framebuffer. // Step 2: Introduce a new 2D Texture with the same Program and Framebuffer.
GLTexture newTexture; GLTexture newTexture;
...@@ -84,14 +84,14 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) ...@@ -84,14 +84,14 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass)
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
uint32_t actualRenderPassCount = contextVk->getRenderPassCounter(); uint32_t actualRenderPassCount = counters.renderPasses;
EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
} }
// Tests that changing a Texture's max level hits the descriptor set cache. // Tests that changing a Texture's max level hits the descriptor set cache.
TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache) TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache)
{ {
rx::ContextVk *contextVk = hackANGLE(); const rx::vk::PerfCounters &counters = hackANGLE();
GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow}; GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow};
...@@ -129,14 +129,14 @@ TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache) ...@@ -129,14 +129,14 @@ TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache)
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
uint32_t expectedWriteDescriptorSetCount = contextVk->getWriteDescriptorSetCounter(); uint32_t expectedWriteDescriptorSetCount = counters.writeDescriptorSets;
// Step 3: Change max level back to original value and verify we hit the cache. // Step 3: Change max level back to original value and verify we hit the cache.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
uint32_t actualWriteDescriptorSetCount = contextVk->getWriteDescriptorSetCounter(); uint32_t actualWriteDescriptorSetCount = counters.writeDescriptorSets;
EXPECT_EQ(expectedWriteDescriptorSetCount, actualWriteDescriptorSetCount); EXPECT_EQ(expectedWriteDescriptorSetCount, actualWriteDescriptorSetCount);
} }
......
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