LunarG / gfxreconstruct

Graphics API Capture and Replay Tools for Reconstructing Graphics Application Behavior
https://vulkan.lunarg.com/doc/sdk/latest/linux/capture_tools.html
MIT License
416 stars 123 forks source link

Android AHardwareBuffer support for non-standard formats #1291

Open marius-pelegrin-arm opened 1 year ago

marius-pelegrin-arm commented 1 year ago

What it's about

A Vulkan application on Android can use AHardwareBuffers with a "non-standard" format, (ie. not listed in the official documentation) and create textures from it in a perfectly safe and defined way. However, it is an undefined behavior for an application to create such a buffer itself - the buffer is often created by vendor applications that know what's happening "under the hood", as for the images yielded by the camera. Thus, when capturing an application that uses externally created AHardwareBuffers with non-standard formats, the same AHardwareBuffers cannot be created at replay time.

The current solution in GFXReconstruct is to completely ignore the issue and still create the buffer with an unauthorized format (which still works on most devices as the format is still known "internally" by Android) and as the format is not recognized in GetHardwareBufferFormatBpp, the buffer is not filled and used as-is by the following Vulkan commands, resulting in textures with undefined content.

The issue

Of course, undefined behavior is an issue in itself, but not filling the buffer also leads to artifacts and thus different results than the original application captured. Finally, absolutely no warning/error/message is displayed by GFXReconstruct.

Proposed solution

I think it is impossible to have at the same time a replay with the exact same behavior and output as the application because it is impossible to know directly what is inside an AHardwareBuffer with a non-standard format. What I think should be a good option is to give the choice to the user:

One of the two option could be the default behavior and the other a simple option passed through and environment variable at capture time.

bradgrantham-lunarg commented 1 year ago

See also https://github.com/LunarG/gfxreconstruct/pull/884

marius-pelegrin-arm commented 1 year ago

Indeed I had not seen this PR, thanks. The issue is that it only partially solves the issue for one known non-standard format, I think a "generic" solution would be preferable.

bradgrantham-lunarg commented 1 year ago

Sorry, I had not meant that #884 was meant to solve this issue. I only wanted to note that we had seen it before and are aware of it.

bradgrantham-lunarg commented 7 months ago

Some more detail:

One possible workaround for this issue is to use a commandbuffer to convert the non-standard format to one of the standard formats in capture and then dump that to the file.

bradgrantham-lunarg commented 7 months ago

Additional (sanitized) context from an internal email thread:

The game uses the buffer in order to render a video in the background of the starting menus. When replaying we fail to render that video completely. Instead we draw a green background while the menus are correct. However the actual game records and replays without problems (as long as the hacky patch is in place where it treats the format as the standard yuv ahb format so that we don't crash at the beginning). All of the [vendor's] formats appear to be yuv variations, so it would make sense if all these formats are used to render videos or feed input from other sources like the phone's camera.

Even if we manage to discover the secret handshake it takes to create buffers with these formats, we will still fail to render the video correctly as we currently only attempt to copy the content through the host and in this case the buffers are not host visible. However, I'm not sure if attempting to actually copy/convert the buffer is going to work either as I'm not sure how the game updates the buffers' content (through vulkan commands or in some other way)

So in this case even if we could create a buffer, it's not clear we can read the data either.