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": "src/libANGLE/Overlay_autogen.cpp":
"7d26b524a7547a19410ea7de72f17b6e", "eb42853f05350cb01919d63fffdafc5e",
"src/libANGLE/Overlay_autogen.h": "src/libANGLE/Overlay_autogen.h":
"ba1a6ffb2302b6617d2ae048efcc14d4", "03ac72d8286f1f933696fa3dabb75eb1",
"src/libANGLE/gen_overlay_widgets.py": "src/libANGLE/gen_overlay_widgets.py":
"e596822a0a7ba713510c5427c82ce938", "e596822a0a7ba713510c5427c82ce938",
"src/libANGLE/overlay_widgets.json": "src/libANGLE/overlay_widgets.json":
"fea3f9e3b8738c1abdd31fa64d05d883" "dd9d2a72035e754bbc5f614410e76df1"
} }
\ No newline at end of file
...@@ -469,6 +469,7 @@ class FastUnorderedMap final ...@@ -469,6 +469,7 @@ class FastUnorderedMap final
} }
bool empty() const { return mData.empty(); } bool empty() const { return mData.empty(); }
size_t size() const { return mData.size(); }
private: private:
FastVector<Pair, N> mData; FastVector<Pair, N> mData;
......
...@@ -239,9 +239,11 @@ TEST(FastUnorderedMap, BasicUsage) ...@@ -239,9 +239,11 @@ TEST(FastUnorderedMap, BasicUsage)
{ {
FastUnorderedMap<int, bool, 3> testMap; FastUnorderedMap<int, bool, 3> testMap;
EXPECT_TRUE(testMap.empty()); EXPECT_TRUE(testMap.empty());
EXPECT_EQ(testMap.size(), 0u);
testMap.insert(5, true); testMap.insert(5, true);
EXPECT_TRUE(testMap.contains(5)); EXPECT_TRUE(testMap.contains(5));
EXPECT_EQ(testMap.size(), 1u);
bool value = false; bool value = false;
EXPECT_TRUE(testMap.get(5, &value)); EXPECT_TRUE(testMap.get(5, &value));
...@@ -251,12 +253,16 @@ TEST(FastUnorderedMap, BasicUsage) ...@@ -251,12 +253,16 @@ TEST(FastUnorderedMap, BasicUsage)
EXPECT_FALSE(testMap.empty()); EXPECT_FALSE(testMap.empty());
testMap.clear(); testMap.clear();
EXPECT_TRUE(testMap.empty()); EXPECT_TRUE(testMap.empty());
EXPECT_EQ(testMap.size(), 0u);
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
testMap.insert(i, false); testMap.insert(i, false);
} }
EXPECT_FALSE(testMap.empty());
EXPECT_EQ(testMap.size(), 10u);
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
EXPECT_TRUE(testMap.contains(i)); EXPECT_TRUE(testMap.contains(i));
......
...@@ -87,6 +87,8 @@ class Overlay : angle::NonCopyable ...@@ -87,6 +87,8 @@ class Overlay : angle::NonCopyable
rx::OverlayImpl *getImplementation() const { return mImplementation.get(); } rx::OverlayImpl *getImplementation() const { return mImplementation.get(); }
bool isEnabled() const { return mImplementation != nullptr; }
private: private:
template <typename Widget, WidgetType Type> template <typename Widget, WidgetType Type>
Widget *getWidgetAs(WidgetId id) const Widget *getWidgetAs(WidgetId id) const
...@@ -122,6 +124,8 @@ class DummyOverlay ...@@ -122,6 +124,8 @@ class DummyOverlay
const overlay::Dummy *getRunningGraphWidget(WidgetId id) const { return &mDummy; } const overlay::Dummy *getRunningGraphWidget(WidgetId id) const { return &mDummy; }
const overlay::Dummy *getRunningHistogramWidget(WidgetId id) const { return &mDummy; } const overlay::Dummy *getRunningHistogramWidget(WidgetId id) const { return &mDummy; }
bool isEnabled() const { return false; }
private: private:
overlay::Dummy mDummy; overlay::Dummy mDummy;
}; };
......
...@@ -400,6 +400,22 @@ void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste( ...@@ -400,6 +400,22 @@ void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
format); 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, void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget,
const gl::Extents &imageExtent, const gl::Extents &imageExtent,
TextWidgetData *textWidget, TextWidgetData *textWidget,
......
...@@ -147,6 +147,49 @@ void Overlay::initOverlayWidgets() ...@@ -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); RunningHistogram *widget = new RunningHistogram(50);
{ {
const int32_t fontSize = GetFontSize(0, kLargeFont); const int32_t fontSize = GetFontSize(0, kLargeFont);
......
...@@ -20,6 +20,8 @@ enum class WidgetId ...@@ -20,6 +20,8 @@ enum class WidgetId
VulkanValidationMessageCount, VulkanValidationMessageCount,
// Number of RenderPasses in a frame (Count). // Number of RenderPasses in a frame (Count).
VulkanRenderPassCount, VulkanRenderPassCount,
// Number of buffers used in RenderPasses (Count).
VulkanRenderPassBufferCount,
// Secondary Command Buffer pool memory waste (Bytes). // Secondary Command Buffer pool memory waste (Bytes).
VulkanSecondaryCommandBufferPoolWaste, VulkanSecondaryCommandBufferPoolWaste,
// Number of Descriptor Set writes in a frame (Count). // Number of Descriptor Set writes in a frame (Count).
...@@ -35,6 +37,7 @@ enum class WidgetId ...@@ -35,6 +37,7 @@ enum class WidgetId
PROC(VulkanLastValidationMessage) \ PROC(VulkanLastValidationMessage) \
PROC(VulkanValidationMessageCount) \ PROC(VulkanValidationMessageCount) \
PROC(VulkanRenderPassCount) \ PROC(VulkanRenderPassCount) \
PROC(VulkanRenderPassBufferCount) \
PROC(VulkanSecondaryCommandBufferPoolWaste) \ PROC(VulkanSecondaryCommandBufferPoolWaste) \
PROC(VulkanWriteDescriptorSetCount) PROC(VulkanWriteDescriptorSetCount)
......
...@@ -71,6 +71,22 @@ ...@@ -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", "name": "VulkanSecondaryCommandBufferPoolWaste",
"comment": "Secondary Command Buffer pool memory waste (Bytes).", "comment": "Secondary Command Buffer pool memory waste (Bytes).",
"type": "RunningHistogram(50)", "type": "RunningHistogram(50)",
......
...@@ -1610,17 +1610,20 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context, ...@@ -1610,17 +1610,20 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
void ContextVk::updateOverlayOnPresent() void ContextVk::updateOverlayOnPresent()
{ {
const gl::OverlayType *overlay = mState.getOverlay();
ASSERT(overlay->isEnabled());
// Update overlay if active. // Update overlay if active.
{ {
gl::RunningGraphWidget *renderPassCount = gl::RunningGraphWidget *renderPassCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount); overlay->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
renderPassCount->add(mRenderPassCommands->getAndResetCounter()); renderPassCount->add(mRenderPassCommands->getAndResetCounter());
renderPassCount->next(); renderPassCount->next();
} }
{ {
gl::RunningGraphWidget *writeDescriptorSetCount = gl::RunningGraphWidget *writeDescriptorSetCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount); overlay->getRunningGraphWidget(gl::WidgetId::VulkanWriteDescriptorSetCount);
writeDescriptorSetCount->add(mPerfCounters.writeDescriptorSets); writeDescriptorSetCount->add(mPerfCounters.writeDescriptorSets);
writeDescriptorSetCount->next(); writeDescriptorSetCount->next();
...@@ -1628,6 +1631,24 @@ void ContextVk::updateOverlayOnPresent() ...@@ -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, angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer) vk::PrimaryCommandBuffer &&commandBuffer)
{ {
...@@ -4483,6 +4504,8 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass() ...@@ -4483,6 +4504,8 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass()
ANGLE_TRY(flushOutsideRenderPassCommands()); ANGLE_TRY(flushOutsideRenderPassCommands());
} }
addOverlayUsedBuffersCount(mRenderPassCommands);
mRenderPassCommands->endRenderPass(); mRenderPassCommands->endRenderPass();
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled) if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
...@@ -4616,6 +4639,8 @@ angle::Result ContextVk::flushOutsideRenderPassCommands() ...@@ -4616,6 +4639,8 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
return angle::Result::Continue; return angle::Result::Continue;
} }
addOverlayUsedBuffersCount(mOutsideRenderPassCommands);
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled) if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
{ {
vk::CommandProcessorTask task = {this, &mPrimaryCommands, mOutsideRenderPassCommands}; vk::CommandProcessorTask task = {this, &mPrimaryCommands, mOutsideRenderPassCommands};
......
...@@ -601,6 +601,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -601,6 +601,7 @@ class ContextVk : public ContextImpl, public vk::Context
void endOcclusionQuery(QueryVk *queryVk); void endOcclusionQuery(QueryVk *queryVk);
void updateOverlayOnPresent(); void updateOverlayOnPresent();
void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer);
// Submit commands to worker thread for processing // Submit commands to worker thread for processing
ANGLE_INLINE void queueCommandsToWorker(const vk::CommandProcessorTask &commands) ANGLE_INLINE void queueCommandsToWorker(const vk::CommandProcessorTask &commands)
......
...@@ -1637,19 +1637,18 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context, ...@@ -1637,19 +1637,18 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context,
void WindowSurfaceVk::updateOverlay(ContextVk *contextVk) const void WindowSurfaceVk::updateOverlay(ContextVk *contextVk) const
{ {
const gl::OverlayType *overlay = contextVk->getOverlay(); const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay);
// If overlay is disabled, nothing to do. // If overlay is disabled, nothing to do.
if (overlayVk == nullptr) if (!overlay->isEnabled())
{ {
return; return;
} }
RendererVk *rendererVk = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
uint32_t validationMessageCount = 0; uint32_t validationMessageCount = 0;
std::string lastValidationMessage = std::string lastValidationMessage =
rendererVk->getAndClearLastValidationMessage(&validationMessageCount); renderer->getAndClearLastValidationMessage(&validationMessageCount);
if (validationMessageCount) if (validationMessageCount)
{ {
overlay->getTextWidget(gl::WidgetId::VulkanLastValidationMessage) overlay->getTextWidget(gl::WidgetId::VulkanLastValidationMessage)
......
...@@ -976,6 +976,7 @@ class CommandBufferHelper : angle::NonCopyable ...@@ -976,6 +976,7 @@ class CommandBufferHelper : angle::NonCopyable
bool usesBuffer(const BufferHelper &buffer) const; bool usesBuffer(const BufferHelper &buffer) const;
bool usesBufferForWrite(const BufferHelper &buffer) const; bool usesBufferForWrite(const BufferHelper &buffer) const;
bool usesImageInRenderPass(const ImageHelper &image) const; bool usesImageInRenderPass(const ImageHelper &image) const;
size_t getUsedBuffersCount() const { return mUsedBuffers.size(); }
// Dumping the command stream is disabled by default. // Dumping the command stream is disabled by default.
static constexpr bool kEnableCommandStreamDiagnostics = false; 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