Commit 3e691bb9 by Jamie Madill Committed by Commit Bot

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/+/2036402Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d8c4b5fb
{ {
"src/libANGLE/Overlay_autogen.cpp": "src/libANGLE/Overlay_autogen.cpp":
"514b8108f62ef616c296dc511bb2f644", "1c882462aacb436dbd88d6e7fdbe4473",
"src/libANGLE/gen_overlay_widgets.py": "src/libANGLE/gen_overlay_widgets.py":
"07252fbde304fd48559ae07f8f920a08", "07252fbde304fd48559ae07f8f920a08",
"src/libANGLE/overlay_widgets.json": "src/libANGLE/overlay_widgets.json":
"552b1e2883a12c38d427c7fbd1c2bf22" "c84d5c85c6bd21d30056ad2fb9213e38"
} }
\ No newline at end of file
...@@ -26,6 +26,7 @@ constexpr std::pair<const char *, WidgetId> kWidgetNames[] = { ...@@ -26,6 +26,7 @@ constexpr std::pair<const char *, WidgetId> kWidgetNames[] = {
{"VulkanLastValidationMessage", WidgetId::VulkanLastValidationMessage}, {"VulkanLastValidationMessage", WidgetId::VulkanLastValidationMessage},
{"VulkanValidationMessageCount", WidgetId::VulkanValidationMessageCount}, {"VulkanValidationMessageCount", WidgetId::VulkanValidationMessageCount},
{"VulkanCommandGraphSize", WidgetId::VulkanCommandGraphSize}, {"VulkanCommandGraphSize", WidgetId::VulkanCommandGraphSize},
{"VulkanRenderPassCount", WidgetId::VulkanRenderPassCount},
{"VulkanSecondaryCommandBufferPoolWaste", WidgetId::VulkanSecondaryCommandBufferPoolWaste}, {"VulkanSecondaryCommandBufferPoolWaste", WidgetId::VulkanSecondaryCommandBufferPoolWaste},
}; };
} // namespace } // namespace
......
...@@ -127,9 +127,19 @@ class DummyOverlay ...@@ -127,9 +127,19 @@ class DummyOverlay
}; };
#if ANGLE_ENABLE_OVERLAY #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 #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 #endif // ANGLE_ENABLE_OVERLAY
} // namespace gl } // namespace gl
......
...@@ -205,6 +205,11 @@ class AppendWidgetDataHelper ...@@ -205,6 +205,11 @@ class AppendWidgetDataHelper
TextWidgetData *textWidget, TextWidgetData *textWidget,
GraphWidgetData *graphWidget, GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts); 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, static void AppendVulkanSecondaryCommandBufferPoolWaste(const overlay::Widget *widget,
const gl::Extents &imageExtent, const gl::Extents &imageExtent,
TextWidgetData *textWidget, TextWidgetData *textWidget,
...@@ -335,6 +340,33 @@ void AppendWidgetDataHelper::AppendVulkanCommandGraphSize(const overlay::Widget ...@@ -335,6 +340,33 @@ void AppendWidgetDataHelper::AppendVulkanCommandGraphSize(const overlay::Widget
} }
} }
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( void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
const overlay::Widget *widget, const overlay::Widget *widget,
const gl::Extents &imageExtent, const gl::Extents &imageExtent,
...@@ -393,6 +425,8 @@ constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppend ...@@ -393,6 +425,8 @@ constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppend
overlay_impl::AppendWidgetDataHelper::AppendVulkanValidationMessageCount}, overlay_impl::AppendWidgetDataHelper::AppendVulkanValidationMessageCount},
{WidgetId::VulkanCommandGraphSize, {WidgetId::VulkanCommandGraphSize,
overlay_impl::AppendWidgetDataHelper::AppendVulkanCommandGraphSize}, overlay_impl::AppendWidgetDataHelper::AppendVulkanCommandGraphSize},
{WidgetId::VulkanRenderPassCount,
overlay_impl::AppendWidgetDataHelper::AppendVulkanRenderPassCount},
{WidgetId::VulkanSecondaryCommandBufferPoolWaste, {WidgetId::VulkanSecondaryCommandBufferPoolWaste,
overlay_impl::AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste}, overlay_impl::AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste},
}; };
...@@ -495,6 +529,7 @@ void OverlayState::fillWidgetData(const gl::Extents &imageExtents, ...@@ -495,6 +529,7 @@ void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
} }
AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id]; AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
ASSERT(appendFunc);
appendFunc(widget.get(), imageExtents, appendFunc(widget.get(), imageExtents,
&textWidgets->widgets[widgetCounts[WidgetInternalType::Text]], &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
&graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts); &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
......
...@@ -59,6 +59,8 @@ enum class WidgetId ...@@ -59,6 +59,8 @@ enum class WidgetId
VulkanValidationMessageCount, VulkanValidationMessageCount,
// Number of nodes in command graph (RunningGraph). // Number of nodes in command graph (RunningGraph).
VulkanCommandGraphSize, VulkanCommandGraphSize,
// Number of RenderPasses in a frame (RunningGraph).
VulkanRenderPassCount,
// Secondary Command Buffer pool memory waste (RunningHistogram). // Secondary Command Buffer pool memory waste (RunningHistogram).
VulkanSecondaryCommandBufferPoolWaste, VulkanSecondaryCommandBufferPoolWaste,
......
// GENERATED FILE - DO NOT EDIT. // GENERATED FILE - DO NOT EDIT.
// Generated by gen_overlay_widgets.py using data from overlay_widgets.json. // 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -147,6 +147,49 @@ void Overlay::initOverlayWidgets() ...@@ -147,6 +147,49 @@ void Overlay::initOverlayWidgets()
} }
{ {
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); RunningHistogram *widget = new RunningHistogram(50);
{ {
const int32_t fontSize = GetFontSize(0, kLargeFont); const int32_t fontSize = GetFontSize(0, kLargeFont);
......
...@@ -67,6 +67,20 @@ ...@@ -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", "name": "VulkanSecondaryCommandBufferPoolWaste",
"type": "RunningHistogram(50)", "type": "RunningHistogram(50)",
"color": [255, 200, 75, 200], "color": [255, 200, 75, 200],
......
...@@ -474,6 +474,8 @@ angle::Result CommandGraphNode::beginOutsideRenderPassRecording(ContextVk *conte ...@@ -474,6 +474,8 @@ angle::Result CommandGraphNode::beginOutsideRenderPassRecording(ContextVk *conte
angle::Result CommandGraphNode::beginInsideRenderPassRecording(ContextVk *context, angle::Result CommandGraphNode::beginInsideRenderPassRecording(ContextVk *context,
CommandBuffer **commandsOut) CommandBuffer **commandsOut)
{ {
context->getCommandGraph()->tickRenderPassCount();
ASSERT(!mHasChildren); ASSERT(!mHasChildren);
// Get a compatible RenderPass from the cache so we can initialize the inheritance info. // Get a compatible RenderPass from the cache so we can initialize the inheritance info.
...@@ -939,7 +941,8 @@ bool SharedGarbage::destroyIfComplete(VkDevice device, Serial completedSerial) ...@@ -939,7 +941,8 @@ bool SharedGarbage::destroyIfComplete(VkDevice device, Serial completedSerial)
CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *poolAllocator) CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *poolAllocator)
: mEnableGraphDiagnostics(enableGraphDiagnostics), : mEnableGraphDiagnostics(enableGraphDiagnostics),
mPoolAllocator(poolAllocator), mPoolAllocator(poolAllocator),
mLastBarrierIndex(kInvalidNodeIndex) mLastBarrierIndex(kInvalidNodeIndex),
mRenderPassCount(0)
{ {
// Push so that allocations made from here will be recycled in clear() below. // Push so that allocations made from here will be recycled in clear() below.
mPoolAllocator->push(); mPoolAllocator->push();
...@@ -998,6 +1001,7 @@ angle::Result CommandGraph::submitCommands(ContextVk *context, ...@@ -998,6 +1001,7 @@ angle::Result CommandGraph::submitCommands(ContextVk *context,
ASSERT(!mNodes.empty()); ASSERT(!mNodes.empty());
updateOverlay(context); updateOverlay(context);
mRenderPassCount = 0;
size_t previousBarrierIndex = 0; size_t previousBarrierIndex = 0;
CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex); CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex);
...@@ -1321,9 +1325,15 @@ void CommandGraph::updateOverlay(ContextVk *contextVk) const ...@@ -1321,9 +1325,15 @@ void CommandGraph::updateOverlay(ContextVk *contextVk) const
overlay->getRunningGraphWidget(gl::WidgetId::VulkanCommandGraphSize)->add(mNodes.size()); overlay->getRunningGraphWidget(gl::WidgetId::VulkanCommandGraphSize)->add(mNodes.size());
overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste) gl::RunningHistogramWidget *poolWaste =
->set(CalculateSecondaryCommandBufferPoolWaste(mNodes)); overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste);
overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste)->next(); 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) CommandGraphNode *CommandGraph::getLastBarrierNode(size_t *indexOut)
......
...@@ -608,6 +608,7 @@ class CommandGraph final : angle::NonCopyable ...@@ -608,6 +608,7 @@ class CommandGraph final : angle::NonCopyable
void makeHostVisibleBufferWriteAvailable(); void makeHostVisibleBufferWriteAvailable();
// External memory synchronization: // External memory synchronization:
void syncExternalMemory(); void syncExternalMemory();
void tickRenderPassCount() { mRenderPassCount++; }
private: private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function, CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
...@@ -672,6 +673,7 @@ class CommandGraph final : angle::NonCopyable ...@@ -672,6 +673,7 @@ class CommandGraph final : angle::NonCopyable
// issued. // issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max(); static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex; size_t mLastBarrierIndex;
uint32_t mRenderPassCount;
}; };
// CommandGraphResource inlines. // CommandGraphResource inlines.
......
...@@ -1298,6 +1298,15 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context, ...@@ -1298,6 +1298,15 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo, angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer) 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(ensureSubmitFenceInitialized());
ANGLE_TRY(mCommandQueue.submitFrame(this, mContextPriority, submitInfo, mSubmitFence, ANGLE_TRY(mCommandQueue.submitFrame(this, mContextPriority, submitInfo, mSubmitFence,
&mCurrentGarbage, &mCommandPool, std::move(commandBuffer))); &mCurrentGarbage, &mCommandPool, std::move(commandBuffer)));
...@@ -3797,7 +3806,7 @@ void OutsideRenderPassCommandBuffer::reset() ...@@ -3797,7 +3806,7 @@ void OutsideRenderPassCommandBuffer::reset()
mCommandBuffer.reset(); mCommandBuffer.reset();
} }
RenderPassCommandBuffer::RenderPassCommandBuffer() = default; RenderPassCommandBuffer::RenderPassCommandBuffer() : mCounter(0) {}
RenderPassCommandBuffer::~RenderPassCommandBuffer() RenderPassCommandBuffer::~RenderPassCommandBuffer()
{ {
......
...@@ -172,7 +172,15 @@ class RenderPassCommandBuffer final : angle::NonCopyable ...@@ -172,7 +172,15 @@ class RenderPassCommandBuffer final : angle::NonCopyable
bool empty() const { return mCommandBuffer.empty(); } bool empty() const { return mCommandBuffer.empty(); }
void reset(); void reset();
uint32_t getAndResetCounter()
{
uint32_t count = mCounter;
mCounter = 0;
return count;
}
private: private:
uint32_t mCounter;
vk::RenderPassDesc mRenderPassDesc; vk::RenderPassDesc mRenderPassDesc;
vk::AttachmentOpsArray mAttachmentOps; vk::AttachmentOpsArray mAttachmentOps;
vk::Framebuffer mFramebuffer; vk::Framebuffer mFramebuffer;
......
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