Commit 5b4f6e31 by Jamie Madill Committed by Commit Bot

Vulkan: Add overlay widget for RP buffer count.

Can help evaluate when scenes stress out the resource tracking in the RenderPass command buffer. Bug: angleproject:4950 Bug: angleproject:4965 Change-Id: I7da2ad0101a840c5441f2112db4bb61f564afcef Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2358521 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent d0b270e6
{
"src/libANGLE/Overlay_autogen.cpp":
"7d26b524a7547a19410ea7de72f17b6e",
"eb42853f05350cb01919d63fffdafc5e",
"src/libANGLE/Overlay_autogen.h":
"ba1a6ffb2302b6617d2ae048efcc14d4",
"03ac72d8286f1f933696fa3dabb75eb1",
"src/libANGLE/gen_overlay_widgets.py":
"e596822a0a7ba713510c5427c82ce938",
"src/libANGLE/overlay_widgets.json":
"fea3f9e3b8738c1abdd31fa64d05d883"
"dd9d2a72035e754bbc5f614410e76df1"
}
\ No newline at end of file
......@@ -469,6 +469,7 @@ class FastUnorderedMap final
}
bool empty() const { return mData.empty(); }
size_t size() const { return mData.size(); }
private:
FastVector<Pair, N> mData;
......
......@@ -239,9 +239,11 @@ TEST(FastUnorderedMap, BasicUsage)
{
FastUnorderedMap<int, bool, 3> testMap;
EXPECT_TRUE(testMap.empty());
EXPECT_EQ(testMap.size(), 0u);
testMap.insert(5, true);
EXPECT_TRUE(testMap.contains(5));
EXPECT_EQ(testMap.size(), 1u);
bool value = false;
EXPECT_TRUE(testMap.get(5, &value));
......@@ -251,12 +253,16 @@ TEST(FastUnorderedMap, BasicUsage)
EXPECT_FALSE(testMap.empty());
testMap.clear();
EXPECT_TRUE(testMap.empty());
EXPECT_EQ(testMap.size(), 0u);
for (int i = 0; i < 10; ++i)
{
testMap.insert(i, false);
}
EXPECT_FALSE(testMap.empty());
EXPECT_EQ(testMap.size(), 10u);
for (int i = 0; i < 10; ++i)
{
EXPECT_TRUE(testMap.contains(i));
......
......@@ -87,6 +87,8 @@ class Overlay : angle::NonCopyable
rx::OverlayImpl *getImplementation() const { return mImplementation.get(); }
bool isEnabled() const { return mImplementation != nullptr; }
private:
template <typename Widget, WidgetType Type>
Widget *getWidgetAs(WidgetId id) const
......@@ -122,6 +124,8 @@ class DummyOverlay
const overlay::Dummy *getRunningGraphWidget(WidgetId id) const { return &mDummy; }
const overlay::Dummy *getRunningHistogramWidget(WidgetId id) const { return &mDummy; }
bool isEnabled() const { return false; }
private:
overlay::Dummy mDummy;
};
......
......@@ -400,6 +400,22 @@ void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
format);
}
void AppendWidgetDataHelper::AppendVulkanRenderPassBufferCount(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) {
std::ostringstream text;
text << "RP VkBuffers (Peak: " << peakRange << ", Max: " << maxValueRange << ")";
return text.str();
};
AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts,
format);
}
void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
......
......@@ -147,6 +147,49 @@ void Overlay::initOverlayWidgets()
}
{
RunningHistogram *widget = new RunningHistogram(100);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
const int32_t offsetX = -50;
const int32_t offsetY = 100;
const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
const int32_t height = 100;
widget->type = WidgetType::RunningHistogram;
widget->fontSize = fontSize;
widget->coords[0] = offsetX - width;
widget->coords[1] = offsetY;
widget->coords[2] = offsetX;
widget->coords[3] = offsetY + height;
widget->color[0] = 1.0;
widget->color[1] = 0.78431372549;
widget->color[2] = 0.294117647059;
widget->color[3] = 0.78431372549;
}
mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount].reset(widget);
{
const int32_t fontSize = GetFontSize(kFontLayerSmall, kLargeFont);
const int32_t offsetX =
mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[0];
const int32_t offsetY =
mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[1];
const int32_t width = 40 * kFontGlyphWidths[fontSize];
const int32_t height = kFontGlyphHeights[fontSize];
widget->description.type = WidgetType::Text;
widget->description.fontSize = fontSize;
widget->description.coords[0] = offsetX;
widget->description.coords[1] = std::max(offsetY - height, 1);
widget->description.coords[2] = std::min(offsetX + width, -1);
widget->description.coords[3] = offsetY;
widget->description.color[0] = 1.0;
widget->description.color[1] = 0.78431372549;
widget->description.color[2] = 0.294117647059;
widget->description.color[3] = 1.0;
}
}
{
RunningHistogram *widget = new RunningHistogram(50);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
......
......@@ -20,6 +20,8 @@ enum class WidgetId
VulkanValidationMessageCount,
// Number of RenderPasses in a frame (Count).
VulkanRenderPassCount,
// Number of buffers used in RenderPasses (Count).
VulkanRenderPassBufferCount,
// Secondary Command Buffer pool memory waste (Bytes).
VulkanSecondaryCommandBufferPoolWaste,
// Number of Descriptor Set writes in a frame (Count).
......@@ -35,6 +37,7 @@ enum class WidgetId
PROC(VulkanLastValidationMessage) \
PROC(VulkanValidationMessageCount) \
PROC(VulkanRenderPassCount) \
PROC(VulkanRenderPassBufferCount) \
PROC(VulkanSecondaryCommandBufferPoolWaste) \
PROC(VulkanWriteDescriptorSetCount)
......
......@@ -71,6 +71,22 @@
}
},
{
"name": "VulkanRenderPassBufferCount",
"comment": "Number of buffers used in RenderPasses (Count).",
"type": "RunningHistogram(100)",
"color": [255, 200, 75, 200],
"coords": [-50, 100],
"bar_width": 6,
"height": 100,
"description": {
"color": [255, 200, 75, 255],
"coords": ["VulkanRenderPassBufferCount.left.align",
"VulkanRenderPassBufferCount.top.adjacent"],
"font": "small",
"length": 40
}
},
{
"name": "VulkanSecondaryCommandBufferPoolWaste",
"comment": "Secondary Command Buffer pool memory waste (Bytes).",
"type": "RunningHistogram(50)",
......
......@@ -1610,17 +1610,20 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
void ContextVk::updateOverlayOnPresent()
{
const gl::OverlayType *overlay = mState.getOverlay();
ASSERT(overlay->isEnabled());
// Update overlay if active.
{
gl::RunningGraphWidget *renderPassCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
overlay->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
renderPassCount->add(mRenderPassCommands->getAndResetCounter());
renderPassCount->next();
}
{
gl::RunningGraphWidget *writeDescriptorSetCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount);
overlay->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount);
writeDescriptorSetCount->add(mPerfCounters.writeDescriptorSets);
writeDescriptorSetCount->next();
......@@ -1628,6 +1631,24 @@ void ContextVk::updateOverlayOnPresent()
}
}
void ContextVk::addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer)
{
const gl::OverlayType *overlay = mState.getOverlay();
if (!overlay->isEnabled())
{
return;
}
gl::RunningHistogramWidget *widget =
overlay->getRunningHistogramWidget(gl::WidgetId::VulkanRenderPassBufferCount);
size_t buffersCount = commandBuffer->getUsedBuffersCount();
if (buffersCount > 0)
{
widget->add(buffersCount);
widget->next();
}
}
angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer)
{
......@@ -4483,6 +4504,8 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass()
ANGLE_TRY(flushOutsideRenderPassCommands());
}
addOverlayUsedBuffersCount(mRenderPassCommands);
mRenderPassCommands->endRenderPass();
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
......@@ -4616,6 +4639,8 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
return angle::Result::Continue;
}
addOverlayUsedBuffersCount(mOutsideRenderPassCommands);
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
{
vk::CommandProcessorTask task = {this, &mPrimaryCommands, mOutsideRenderPassCommands};
......
......@@ -601,6 +601,7 @@ class ContextVk : public ContextImpl, public vk::Context
void endOcclusionQuery(QueryVk *queryVk);
void updateOverlayOnPresent();
void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer);
// Submit commands to worker thread for processing
ANGLE_INLINE void queueCommandsToWorker(const vk::CommandProcessorTask &commands)
......
......@@ -1637,19 +1637,18 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context,
void WindowSurfaceVk::updateOverlay(ContextVk *contextVk) const
{
const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay);
// If overlay is disabled, nothing to do.
if (overlayVk == nullptr)
if (!overlay->isEnabled())
{
return;
}
RendererVk *rendererVk = contextVk->getRenderer();
RendererVk *renderer = contextVk->getRenderer();
uint32_t validationMessageCount = 0;
std::string lastValidationMessage =
rendererVk->getAndClearLastValidationMessage(&validationMessageCount);
renderer->getAndClearLastValidationMessage(&validationMessageCount);
if (validationMessageCount)
{
overlay->getTextWidget(gl::WidgetId::VulkanLastValidationMessage)
......
......@@ -976,6 +976,7 @@ class CommandBufferHelper : angle::NonCopyable
bool usesBuffer(const BufferHelper &buffer) const;
bool usesBufferForWrite(const BufferHelper &buffer) const;
bool usesImageInRenderPass(const ImageHelper &image) const;
size_t getUsedBuffersCount() const { return mUsedBuffers.size(); }
// Dumping the command stream is disabled by default.
static constexpr bool kEnableCommandStreamDiagnostics = false;
......
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