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":
"514b8108f62ef616c296dc511bb2f644",
"1c882462aacb436dbd88d6e7fdbe4473",
"src/libANGLE/gen_overlay_widgets.py":
"07252fbde304fd48559ae07f8f920a08",
"src/libANGLE/overlay_widgets.json":
"552b1e2883a12c38d427c7fbd1c2bf22"
"c84d5c85c6bd21d30056ad2fb9213e38"
}
\ No newline at end of file
......@@ -26,6 +26,7 @@ constexpr std::pair<const char *, WidgetId> kWidgetNames[] = {
{"VulkanLastValidationMessage", WidgetId::VulkanLastValidationMessage},
{"VulkanValidationMessageCount", WidgetId::VulkanValidationMessageCount},
{"VulkanCommandGraphSize", WidgetId::VulkanCommandGraphSize},
{"VulkanRenderPassCount", WidgetId::VulkanRenderPassCount},
{"VulkanSecondaryCommandBufferPoolWaste", WidgetId::VulkanSecondaryCommandBufferPoolWaste},
};
} // namespace
......
......@@ -127,9 +127,19 @@ class DummyOverlay
};
#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
......
......@@ -205,6 +205,11 @@ class AppendWidgetDataHelper
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::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(
const overlay::Widget *widget,
const gl::Extents &imageExtent,
......@@ -393,6 +425,8 @@ constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppend
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 @@ void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
}
AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
ASSERT(appendFunc);
appendFunc(widget.get(), imageExtents,
&textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
&graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
......
......@@ -59,6 +59,8 @@ enum class WidgetId
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,
......
// 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 @@ 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);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
......
......@@ -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],
......
......@@ -474,6 +474,8 @@ angle::Result CommandGraphNode::beginOutsideRenderPassRecording(ContextVk *conte
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 @@ bool SharedGarbage::destroyIfComplete(VkDevice device, Serial completedSerial)
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 @@ angle::Result CommandGraph::submitCommands(ContextVk *context,
ASSERT(!mNodes.empty());
updateOverlay(context);
mRenderPassCount = 0;
size_t previousBarrierIndex = 0;
CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex);
......@@ -1321,9 +1325,15 @@ void CommandGraph::updateOverlay(ContextVk *contextVk) const
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)
......
......@@ -608,6 +608,7 @@ class CommandGraph final : angle::NonCopyable
void makeHostVisibleBufferWriteAvailable();
// External memory synchronization:
void syncExternalMemory();
void tickRenderPassCount() { mRenderPassCount++; }
private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
......@@ -672,6 +673,7 @@ class CommandGraph final : angle::NonCopyable
// issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex;
uint32_t mRenderPassCount;
};
// CommandGraphResource inlines.
......
......@@ -1298,6 +1298,15 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
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 @@ void OutsideRenderPassCommandBuffer::reset()
mCommandBuffer.reset();
}
RenderPassCommandBuffer::RenderPassCommandBuffer() = default;
RenderPassCommandBuffer::RenderPassCommandBuffer() : mCounter(0) {}
RenderPassCommandBuffer::~RenderPassCommandBuffer()
{
......
......@@ -172,7 +172,15 @@ class RenderPassCommandBuffer final : angle::NonCopyable
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;
......
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