Do we have to do two image layout transitions when creating a new image? - vulkan

When I want to upload an image to device local memory I first create an image, then I issue a layout transition to transition from UNDEFINED to TRANSFER DESTINATION, then I do a copy buffer to image. Then I transition from TRANSFER DESTINATION to whatever layout I want. Is there a more direct way to do this? In vkCmdCopyBufferToImage there is an argument 'dstImageLayout'. I made the mistake of thinking that the argument tells Vulkan to transition the image automatically to that layout as it copies it. This 'would' seem to me to be more efficient and make more sense, but it's not what I thought it was.
Is there a way to do this without two layout transitions? It's OK if there isn't, I think this is the proper way to do it, I just wanted to make sure.

You do not strictly speaking have to perform two layout transitions. The GENERAL layout can be used with basically anything. So you could just transition it once, copy into it, and use it from there.
However, this would be pointless for several reasons. First, it's reasonable to assume that any layout transition from UNDEFINED will be a no-op as far as actual GPU processing is concerned. Such transitions conceptually trash any of the contents of the image, so there's no point in having the GPU do anything to the image's bytes.
Second, in order to use an image you copied into, you will need some kind of explicit synchronization between the copy operation and the usage of it. Whatever that synchronization is, it may as well include a layout transition. The GPU is going to have to make sure the two don't overlap, so you may as well toss in a layout transition.
Lastly, using GENERAL like this is a premature optimization and therefore should be avoided unless you have profiling data telling you that layout transitions are an actual performance problem (or you have no other choice).

LAYOUT_TRANSFER_DST is by definition the most efficient target for copies. So no other layout can be more efficient.
Some actual GPU might perform no actual layout transitions. The layout system is just a general API abstraction. It is not even defined what "layout" actually is, and the GPU driver may use the API concept whichever way it is beneficial for it.
If a particular picky GPU needs the image in such specific layout when copying into it, then there's no way around it, and there would be two layout transitions no matter how you shape the API. If the GPU does not need it, then it will just elide the layout transitions on its own.

Related

Rendering multiple objects with different textures, vertex buffers, and uniform values in Vulkan

My background is in OpenGL and I'm attempting to learn Vulkan. I'm having a little trouble with setting up a class so I can render multiple objects with different textures, vertex buffers, and UBO values. I've run into an issue where two of my images are drawn, but they flicker and alternate. I'm thinking it must be due to presenting the image after the draw call. Is there a way to delay presentation of an image? Or merge different images together before presenting? My code can be found here, I'm hoping it is enough for someone to get an idea of what I'm trying to do: https://gitlab.com/cwink/Ingin/blob/master/ingin.cpp
Thanks!
You call render twice per frame. And render calls vkQueuePresentKHR, so obviously the two renderings of yours alternate.
You can delay presentation simply by delaying vkQueuePresentKHR call. Let's say you want to show each image for ~1 s. You can simply std::this_thread::sleep_for (std::chrono::seconds(1)); after each render call. (Possibly not the bestest way to do it, but just to get the idea where your problem lies.)
vkQueuePresentKHR does not do any kind of "merging" for you. Typically you "merge images" by simply drawing them into the same swapchain VkImage in the first place, and then present it once.

Moving image layouts with barrier or renderpasses

The vulkan docs mention that moving image layouts in render passes (see VkAttachmentDescription structure) is preferred compared to moving them using barriers (i.e. vkCmdPipelineBarrier). I can understand that since the latter introduce sync points which constrain parallel execution.
Now consider a typical example: A transition from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL. In this case the resource is going to be read in the shader, but in order to do that safely it is necessary to synchronize the writing of the color attachment with the reading in the shader. In other words we need to use a barrier anyway and moving the layout in the render pass doesn't seem to give any advantage at all.
Can somehow explain how all this works in detail? In which situations does one have a real advantage of moving layouts in render passes? Are there (practical) layout changes which do not require further synchronization?
Firstly, you are not given a choice. The API forces you to provide finalLayout, and intermediate VkAttachmentReference::layouts. You can use vkCmdPipelineBarrier inside the render pass conditionally (aka subpass self-dependency), but one of the rules is you are not allowed to change the layout of an attached image:
If a VkImageMemoryBarrier is used, the image and image subresource range specified in the barrier must be a subset of one of the image views used by the framebuffer in the current subpass. Additionally, oldLayout must be equal to newLayout, and both the srcQueueFamilyIndex and dstQueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED.
So during a render pass, you can only change layout using the render pass mechanism, or you must be outside the render pass. That leaves only the "outside render pass" case to discuss:
Good way to think of a render pass is that it (potentially, based on platform) copies the resource (using loadOp) to specialized memory, and when done copies it back (using storeOp) back to general-purpose memory.
That being said, it is reasonable to assume you may get the layout transition to finalLayout for free as part of the storeOp. (And similarly the transition from initialLayout to first VkAttachmentReference::layout as part of the loadOp.) So, it makes sense to have the layout transition as part of the renderpass, if possible\convenient enough.

