Vulkan: Overlay widgets for submission statistics

Bug: angleproject:7084
Change-Id: I68e69bda43862f9f2711c25a28dbe4745c19a45c
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3602832
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Shahbaz Youssefi 2022-04-22 13:21:03 -04:00 коммит произвёл Angle LUCI CQ
Родитель 02b968481a
Коммит 4aae5815f1
14 изменённых файлов: 576 добавлений и 286 удалений

Просмотреть файл

@ -1,10 +1,10 @@
{
"src/libANGLE/Overlay_autogen.cpp":
"c9763a51339da8432a0827322f21bd2e",
"f6a827173b542553c1766c5d1f0b22b6",
"src/libANGLE/Overlay_autogen.h":
"e9594b02a505c22e121541810551a19d",
"64f39d05494a9825c4162d622a9d4bfd",
"src/libANGLE/gen_overlay_widgets.py":
"4530a7f65c51206ce9de6917683e3687",
"a3c5bcd77c8ff8660a542be85f9d6e59",
"src/libANGLE/overlay_widgets.json":
"2a424ff932317c54df13acabfb1251a3"
"d143bd5c7abae4ab7e95276ccb64d474"
}

Просмотреть файл

@ -131,8 +131,11 @@ struct PerfMonitorTriplet
};
#define ANGLE_VK_PERF_COUNTERS_X(FN) \
FN(commandQueueSubmitCallsTotal) \
FN(commandQueueSubmitCallsPerFrame) \
FN(vkQueueSubmitCallsTotal) \
FN(vkQueueSubmitCallsPerFrame) \
FN(renderPasses) \
FN(submittedCommands) \
FN(writeDescriptorSets) \
FN(flushedOutsideRenderPassCommandBuffers) \
FN(swapchainResolveInSubpass) \

Просмотреть файл

