(upbeat music)
Welcome to the Android GPU Inspector session.
Hi, my name is Jay Kong,
and I’m a Product Manager working on Android Games.
I have with me Francesco, who’s a partner developer advocate
working on games as well.
Today, we’d like to talk about what’s new in Android GPU Inspector
since our open beta release last year, and also walk through a real-life example
on how to optimize the graphics in your games with this tool.
Before we start, we’re also doing a Q&A as part of this session.
Add your questions in the Q&A tool
on the event website and our team will look at them.
You may not see them pop up right away, but rest assured, we're reviewing them
and we’ll get to as many of them as possible during this event.
If you've seen the Android Game Development Kit talk,
you'll remember there are three key areas of game development where AGDK can help.
If you’ve not, don’t worry, and please feel free to watch that session after this.
Android GPU Inspector is part of AGDK
and it falls within the performance optimization category of the kit.
The goal of this tool is to help developers like yourselves
optimize your games pre and post-launch.
Now, before we dive into the new stuff, I'd like to give a quick recap.
We set out last year with a vision of building a single tool
that will help developers profile and debug graphics on Android, regardless of device.
For all of you who are watching,
we know that this area is still a big pain point.
As a result, we built Android GPU Inspector, or AGI for short,
collaborating with many top studios and released it in open beta last year.
Since then, we’ve greatly improved the stability and the feature set of the tool
which we'll share more about.
In the open beta's launch last year,
AGI came with what we call the Systems Profiling Mode.
This mode lets you take a trace of events of the entire system with your game running.
It captures system activities and high-frequency hardware counters
and plots them on a timeline, similar to our Systrace tool.
However, the key differences between this and the Systrace tool
is that AGI provides high-frequency GPU counters and GPU activity information.
Moving on to the new stuff.
One highly requested feature we added was GPU memory support.
Historically on Android, GPU memory is a black box.
The system was only able to represent how much total memory was being used.
What part of that belonged to GPU was unknown.
We worked with Qualcomm, Imagination, and ARM to add the ability to track GPU memory.
When you take a systems trace now, you'll be able to see a GPU memory track
that tells you how much GPU memory is being used at that point in time.
We’re also doing a deeper integration of showing GPU memory,
such as object-level breakdowns.
While AGI is a Vulkan-first tool,
we know that a lot of your content is still running on OpenGL ES.
We've added OpenGL ES support via ANGLE,
which is Google's OpenGL abstraction layer.
It translates OpenGL to Vulkan in the context of AGI.
This is super exciting because from an engineering perspective,
we won't have to maintain two code bases, one in Vulcan and one in OpenGL.
And that allows us to focus on adding and improving features on AGI.
Next, I want to talk a little bit about device support.
Recall that part of the vision is that we want AGI to work on all devices out there.
Since last year, we’ve worked with Oppo and Samsung to add support
on some of their newer flagship devices
like the Samsung Galaxy S21 series and the Oppo Reno Find X3 and Find X3 Pro.
We’re also mandating all new Android devices released with Android 12 and above
to support GPU profiling out of the box.
You can learn more about the currently supported devices
at the link shown on the slide.
Finally, as hinted by the title of the talk,
we're introducing something what we call the Frame Profiler.
This is something we believe is necessary to build an excellent GPU profiler.
Our envisioned workflow is that you’d first use the systems profiler
to get a high-level understanding of where the hot zones are
in the scenes that you're interested in optimizing.
Then, you’d use the Frame Profiler to pinpoint exactly where that bottleneck is.
The Frame Profiler allows you to deep dive into a single frame as it provides
timing information breakdowns at the render pass level.
Not only that, it also lets you explore textures,
geometries, shaders, render pipelines, et cetera,
to let you analyze and better understand what's going on in that frame.
I'll now hand this off to Francesco to showcase the AGI Frame Profiler
with a real-world example in Vertex Data Optimizations.
Please take it away, Fran.
Thanks, Jay.
I've been a game developer for couple of decades now.
I was working on this game a while ago and when it captured a frame using AGI,
I immediately noticed a very high GPU frame time.
The more interesting the time spent in the color pass
in relation to the other passes is very, very high.
Almost 40 milliseconds on a Pixel 4 to render your main pass
will likely lead to a suboptimal user experience here.
This won’t get better at all on lower-end devices.
By looking at the DRO calls,
I noticed a lot of geometry being pushed to the GPU,
which prompt me to check GPU counters in the Perf Tab.
You see the number there.
That’s the bandwidth being consumed by the GPU fetching vertex data
from main memory during the color pass.
And it’s even higher during the previous pass
which is likely to be the shadow pass where the shadow map is being rendered.
1.7 gigabytes per second is a very high value that does not make me happy at all.
For vertex read bandwidth,
you want to be well below 0.5 gigabyte per second.
On mobile devices, accessing memory and sending data
across the pass are very power consuming operations.
Higher bandwidth usage by the GPU means less bandwidth at disposal of the CPU,
higher power consumption, higher temperature, less battery life.
It goes downhill from here.
We need to look more closely at where this data's coming from.
Which is why I had a straight look at the vertex format.
The first vertex attribute is very likely the vertex position.
Four components to store position. We don’t need four.
Position can be stored with only three components: X, Y, and Z.
And 32-bit position to represent a component
of the vertex position in object space is way overkill.
By cleverly encoding position normalized in relation to the bounding box on the model,
we can easily get away with using only three 16-bit floating point components
to represent position with negligible loss of precision, less than 1%.
This is another typical vertex format that is storing position,
two vectors for the tangent space, normal and tangent,
a color texture coordinates.
The tangent space can be encoded with various techniques,
and it’s way beyond the scope of this presentation to go into the gritty details.
I mean, we can stay here for another couple of hours,
but we better talk about the fact that we can store four components,
each 16-bit floating point is generally more than enough for the tangent space.
Also, using 32-bit for two-texture coordinates is, again, way too much.
16-bit is more than enough for the texture coordinates.
With just some simple math, a bunch of ALU instructions in a shader,
we can reduce the size of this vertex from 48 bytes to a more reasonable 20 bytes.
A 60% reduction, which translates to at least 60% reduction in bandwidth.
We are close to the 0.5 gigabyte per second that I mentioned earlier.
Can we do better, yeah!
It so happens that on tiled GPU architectures which are prevalent on mobile devices,
the GPU will first process all the vertices in the scene that are being submitted.
And then in a second pass, after the binning phase,
we'll need the rest of the vertex attributes.
If we separate position in its own vertex stream, during the binning phase,
the GPU needs to only fetch position from main memory,
six bytes in our compressed vertex, instead of the full 48 bytes
in our uncompressed vertex and unsplit original form.
That’s 12.5% of the original bandwidth during the binning phase only.
To sum it up: compress your geometry.
You will save bandwidth, which translates to saving battery,
which translates to longer gaming sessions for your players,
and will also make me pretty happy.
And please take advantage of tiled architectures
by storing position in its own vertex stream,
along with the other attributes that affect position.
Bone weights for animated geometry, for example.
In the game we just looked at, we can easily achieve
a 70-80% reduction in vertex bandwidth
and a massive improvement in the GPU frame rendering time.
And Jay will have another quick word for you.
Thanks, Fran.
AGI was conceived and built from your needs and your feedback.
Please continue engaging with us to let us know what you’d like to see in AGI
to make game optimizations for you easier.
As AGI is open source, feel free to reach out to us
on our GitHub repository linked on the slide,
or you can also join our mailing list, also linked on the slide here.
Now armed with the knowledge we just went through,
go and download the GPU Inspector and give it a try.
Get acquainted with it.
Give it a go and make some great games on Android.
My name is Francesco Carucci. Thank you for attending.
(upbeat music)