Nondeterminism on PowerVR
Android rendering issues on the Google Nexus Player with an Imagination GPU
In our posts so far (looking at Samsung S8, NVIDIA Shield and Google Pixel devices) we’ve seen how ShaderTest GLES identifies rendering issues, crashes, compile failures and performance issues cross-checking families of equivalent shaders.
We turn our attention now to Imagination’s PowerVR GPU, which ships with the Google Nexus Player. The Nexus Player is still actively supported by Google, with a recent Android 8.0 (Oreo) update.
What sticks out in the results is that the Imagination driver suffers from a lot of rendering issues, and that worse still it exhibits nondeterministic rendering, where repeatedly rendering a frame using a single shader gives different results.
The problem of nondeterminism is showcased by the above animated image, which comes from the results for shader family 002. The animation flips between a clean image (the expected result), and a corrupted image. These images are captured by rendering a frame using the same compiled fragment shader multiple times.
As well as being a pain for end users, nondeterminism is potentially very serious because it may be due to memory safety issues, where garbage data is read from invalid addresses due to a driver bug — we found an issue like this when applying our techniques to Apple GPUs in older iOS versions, which Apple subsequently fixed (see CVE-2017–2424).
Turning to deterministic rendering issues, we see several cases where even our small selection of shaders from ShaderTest GLES lead to multiple distinct wrong images per shader family. In the following, each row shows the reference image for a shader family, and two bad images rendered for variants in that family on the Nexus Player, with an Imagination GPU:
Here’s an executive summary of our results so far:
- Qualcomm: highest number of issues overall; highest rate of crashes; plenty of compile failures; quite a few rendering issues.
- Imagination: highest rate of rendering issues; only GPU to exhibit nondeterministic rendering; plenty of crashes and compile failures.
- NVIDIA: highest rate of timeouts by far; plenty of compile failures; some crashes and rendering issues.
- ARM: lowest rate of rendering issues and compile failures; plenty of crashes.
This highlights that all GPU designers have issues that ShaderTest GLES could help address.
This table, sorted by rendering issues, gives more detail; our website provides an interactive version that you can sort in other ways:
For shader family 002, Imagination’s reference image differs from all the others:
This difference propagates through all variants in the shader family. This might not be a bug — the GLES spec is deliberately loose on floating-point semantics — but the discrepancy would likely be useful for Imagination to investigate.
Until this post, we had not seen a device that managed to render an image for variant 199 of shader family 010. Well, now we have one! The Google Nexus Player, with Imagination’s PowerVR GPU and driver, renders an image, and it is the right image.
No clean sweeps
Despite doing better than the competition on that tough shader, overall the Imagination driver does seem to suffer from a lot of issues, and we don’t see any “clean sweeps”: for every shader family, our results show at least one rendering issue, compile failure or crash.
Let’s look at some more ARM Mali GPUs, this time in the Huawei Honor 9 and Honor 10 smartphones.