@ -202,7 +202,7 @@ class AppendWidgetDataHelper
TextWidgetData *textWidget,
OverlayWidgetCounts *widgetCounts);
using FormatGraphTitleFunc = std::function<std::string(size_t maxValue)>;
using FormatGraphTitleFunc = std::function<std::string(size_t curValue, size_t maxValue)>;
static void AppendRunningGraphCommon(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
@ -270,11 +270,21 @@ void AppendWidgetDataHelper::AppendRunningGraphCommon(
AppendWidgetDataHelper::FormatGraphTitleFunc formatFunc)
{
const overlay::RunningGraph *graph = static_cast<const overlay::RunningGraph *>(widget);
const overlay::Widget *matchToWidget = widget->matchToWidget;
if (matchToWidget == nullptr)
{
matchToWidget = widget;
}
const overlay::RunningGraph *matchToGraph =
static_cast<const overlay::RunningGraph *>(matchToWidget);
const size_t maxValue =
*std::max_element(graph->runningValues.begin(), graph->runningValues.end());
const size_t maxValueInMatchToGraph =
*std::max_element(matchToGraph->runningValues.begin(), matchToGraph->runningValues.end());
const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
const float graphScale = static_cast<float>(graphHeight) / maxValue;
const float graphScale = static_cast<float>(graphHeight) / maxValueInMatchToGraph;
const size_t graphSize = graph->runningValues.size();
const size_t currentIdx = graph->lastValueIndex - 1;
@ -287,8 +297,7 @@ void AppendWidgetDataHelper::AppendRunningGraphCommon(
if ((*widgetCounts)[WidgetInternalType::Text] <
kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
{
// std::string text = formatFunc(maxValue);
std::string text = formatFunc(curValue);
std::string text = formatFunc(curValue, maxValue);
AppendTextCommon(&graph->description, imageExtent, text, textWidget, widgetCounts);
}
}
@ -374,7 +383,7 @@ void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "RenderPass Count: " << maxValue;
return text.str();
@ -423,7 +432,7 @@ void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "WriteDescriptorSet Count: " << maxValue;
return text.str();
@ -438,7 +447,7 @@ void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay:
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Descriptor Set Allocations: " << maxValue;
return text.str();
@ -453,7 +462,7 @@ void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(const overlay::
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)";
return text.str();
@ -468,7 +477,7 @@ void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay:
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "DynamicBuffer Allocations (Max: " << maxValue << ")";
return text.str();
@ -484,9 +493,9 @@ void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize(
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t curVal) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Total Texture Descriptor Cache Size: " << curVal;
text << "Total Texture Descriptor Cache Size: " << curValue;
return text.str();
};
@ -500,9 +509,9 @@ void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize(
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t curVal) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Total Uniform Descriptor Cache Size: " << curVal;
text << "Total Uniform Descriptor Cache Size: " << curValue;
return text.str();
};
@ -515,9 +524,9 @@ void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widg
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t curVal) {
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Total Descriptor Cache Size: " << curVal;
text << "Total Descriptor Cache Size: " << curValue;
return text.str();
};
@ -538,6 +547,36 @@ void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::W
AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
}
void AppendWidgetDataHelper::AppendVulkanAttemptedSubmissions(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Attempted submissions (peak): " << maxValue;
return text.str();
};
AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
}
void AppendWidgetDataHelper::AppendVulkanActualSubmissions(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t curValue, size_t maxValue) {
std::ostringstream text;
text << "Actual submissions (peak): " << maxValue;
return text.str();
};
AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
}
std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
const overlay::PerSecond *perSecond)
{

Просмотреть файл

@ -66,6 +66,11 @@ class Widget
int32_t coords[4];
float color[4];
// In some cases, a widget may need to match its contents (e.g. graph height scaling) with
// another related widget. In such a case, this pointer will point to the widget it needs to
// match to.
Widget *matchToWidget;
friend class gl::Overlay;
friend class gl::OverlayState;
friend class overlay_impl::AppendWidgetDataHelper;

Просмотреть файл

@ -52,6 +52,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7490196078431373f;
widget->color[2] = 1.0f;
widget->color[3] = 1.0f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::FPS].reset(widget);
}
@ -75,6 +76,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.0f;
widget->color[2] = 0.0f;
widget->color[3] = 1.0f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanLastValidationMessage].reset(widget);
}
@ -99,6 +101,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.0f;
widget->color[2] = 0.0f;
widget->color[3] = 1.0f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanValidationMessageCount].reset(widget);
}
@ -122,6 +125,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.0f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount].reset(widget);
{
@ -143,6 +147,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.0f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -165,6 +170,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount].reset(widget);
{
@ -186,6 +192,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -208,6 +215,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste].reset(widget);
{
@ -229,6 +237,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -251,6 +260,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.0f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount].reset(widget);
{
@ -272,6 +282,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.0f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -294,6 +305,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.0f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations].reset(widget);
{
@ -315,6 +327,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.0f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -337,6 +350,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.0f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate].reset(widget);
{
@ -358,6 +372,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.0f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -380,6 +395,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations].reset(widget);
{
@ -401,6 +417,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -423,6 +440,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.7254901960784313f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize].reset(widget);
{
@ -444,6 +462,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -466,6 +485,7 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 0.29411764705882354f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize].reset(widget);
{
@ -487,6 +507,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -507,8 +528,9 @@ void Overlay::initOverlayWidgets()
widget->coords[3] = offsetY + height;
widget->color[0] = 0.0f;
widget->color[1] = 0.7843137254901961f;
widget->color[2] = 1.1764705882352942f;
widget->color[2] = 1.0f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize].reset(widget);
{
@ -530,6 +552,7 @@ void Overlay::initOverlayWidgets()
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
@ -552,9 +575,103 @@ void Overlay::initOverlayWidgets()
widget->color[1] = 1.0f;
widget->color[2] = 1.0f;
widget->color[3] = 1.0f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheKeySize].reset(widget);
}
{
RunningGraph *widget = new RunningGraph(60);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
const int32_t offsetX = -50;
const int32_t offsetY = 50;
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 - width;
widget->coords[1] = offsetY;
widget->coords[2] = offsetX;
widget->coords[3] = offsetY + height;
widget->color[0] = 1.0f;
widget->color[1] = 0.0f;
widget->color[2] = 0.0f;
widget->color[3] = 0.39215686274509803f;
widget->matchToWidget = nullptr;
}
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].reset(widget);
{
const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
const int32_t offsetX =
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0];
const int32_t offsetY =
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1];
const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
const int32_t height = (kFontGlyphHeight >> 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] = 0.7843137254901961f;
widget->description.color[1] = 0.0f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
{
RunningGraph *widget = new RunningGraph(60);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
const int32_t offsetX =
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0];
const int32_t offsetY =
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1];
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] = std::min(offsetX + width, -1);
widget->coords[3] = offsetY + height;
widget->color[0] = 0.0f;
widget->color[1] = 1.0f;
widget->color[2] = 0.0f;
widget->color[3] = 0.7843137254901961f;
widget->matchToWidget =
mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].get();
}
mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions].reset(widget);
{
const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
const int32_t offsetX =
mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[0];
const int32_t offsetY =
mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[3];
const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
const int32_t height = (kFontGlyphHeight >> fontSize);
widget->description.type = WidgetType::Text;
widget->description.fontSize = fontSize;
widget->description.coords[0] = offsetX;
widget->description.coords[1] = offsetY;
widget->description.coords[2] = std::min(offsetX + width, -1);
widget->description.coords[3] = offsetY + height;
widget->description.color[0] = 0.0f;
widget->description.color[1] = 0.7843137254901961f;
widget->description.color[2] = 0.29411764705882354f;
widget->description.color[3] = 1.0f;
widget->description.matchToWidget = nullptr;
}
}
}
} // namespace gl

