A complex application has frequently changing performance characteristics due to both a varying number of objects to draw and different effects that need to be applied to them. When characterizing the performance of an application, it can be easy to miss scenes which need optimization, especially if they are ephemeral.
A debug overlay that shows on-the-fly statistics from the running application can greatly aid the developer in finding where the bottlenecks are and which scenes need further investigation and profiling.
ANGLE’s Vulkan debug overlay is drawn in a single compute pass for efficiency. The initial implementation includes a few pieces of information for demonstration purposes. Here’s the glmark2 terrain scene with these overlay items enabled:
This is a screenshot of a debug build, hence the low FPS. The command graph size is constant every frame.
Overlay items are of two fundamental types:
Built on these, various overlay item types are defined that gather statistics. Five such types are defined with one item per type as example:
swap()
.vkQueueSubmit()
, the memory waste from command buffer pool allocations is recorded in the histogram.Overlay font are placed in libANGLE/overlay/ which gen_overlay_fonts.py processes to create an array of bits, which is processed at runtime to create the actual font image (an image with 3 layers).
The overlay widget layout is defined in overlay_widgets.json which gen_overlay_widgets.py processes to generate an array of widgets, each of its respective type, and sets their properties, such as color and bounding box. The json file allows widgets to align against other widgets as well as against the framebuffer edges. The following is a part of this file:
{ "name": "VulkanValidationMessageCount", "type": "Count", "color": [255, 0, 0, 255], "coords": [10, "VulkanLastValidationMessage.top.adjacent"], "font": "small", "length": 25 }, { "name": "VulkanSecondaryCommandBufferPoolWaste", "type": "RunningHistogram(50)", "color": [255, 200, 75, 200], "coords": [-50, 100], "bar_width": 6, "height": 100, "description": { "color": [255, 200, 75, 255], "coords": ["VulkanSecondaryCommandBufferPoolWaste.left.align", "VulkanSecondaryCommandBufferPoolWaste.top.adjacent"], "font": "small", "length": 40 } }
Negative coordinates in this file indicate alignment to the right/bottom of the framebuffer. OtherItem.edge.mode
lets an item be aligned with another. If mode
is align
, the item has the same origin as OtherItem
and expands in the same direction. If adjacent
, the item expands in the opposite direction.
Two compute shaders are implemented to efficiently render the UI:
subgroupBallot()
where possible, if not subgroupOr()
where possible or otherwise shared buffers to create the bitset collaboratively.present()
.To build ANGLE with overlay capability, angle_enable_overlay = true
must be placed in args.gn
.
Currently, to enable overlay items an environment variable is used. For example:
$ export ANGLE_OVERLAY=FPS:VulkanSecondaryCommandBufferPoolWaste $ ./hello_triangle --use-angle=vulkan
Possible future work