Imagemap usage in qml

Is there any way to build an image map with qml (qt quick) components directly without importing html code?And I want to it's coordinates be same as html imagemap's coordinates(I dont want to recalculate my image map coords).
and
my shape is rectangular.tnx
No, there is no way. MouseAreas are always rectangular.
You would need to provide a some kind of collision detection function, to check whether your click happened inside of your object, described by the coordinates.
For this you can implement any of the algorithmns out there, in a way, that it supports your coordinate format. The right choice depends on the characteristics of your objects, like:
Is it a circle?
Is it a regular shape?
Is it convex?
Is it concave?
There are many good pages on collision detection, though a performant implementation might be tricky - especially in QtQuicks JS, so you probably want to do it in C++.
Another shot you might take, is dropping your coordinates, and produce masks that can be used with the solution provided here: https://stackoverflow.com/a/38177820/2056452 (coming from an official example)

Create mock 3D "space" with forwards and backwards navigation

In iOS, I'd like to have a series of items in "space" similar to the way Time Machine works. The "space" would be navigated by a scroll bar like feature on the side of the page. So if the person scrolls up, it would essentially zoom in in the space and objects that were further away will be closer to the reference point. If one zooms out, then those objects will fade into the back and whatever is behind the frame of refrence will come into view. Kind of like this.
I'm open to a variety of solutions. I imagine there's a relatively easy solution within openGL, I just don't know where to begin.
Check out Nick Lockwood's iCarousel on github. It's a very good component. The example code he provides uses a custom carousel style very much like what you describe. You should get there with just a few tweaks.
As you said, in OpenGL(ES) is relatively easy to accomplish what you ask, however it may not be equally easy to explain it to someone that is not confident with OpenGL :)
First of all, I may suggest you to take a look at The Red Book, the reference guide to OpenGL, or at the OpenGL Wiki.
To begin, you may do some practice using GLUT; it will help you taking confidence with OpenGL, providing some high-level API that will let you skip the boring side of setting up an OpenGL context, letting you go directly to the drawing part.
OpenGL ES is a subset of OpenGL, so essentially has the same structure. Once you understood how to use OpenGL shouldn't be so difficult to use OpenGL ES. Of course Apple documentation is a very important resource.
Now that you know a lot of stuff about OpenGL you should be able to easily understand how your program should be structured.
You may, for example, keep your view point fixed and translate the world (or viceversa). There is not (of course) a universal solution, especially because the only thing that matters is the final result.
Another solution (maybe equally good, it depends on your needs), may be to simply scale up and down images (representing the objects of your world) to simulate the movement through the object itself.
For example you may use an array to store all of your images and use a slider to set (increase/decrease) the dimension of your image. Once the image becomes too large for the display you may gradually decrease alpha, so that the image behind will slowly appear. Take a look at UIImageView reference, it contains all the API's you need for it.
This may lead you to the loss of 3-dimensionality, but it's probably a simpler/faster solution than learn OpenGL.

Simple, but dynamically generated flow chart or process chart view for iOS

Perhaps "flow chart" or "process chart" isn't even the correct terminology for what I'm looking for, but it's the best analog I can come up with. Basically, I'm trying to find a library or class that allows for the dynamic creation (in code) of connected cells/UIViews within a given space. In code, you could add/delete ordered cells from the view and it will arrange accordingly. Normally, if the superview size permits (i.e. iPad), it would arrange these connected cells horizontally. If it's space constrained (iPhone), it would arrange as many cells as possible on one line horizontally, then continue the rest of the cells horizontally below ... akin to a graphical "word wrap".
Granted, I doubt there's a magical library that does all of this, but if the SO community can point me to some better terminology and/or some potential candidates to fork, I would be incredibly appreciative.
I've looked at AQGridView and it is such a vast library, I believe it's overkill with a compiled size of +700 Kb. SSCollectionView is really close, but you have to manually center cells and it doesn't yet support variable cell height/width.
To give you a better sense of what I'm imagining, here's a pic:
Done. I had to write my own, but it works just like I wanted it to. Feel free to fork my AppendingFlowView repository at GitHub.
It's dynamic (add stages on demand).
It responds to changes in the master view by reorienting and resizing the cells as necessary with animation!
It handles multiple rows automatically, depending on the desired cell size and number of cells.
I created this open-source ios-lib to easily create a graph or tree and draw it in a view.
Please feel free to make pull requests :)
https://github.com/chikuba/JENTreeView