Vulkan: Count active renderpasses in overlay.
Useful debugging information for benchmarks. Also helpful when working
with the command graph to ensure we don't regress performance.
Bug: angleproject:4029
Bug: angleproject:4320
Change-Id: Ibe224c40a3acaca9231bf3869486a0f8bba07ba0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2036402
Reviewed-by: Tim Van Patten <timvp@google.com>
Reviewed-by: Tobin Ehlis <tobine@google.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/scripts/code_generation_hashes/overlay_widgets.json b/scripts/code_generation_hashes/overlay_widgets.json
index edfd26a..17b89b1 100644
--- a/scripts/code_generation_hashes/overlay_widgets.json
+++ b/scripts/code_generation_hashes/overlay_widgets.json
@@ -1,8 +1,8 @@
{
"src/libANGLE/Overlay_autogen.cpp":
- "514b8108f62ef616c296dc511bb2f644",
+ "1c882462aacb436dbd88d6e7fdbe4473",
"src/libANGLE/gen_overlay_widgets.py":
"07252fbde304fd48559ae07f8f920a08",
"src/libANGLE/overlay_widgets.json":
- "552b1e2883a12c38d427c7fbd1c2bf22"
+ "c84d5c85c6bd21d30056ad2fb9213e38"
}
\ No newline at end of file
diff --git a/src/libANGLE/Overlay.cpp b/src/libANGLE/Overlay.cpp
index 2de65d2..4a09331 100644
--- a/src/libANGLE/Overlay.cpp
+++ b/src/libANGLE/Overlay.cpp
@@ -26,6 +26,7 @@
{"VulkanLastValidationMessage", WidgetId::VulkanLastValidationMessage},
{"VulkanValidationMessageCount", WidgetId::VulkanValidationMessageCount},
{"VulkanCommandGraphSize", WidgetId::VulkanCommandGraphSize},
+ {"VulkanRenderPassCount", WidgetId::VulkanRenderPassCount},
{"VulkanSecondaryCommandBufferPoolWaste", WidgetId::VulkanSecondaryCommandBufferPoolWaste},
};
} // namespace
diff --git a/src/libANGLE/Overlay.h b/src/libANGLE/Overlay.h
index 7662cf4..15af6a2 100644
--- a/src/libANGLE/Overlay.h
+++ b/src/libANGLE/Overlay.h
@@ -127,9 +127,19 @@
};
#if ANGLE_ENABLE_OVERLAY
-using OverlayType = Overlay;
+using OverlayType = Overlay;
+using CountWidget = overlay::Count;
+using PerSecondWidget = overlay::PerSecond;
+using RunningGraphWidget = overlay::RunningGraph;
+using RunningHistogramWidget = overlay::RunningHistogram;
+using TextWidget = overlay::Text;
#else // !ANGLE_ENABLE_OVERLAY
-using OverlayType = DummyOverlay;
+using OverlayType = DummyOverlay;
+using CountWidget = const overlay::Dummy;
+using PerSecondWidget = const overlay::Dummy;
+using RunningGraphWidget = const overlay::Dummy;
+using RunningHistogramWidget = const overlay::Dummy;
+using TextWidget = const overlay::Dummy;
#endif // ANGLE_ENABLE_OVERLAY
} // namespace gl
diff --git a/src/libANGLE/OverlayWidgets.cpp b/src/libANGLE/OverlayWidgets.cpp
index 50cfcc1..9ea17a9 100644
--- a/src/libANGLE/OverlayWidgets.cpp
+++ b/src/libANGLE/OverlayWidgets.cpp
@@ -205,6 +205,11 @@
TextWidgetData *textWidget,
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts);
+ static void AppendVulkanRenderPassCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts);
static void AppendVulkanSecondaryCommandBufferPoolWaste(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
@@ -335,6 +340,33 @@
}
}
+void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::RunningGraph *renderPassCount =
+ static_cast<const overlay::RunningGraph *>(widget);
+
+ const size_t maxValue = *std::max_element(renderPassCount->runningValues.begin(),
+ renderPassCount->runningValues.end());
+ const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
+ const float graphScale = static_cast<float>(graphHeight) / maxValue;
+
+ AppendGraphCommon(widget, imageExtent, renderPassCount->runningValues,
+ renderPassCount->lastValueIndex + 1, graphScale, graphWidget, widgetCounts);
+
+ if ((*widgetCounts)[WidgetInternalType::Text] <
+ kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
+ {
+ std::ostringstream text;
+ text << "RenderPass Count (Max: " << maxValue << ")";
+ AppendTextCommon(&renderPassCount->description, imageExtent, text.str(), textWidget,
+ widgetCounts);
+ }
+}
+
void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
const overlay::Widget *widget,
const gl::Extents &imageExtent,
@@ -393,6 +425,8 @@
overlay_impl::AppendWidgetDataHelper::AppendVulkanValidationMessageCount},
{WidgetId::VulkanCommandGraphSize,
overlay_impl::AppendWidgetDataHelper::AppendVulkanCommandGraphSize},
+ {WidgetId::VulkanRenderPassCount,
+ overlay_impl::AppendWidgetDataHelper::AppendVulkanRenderPassCount},
{WidgetId::VulkanSecondaryCommandBufferPoolWaste,
overlay_impl::AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste},
};
@@ -495,6 +529,7 @@
}
AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
+ ASSERT(appendFunc);
appendFunc(widget.get(), imageExtents,
&textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
&graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
diff --git a/src/libANGLE/OverlayWidgets.h b/src/libANGLE/OverlayWidgets.h
index 085f2f4..7352834 100644
--- a/src/libANGLE/OverlayWidgets.h
+++ b/src/libANGLE/OverlayWidgets.h
@@ -59,6 +59,8 @@
VulkanValidationMessageCount,
// Number of nodes in command graph (RunningGraph).
VulkanCommandGraphSize,
+ // Number of RenderPasses in a frame (RunningGraph).
+ VulkanRenderPassCount,
// Secondary Command Buffer pool memory waste (RunningHistogram).
VulkanSecondaryCommandBufferPoolWaste,
diff --git a/src/libANGLE/Overlay_autogen.cpp b/src/libANGLE/Overlay_autogen.cpp
index f202d0e..18c803d 100644
--- a/src/libANGLE/Overlay_autogen.cpp
+++ b/src/libANGLE/Overlay_autogen.cpp
@@ -1,7 +1,7 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_overlay_widgets.py using data from overlay_widgets.json.
//
-// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -147,6 +147,49 @@
}
{
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = 100;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.294117647059;
+ widget->color[1] = 0.78431372549;
+ widget->color[2] = 0.0;
+ widget->color[3] = 0.78431372549;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontLayerSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->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] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.294117647059;
+ widget->description.color[1] = 0.78431372549;
+ widget->description.color[2] = 0.0;
+ widget->description.color[3] = 1.0;
+ }
+ }
+
+ {
RunningHistogram *widget = new RunningHistogram(50);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
diff --git a/src/libANGLE/overlay_widgets.json b/src/libANGLE/overlay_widgets.json
index 0f65f75..d5fbe25 100644
--- a/src/libANGLE/overlay_widgets.json
+++ b/src/libANGLE/overlay_widgets.json
@@ -67,6 +67,20 @@
}
},
{
+ "name": "VulkanRenderPassCount",
+ "type": "RunningGraph(60)",
+ "color": [75, 200, 0, 200],
+ "coords": [10, 100],
+ "bar_width": 5,
+ "height": 100,
+ "description": {
+ "color": [75, 200, 0, 255],
+ "coords": ["VulkanRenderPassCount.left.align", "VulkanRenderPassCount.top.adjacent"],
+ "font": "small",
+ "length": 40
+ }
+ },
+ {
"name": "VulkanSecondaryCommandBufferPoolWaste",
"type": "RunningHistogram(50)",
"color": [255, 200, 75, 200],
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index 79a2c16..0452487 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -474,6 +474,8 @@
angle::Result CommandGraphNode::beginInsideRenderPassRecording(ContextVk *context,
CommandBuffer **commandsOut)
{
+ context->getCommandGraph()->tickRenderPassCount();
+
ASSERT(!mHasChildren);
// Get a compatible RenderPass from the cache so we can initialize the inheritance info.
@@ -939,7 +941,8 @@
CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *poolAllocator)
: mEnableGraphDiagnostics(enableGraphDiagnostics),
mPoolAllocator(poolAllocator),
- mLastBarrierIndex(kInvalidNodeIndex)
+ mLastBarrierIndex(kInvalidNodeIndex),
+ mRenderPassCount(0)
{
// Push so that allocations made from here will be recycled in clear() below.
mPoolAllocator->push();
@@ -998,6 +1001,7 @@
ASSERT(!mNodes.empty());
updateOverlay(context);
+ mRenderPassCount = 0;
size_t previousBarrierIndex = 0;
CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex);
@@ -1321,9 +1325,15 @@
overlay->getRunningGraphWidget(gl::WidgetId::VulkanCommandGraphSize)->add(mNodes.size());
- overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste)
- ->set(CalculateSecondaryCommandBufferPoolWaste(mNodes));
- overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste)->next();
+ gl::RunningHistogramWidget *poolWaste =
+ overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste);
+ poolWaste->set(CalculateSecondaryCommandBufferPoolWaste(mNodes));
+ poolWaste->next();
+
+ gl::RunningGraphWidget *renderPassCount =
+ overlay->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
+ renderPassCount->add(mRenderPassCount);
+ renderPassCount->next();
}
CommandGraphNode *CommandGraph::getLastBarrierNode(size_t *indexOut)
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index ca679cb..ae1bea1 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -608,6 +608,7 @@
void makeHostVisibleBufferWriteAvailable();
// External memory synchronization:
void syncExternalMemory();
+ void tickRenderPassCount() { mRenderPassCount++; }
private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
@@ -672,6 +673,7 @@
// issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex;
+ uint32_t mRenderPassCount;
};
// CommandGraphResource inlines.
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index e820f47..3666bab 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -1298,6 +1298,15 @@
angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer)
{
+ // Update overlay if active.
+ if (!commandGraphEnabled())
+ {
+ gl::RunningGraphWidget *renderPassCount =
+ mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
+ renderPassCount->add(mRenderPassCommands.getAndResetCounter());
+ renderPassCount->next();
+ }
+
ANGLE_TRY(ensureSubmitFenceInitialized());
ANGLE_TRY(mCommandQueue.submitFrame(this, mContextPriority, submitInfo, mSubmitFence,
&mCurrentGarbage, &mCommandPool, std::move(commandBuffer)));
@@ -3797,7 +3806,7 @@
mCommandBuffer.reset();
}
-RenderPassCommandBuffer::RenderPassCommandBuffer() = default;
+RenderPassCommandBuffer::RenderPassCommandBuffer() : mCounter(0) {}
RenderPassCommandBuffer::~RenderPassCommandBuffer()
{
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h
index ba8bf2d..f2dfffb 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.h
+++ b/src/libANGLE/renderer/vulkan/ContextVk.h
@@ -172,7 +172,15 @@
bool empty() const { return mCommandBuffer.empty(); }
void reset();
+ uint32_t getAndResetCounter()
+ {
+ uint32_t count = mCounter;
+ mCounter = 0;
+ return count;
+ }
+
private:
+ uint32_t mCounter;
vk::RenderPassDesc mRenderPassDesc;
vk::AttachmentOpsArray mAttachmentOps;
vk::Framebuffer mFramebuffer;