Просмотреть файл

@ -40,6 +40,10 @@ enum class WidgetId
VulkanUniformDescriptorCacheSize,
// Total size of all keys in the descriptor set caches
VulkanDescriptorCacheKeySize,
// Number of times the Vulkan backend attempted to submit commands
VulkanAttemptedSubmissions,
// Number of times the Vulkan backend actually submitted commands
VulkanActualSubmissions,
InvalidEnum,
EnumCount = InvalidEnum,
@ -60,6 +64,8 @@ enum class WidgetId
PROC(VulkanDescriptorCacheSize) \
PROC(VulkanTextureDescriptorCacheSize) \
PROC(VulkanUniformDescriptorCacheSize) \
PROC(VulkanDescriptorCacheKeySize)
PROC(VulkanDescriptorCacheKeySize) \
PROC(VulkanAttemptedSubmissions) \
PROC(VulkanActualSubmissions)
} // namespace gl

Просмотреть файл

@ -103,6 +103,7 @@ widget->{subwidget}color[0] = {color_r}f;
widget->{subwidget}color[1] = {color_g}f;
widget->{subwidget}color[2] = {color_b}f;
widget->{subwidget}color[3] = {color_a}f;
widget->{subwidget}matchToWidget = {match_to};
}}
"""
@ -149,6 +150,7 @@ class OverlayWidget:
def extract_common(self, properties):
self.color = properties['color']
self.coords = properties['coords']
self.match_to = properties.get('match_to', None)
if is_graph_type(self.type):
self.bar_width = properties['bar_width']
self.height = properties['height']
@ -280,6 +282,9 @@ def generate_widget_init_helper(widget, is_graph_description=False):
coord0, coord2 = get_bounding_box_coords('offsetX', 'width', offset_x_is_left, is_left_aligned)
coord1, coord3 = get_bounding_box_coords('offsetY', 'height', offset_y_is_top, is_top_aligned)
match_to = 'nullptr' if widget.match_to is None else \
'mState.mOverlayWidgets[WidgetId::' + widget.match_to + '].get()'
return WIDGET_INIT_TEMPLATE.format(
subwidget='description.' if is_graph_description else '',
offset_x=offset_x,
@ -295,7 +300,8 @@ def generate_widget_init_helper(widget, is_graph_description=False):
color_r=color[0],
color_g=color[1],
color_b=color[2],
color_a=color[3])
color_a=color[3],
match_to=match_to)
def generate_widget_init(widget):

Просмотреть файл

@ -24,6 +24,7 @@
" - length: for Text widgets, maximum number of characters for this widget",
" - bar_width: for Graph widgets, size of each graph bar.",
" - height: for Graph widgets, the height of the graph.",
" - match_to: a reference to another widget",
" - text: for Graph widgets, data for the attached Text widget. This is a map with the same",
" Text keys as above except type, which is implicitly Text."
],
@ -201,7 +202,7 @@
"name": "VulkanUniformDescriptorCacheSize",
"comment": "Number of cached default uniform descriptor sets",
"type": "RunningGraph(60)",
"color": [0, 200, 300, 200],
"color": [0, 200, 255, 200],
"coords": [0, 450],
"bar_width": 5,
"height": 100,
@ -221,6 +222,40 @@
"coords": [10, 100],
"font": "small",
"length": 30
},
{
"name": "VulkanAttemptedSubmissions",
"comment": "Number of times the Vulkan backend attempted to submit commands",
"type": "RunningGraph(60)",
"color": [255, 0, 0, 100],
"coords": [-50, 50],
"bar_width": 5,
"height": 100,
"description": {
"color": [200, 0, 75, 255],
"coords": ["VulkanAttemptedSubmissions.left.align",
"VulkanAttemptedSubmissions.top.adjacent"],
"font": "small",
"length": 45
}
},
{
"name": "VulkanActualSubmissions",
"comment": "Number of times the Vulkan backend actually submitted commands",
"type": "RunningGraph(60)",
"color": [0, 255, 0, 200],
"coords": ["VulkanAttemptedSubmissions.left.align",
"VulkanAttemptedSubmissions.top.align"],
"bar_width": 5,
"height": 100,
"match_to": "VulkanAttemptedSubmissions",
"description": {
"color": [0, 200, 75, 255],
"coords": ["VulkanActualSubmissions.left.align",
"VulkanActualSubmissions.bottom.adjacent"],
"font": "small",
"length": 45
}
}
]
}

Просмотреть файл

@ -1107,6 +1107,9 @@ angle::Result CommandQueue::submitFrame(
RendererVk *renderer = context->getRenderer();
VkDevice device = renderer->getDevice();
++mPerfCounters.commandQueueSubmitCallsTotal;
++mPerfCounters.commandQueueSubmitCallsPerFrame;
DeviceScoped<CommandBatch> scopedBatch(device);
CommandBatch &batch = scopedBatch.get();
@ -1324,12 +1327,19 @@ angle::Result CommandQueue::queueSubmit(Context *context,
ANGLE_VK_TRY(context, vkQueueSubmit(queue, 1, &submitInfo, fenceHandle));
mLastSubmittedQueueSerial = submitQueueSerial;
++mPerfCounters.submittedCommands;
++mPerfCounters.vkQueueSubmitCallsTotal;
++mPerfCounters.vkQueueSubmitCallsPerFrame;
// Now that we've submitted work, clean up RendererVk garbage
return renderer->cleanupGarbage(mLastCompletedQueueSerial);
}
void CommandQueue::resetPerFramePerfCounters()
{
mPerfCounters.commandQueueSubmitCallsPerFrame = 0;
mPerfCounters.vkQueueSubmitCallsPerFrame = 0;
}
VkResult CommandQueue::queuePresent(egl::ContextPriority contextPriority,
const VkPresentInfoKHR &presentInfo)
{

Просмотреть файл

@ -426,6 +426,7 @@ class CommandQueue final : public CommandQueueInterface
VkQueue getQueue(egl::ContextPriority priority) { return mQueueMap[priority]; }
const angle::VulkanPerfCounters &getPerfCounters() const { return mPerfCounters; }
void resetPerFramePerfCounters();
private:
void releaseToCommandBatch(bool hasProtectedContent,
@ -578,6 +579,7 @@ class CommandProcessor final : public Context, public CommandQueueInterface
{
return mCommandQueue.getPerfCounters();
}
void resetPerFramePerfCounters() { mCommandQueue.resetPerFramePerfCounters(); }
private:
bool hasPendingError() const

Просмотреть файл

@ -1192,7 +1192,7 @@ angle::Result ContextVk::finish(const gl::Context *context)
ANGLE_TRY(finishImpl(RenderPassClosureReason::GLFinish));
}
syncObjectPerfCounters();
syncObjectPerfCounters(mRenderer->getCommandQueuePerfCounters());
return angle::Result::Continue;
}
@ -2537,7 +2537,7 @@ angle::Result ContextVk::handleDirtyDescriptorSetsImpl(CommandBufferHelperT *com
pipelineType);
}
void ContextVk::syncObjectPerfCounters()
void ContextVk::syncObjectPerfCounters(const angle::VulkanPerfCounters &commandQueuePerfCounters)
{
mPerfCounters.descriptorSetCacheTotalSize = 0;
mPerfCounters.descriptorSetCacheKeySizeBytes = 0;
@ -2604,7 +2604,12 @@ void ContextVk::syncObjectPerfCounters()
}
// Update perf counters from the renderer as well
mPerfCounters.submittedCommands = mRenderer->getCommandQueuePerfCounters().submittedCommands;
mPerfCounters.commandQueueSubmitCallsTotal =
commandQueuePerfCounters.commandQueueSubmitCallsTotal;
mPerfCounters.commandQueueSubmitCallsPerFrame =
commandQueuePerfCounters.commandQueueSubmitCallsPerFrame;
mPerfCounters.vkQueueSubmitCallsTotal = commandQueuePerfCounters.vkQueueSubmitCallsTotal;
mPerfCounters.vkQueueSubmitCallsPerFrame = commandQueuePerfCounters.vkQueueSubmitCallsPerFrame;
}
void ContextVk::updateOverlayOnPresent()
@ -2612,7 +2617,8 @@ void ContextVk::updateOverlayOnPresent()
const gl::OverlayType *overlay = mState.getOverlay();
ASSERT(overlay->isEnabled());
syncObjectPerfCounters();
angle::VulkanPerfCounters commandQueuePerfCounters = mRenderer->getCommandQueuePerfCounters();
syncObjectPerfCounters(commandQueuePerfCounters);
// Update overlay if active.
{
@ -2670,6 +2676,22 @@ void ContextVk::updateOverlayOnPresent()
overlay->getRunningGraphWidget(gl::WidgetId::VulkanDynamicBufferAllocations);
dynamicBufferAllocations->add(mPerfCounters.dynamicBufferAllocations);
}
{
// A submission will follow the overlay rendering, so the per-frame submit calls are
// incremented by one to account for that submission.
gl::RunningGraphWidget *attemptedSubmissionsWidget =
overlay->getRunningGraphWidget(gl::WidgetId::VulkanAttemptedSubmissions);
attemptedSubmissionsWidget->add(commandQueuePerfCounters.commandQueueSubmitCallsPerFrame +
1);
attemptedSubmissionsWidget->next();
gl::RunningGraphWidget *actualSubmissionsWidget =
overlay->getRunningGraphWidget(gl::WidgetId::VulkanActualSubmissions);
actualSubmissionsWidget->add(commandQueuePerfCounters.vkQueueSubmitCallsPerFrame + 1);
actualSubmissionsWidget->next();
}
}
void ContextVk::addOverlayUsedBuffersCount(vk::CommandBufferHelperCommon *commandBuffer)
@ -7217,7 +7239,7 @@ ProgramExecutableVk *ContextVk::getExecutable() const
const angle::PerfMonitorCounterGroups &ContextVk::getPerfMonitorCounters()
{
syncObjectPerfCounters();
syncObjectPerfCounters(mRenderer->getCommandQueuePerfCounters());
angle::PerfMonitorCounters &counters =
angle::GetPerfMonitorCounterGroup(mPerfMonitorCounters, "vulkan").counters;
@ -7341,5 +7363,7 @@ void ContextVk::resetPerFramePerfCounters()
ProgramVk *programVk = vk::GetImpl(program);
programVk->getExecutable().resetDescriptorSetPerfCounters();
}
mRenderer->resetCommandQueuePerFrameCounters();
}
} // namespace rx

Просмотреть файл

@ -695,7 +695,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
// Used by QueryVk to share query helpers between transform feedback queries.
QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
void syncObjectPerfCounters();
void syncObjectPerfCounters(const angle::VulkanPerfCounters &commandQueuePerfCounters);
void updateOverlayOnPresent();
void addOverlayUsedBuffersCount(vk::CommandBufferHelperCommon *commandBuffer);

Просмотреть файл

@ -405,6 +405,18 @@ class RendererVk : angle::NonCopyable
return mCommandQueue.getPerfCounters();
}
}
void resetCommandQueuePerFrameCounters()
{
vk::ScopedCommandQueueLock lock(this, mCommandQueueMutex);
if (isAsyncCommandQueueEnabled())
{
mCommandProcessor.resetPerFramePerfCounters();
}
else
{
mCommandQueue.resetPerFramePerfCounters();
}
}
egl::Display *getDisplay() const { return mDisplay; }

Просмотреть файл

@ -568,7 +568,7 @@ TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferDoesNotBreakR
size_t kMaxBufferToImageCopySize = 1 << 28;
uint32_t kNumSubmits = 2;
uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
uint32_t expectedSubmitCommandsCount = getPerfCounters().submittedCommands + kNumSubmits;
uint32_t expectedSubmitCommandsCount = getPerfCounters().vkQueueSubmitCallsTotal + kNumSubmits;
// Step 1: Set up a simple 2D texture.
GLTexture texture;
@ -622,7 +622,7 @@ TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferDoesNotBreakR
// Verify render pass and submitted frame counts.
EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
EXPECT_EQ(getPerfCounters().submittedCommands, expectedSubmitCommandsCount);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedSubmitCommandsCount);
}
// Tests that RGB texture should not break renderpass.
@ -4910,6 +4910,37 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateThenRepeatedClearThenReadbackThen
compareColorOpCounters(getPerfCounters(), expected);
}
// Tests that the submission counters count the implicit submission in eglSwapBuffers().
TEST_P(VulkanPerformanceCounterTest, VerifySubmitCounters)
{
initANGLEFeatures();
uint32_t expectedVkQueueSubmitCount = getPerfCounters().vkQueueSubmitCallsTotal;
uint32_t expectedCommandQueueSubmitCount = getPerfCounters().commandQueueSubmitCallsTotal;
// One submission coming from clear and read back
++expectedVkQueueSubmitCount;
++expectedCommandQueueSubmitCount;
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCount);
EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
// One submission coming from draw and implicit submission from eglSwapBuffers
++expectedVkQueueSubmitCount;
++expectedCommandQueueSubmitCount;
ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 1.f);
swapBuffers();
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCount);
EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
}
// Ensure that glFlush doesn't lead to vkQueueSubmit if there's nothing to submit.
TEST_P(VulkanPerformanceCounterTest, UnnecessaryFlushDoesntCauseSubmission)
{
@ -4917,7 +4948,7 @@ TEST_P(VulkanPerformanceCounterTest, UnnecessaryFlushDoesntCauseSubmission)
initANGLEFeatures();
swapBuffers();
uint32_t expectedSubmittedCommands = getPerfCounters().submittedCommands;
uint32_t expectedVkQueueSubmitCalls = getPerfCounters().vkQueueSubmitCallsTotal;
glFlush();
glFlush();
@ -4925,17 +4956,17 @@ TEST_P(VulkanPerformanceCounterTest, UnnecessaryFlushDoesntCauseSubmission)
// Nothing was recorded, so there shouldn't be anything to flush.
glFinish();
EXPECT_EQ(getPerfCounters().submittedCommands, expectedSubmittedCommands);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
// One submission for the above readback
++expectedSubmittedCommands;
++expectedVkQueueSubmitCalls;
glFinish();
EXPECT_EQ(getPerfCounters().submittedCommands, expectedSubmittedCommands);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
glFlush();
glFlush();
@ -4943,7 +4974,7 @@ TEST_P(VulkanPerformanceCounterTest, UnnecessaryFlushDoesntCauseSubmission)
// No addional submissions since last one
glFinish();
EXPECT_EQ(getPerfCounters().submittedCommands, expectedSubmittedCommands);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
}
// Ensure that glFenceSync doesn't lead to vkQueueSubmit if there's nothing to submit.
@ -4953,13 +4984,13 @@ TEST_P(VulkanPerformanceCounterTest, SyncWihtoutCommandsDoesntCauseSubmission)
initANGLEFeatures();
swapBuffers();
uint32_t expectedSubmittedCommands = getPerfCounters().submittedCommands;
uint32_t expectedVkQueueSubmitCalls = getPerfCounters().vkQueueSubmitCallsTotal;
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
// Nothing was recorded, so there shouldn't be anything to flush.
glFinish();
EXPECT_EQ(getPerfCounters().submittedCommands, expectedSubmittedCommands);
EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
}
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER());