2D images in Vulkan

Hi,

I am a Vulkan n00b struggling to implement a project for some customers who have a bee in their bonnet about using Vulkan to display 2D images on an Android device (e.g. for viewing photos). First of all, is it even possible to get Vulkan to do such a thing? I would think ‘yes’, because Vulkan does textures for objects (or at least facilitates texturing by shaders) and textures are just 2D images bent over a 3D mesh, but I wanted to hear from experienced Vulkan users.

Second, assuming it is possible, my current understanding is that I’d have to generate vertices to define a rectangle (or possibly even a rectangular prism) oriented so that it fills the screen from edge to edge, then feed it through a vertex shader and rasterizer, then use a fragment shader to ‘paint’ the 2D image onto the fragments, then dump the result to a framebuffer. What I want to know is, is it possible to skip most of that process while still using Vulkan? Since a framebuffer is just a bitmap, isn’t there some way to load a 2D image, then dump its bits directly to the next available framebuffer?

As I mentioned, we need to be able to do this on Android. I’m currently targeting Android 7.1, because one of our test phones is 7.1 and the other is 8.0. I can’t think of any other relevant system info.

Sorry for the odd questions, but this is really important to our client; any light the forum could shed on this would be helpful.

Thanks.

I don’t know about Android specifics, but in general getting an external image onto a swapchain image can be done an easier way when you don’t need to apply any effects.
Just create a linear image in host memory and copy the texture data to it. Then you can blit it to the swapchain image using CmdBlitImage.

Going for that nice Vulkan sticker on your product, eh?
Well, you seem to already know this, but that sounds dumb (forgive my french):
Firstly, about 80 % of devices do not support Vulkan yet (they are android < 7.0). Alternative code path would have to be provided. And that alternative would probably be as good or better than Vulkan at this:
Secondly, Vulkan is not an API primarily for “displaying” stuff (the Vulkan implementation no doubt uses other APIs to achieve that). So, at best this is just underusing Vulkan, at worst Vulkan would just get in the way (bigger binaries, wasted development time messing with Native code, etc).

As said above you can create a linear image, and blit or copy (if it is same size) to the swapchain image. Most android devices (all?) have shared memory heap between the GPU and CPU, so there is no difference between host and device memory.

Assuming you want to actually do some interesting stuff in the fragment shader you would indeed make a rectangle (two triangles) to fill the screen and write on them. It can be managed in one triangle using clipping: link.
Or alternatively you could use a compute pipeline (with compute shaders).
Even so it would possibly be better to use widely supported OpenGL ES. Especially for simple stuff (such as single draw command to fullscreen quad per frame).

Just create a linear image in host memory and copy the texture data to it. Then you can blit it to the swapchain image using CmdBlitImage.

Actually, you can’t. Or rather, you can’t know a priori that you can. The swap chain’s images are not required to support any uses other than as render targets and as presentation sources. So copying into a swapchain image is something you have to check for via VkSurfaceCapabilitiesKHR::supportedUsageFlags.

Secondly, Vulkan is not an API primarily for “displaying” stuff (the Vulkan implementation no doubt uses other APIs to achieve that). So, at best this is just underusing Vulkan, at worst Vulkan would just get in the way (bigger binaries, wasted development time messing with Native code, etc).

To be fair, in the “displaying stuff” department, Vulkan has one advantage over other APIs: better control over swap behavior. Granted, if you’re just displaying an image you loaded, then that’s irrelevant.

[QUOTE=Alfonse Reinheart;42664]Actually, you can’t. Or rather, you can’t know a priori that you can. The swap chain’s images are not required to support any uses other than as render targets and as presentation sources. So copying into a swapchain image is something you have to check for via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
[/QUOTE]

That’s fair, though not implementing USAGE_TRANSFER_* is extra lazy, especially on UMA. HW database seems to support a claim that there is ubiquitous support for that on Android.

[QUOTE=Alfonse Reinheart;42664]To be fair, in the “displaying stuff” department, Vulkan has one advantage over other APIs: better control over swap behavior. Granted, if you’re just displaying an image you loaded, then that’s irrelevant.
[/QUOTE]

How so? Do you know how it is implemented on Android?
It seems to use the same API as anything else. Might as well not use Vulkan as middle-man, no? As you say, it is pointless if you do not intend to use Vulkan for its primary usage.

You could always stick to the standard Android interface stuff for displaying your pictures and persuade your client that because Android uses Vulkan internally for rendering the UI* your app is indeed using Vulkan.

FYI - while Vulkan support on Android was added in 7.0 (well, there were some dodgy drivers around earlier than that, but you don’t want to go there), targeting 7.1 as a minimum is no guarantee of Vulkan support. Many devices run 7.1 or 8, but don’t support Vulkan.

  • Actually, while I think I heard that somewhere, I can’t find a online source anywhere to back me up.

[QUOTE=Columbo;42668]You could always stick to the standard Android interface stuff for displaying your pictures and persuade your client that because Android uses Vulkan internally for rendering the UI* your app is indeed using Vulkan.

  • Actually, while I think I heard that somewhere, I can’t find a online source anywhere to back me up.[/QUOTE]

This is probably a problem, where facts do not matter… But this seems innacurate.
It is not impossible (the windowing architecture uses API-agnostic graphics memory that can generally-speaking be imported into GL as well as into Vulkan), but the documentation still says the composition is made using GL ES.