Vulkan API Tutorial - 7 - Swapchain

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome to my Vulkan API tutorial number seven where we'll discuss the swap Jane sorry this one took a while I will I was a bit more busy than I thought I would be but you went along enough already so let's continue in short the swap chain is a collection of presentable images and methods of accessing and presenting those images swap Jane also handles the presentation time for us and in this way it manages the vertical synchronization so we don't have to manually deal with it swap chain is another extension to Vulcan it connects to the WSI extension and with it we can give images to the presentation engine there is also a swap chain extension for the displays but we're not gonna touch those so when I talk about the swap chain I talk about the window surface swap Jane so what exactly is a presentation engine then the presentation engine is an abstraction for platform compositor once we give an image for the presentation engine it will decide when and where the image should be drawn usually a presentation engine is a part of the operating systems window manager phone it can be a little bit more involved with the hardware we don't really need to worry about that too much swap chain image count is more familiarly referred to as double triple or quadruple buffering swap jam each count would be two so we have to swap chain images OpenGL is usually locked due to double buffering although the driver can on some platforms forced the OpenGL to do triple buffering DirectX has had triple buffering natively available for a long time already and we can also do that natively in Vulcan triple buffering is usually recommended for maximum performance and quality as it is used to prove and tearing at least on the directx anything more than triple buffering is usually unnecessary got buffering used in OpenGL for stereoscopic rendering is unrelated to this Vulcan handle stereoscopic images differently and for this tutorial we're not gonna do any stereoscopic rendering at all we're just gonna stick with double buffering but if you want to you can easily convert that to a triple buffering the first thing we're going to do we are going to go to the window dot CPP file within this file and within the function in its surface after we call a function bkq a physical device surface capabilities khr we're going to add a new check if surface capabilities dance currents extend down width or height is smaller than you int 32 max in that case we are going to set the current size I forgot to do this last time but all we really need to check this as soon as we get the surface when we create the surface we give it a size that we want however we need to be sure what surface size we actually got those are two different things we want it and what we got we can get the actual surface size from the surface capabilities instruction surface capabilities dark currents extend tells us the current size of this surface extent is a Vulcan synonym for size and it's often used with images extents contains width and height it's not quite that easy though as the current extent might also be set as you int32 max on both width and height if we got this value then the Vulcan implementation and the presentation engine does not care about what the size of swap gem images are going to be use so the first thing we check is if either width or height of the current extent is lower than you in 32 max if it is then we set the surface size X and service size Y to match the current actual size of the surface in my system using swap chain images smaller than the current surface size resulted the rendered image to appear on the upper left corner of that window using swap Jaime image is larger than the surface resulted to crash swap gen images might also be scaled to fit the surface by the Vulcan implementation but this is never guaranteed and you should be afraid of that crash so making sure that the your swap chain images match the surface size is always a good idea after this step we can be sure that surface size X and surface iswhy are the actual size of that surface or at least sizes now it should work with everything it would be a good idea to create two sets of variables in most of these functions requested and actual but again for simplicity I'm gonna treat these variables as requests first and actual after the constructor has finished after this we can actually continue the tutorial to the actual meat of it so let's go to the window dot H file we're going to create two new functions void in its swap chain and void D init swap chain and we'll create these functions over the function bodies in the window dot CPP file and we'll also have the functions to their constructor and destructor in the construction can call the in it swap Jain function as a last function for now and in the this structure I'm gonna call the D in it swap Jane as a first function for now like so function that we are going to use here is a VK create swap Jane K HR and in that D init swap Jane function I'm gonna call VK destroy swap Jane k HR let's do the destroy swap Jane first this one takes a device first so renderer get bulk and device and the swab chain itself and the allocation callbacks let's create the swap chain handle in the window dot H file under the surface handle so VK swap Jane k HR swap Jane and by default it will be a null pointer or non hot null handle let's go back to the window at CPP file and give us swap chained to this destroy swap Jane function within the in its swap Jane function we call VK create swap Jane K HR function the first parameter is going to be the device again so renderer get walking device we need to provide creating 'fl to this us what changes up let's give a pointer to non existing data for now I'm gonna call this swap chain create info allocation callbacks it's gonna be a null pointer and the last parameter is going to be a pointer to that handle to the swap chain handle the type of this swap chain creates info it's going to be a structure called VK swap chain create info khr within this VK swap chain create in full structure the P next is we're not going to use that and flags is reserved for future use so we're not going to touch that either the first actual thing that we're going to change is the surface so we're just going to give the surface to this structure in here the next one is min image count now this is actually the amount of images we want to use so if I put two in here that will create double buffering the reason why it's called min image count is because we're going to tell or we're telling this a swap chain that we want two images at a minimum however it doesn't mean that we are going to get two images it means that we are definitely going to want at least two images so in theory or in some crazy platforms this could create triple buffered swap chain what I want to do here is actually go back to the window dot H file and under the window name I'm gonna create a new variable called swap chain image count and I'm gonna use this variable in the window dot CPP file again for this mean image count this small problem in here is because we actually need to limit this value ourselves before we pass it to this structure so I'm going to create a couple of tests in here this max image count and main image count tells us the range of images or amount of images we can have in the swap chain so surface capabilities dot max image count if this have whopping swap chained image count is larger than the max image count in our case swap chain in which count equals or gets set to service capabilities max image count if however this variable is smaller than min image count plus one in that case we're gonna set it to the service capabilities done many much I mean image count plus one minimum number of swap gem images is told by the surface capabilities structure we fill to when we created the surface main image count tells the absolute minimum amount of images we have to have and my system says 1 max image count tells the absolute maximum amount of images we can have and my system says 8 so I could have 8 buffering if I wanted to do that smallest optimal amount of swap gem images is min image count plus 1 this guarantees that we can own one image at any given time in my system this minimum optimal would be 2 which is double buffering image format this is the format we want our swap Jane images to be you need to be one of the format's supported by the surface we got one when we created the surface so we can just use that image color space and we also need to specify the color space currently there is only one option but to keep it consistent and capable of future updates I'm just going to use of one I picked when we created the surface swap Jane image size or extend as the Vulcan knows it we set the width of the image in here and same for the height image array layers is a bit funny one this is used to tell how many layers an image has one layer in this case means a traditional rendering and two would be a serious Copic rendering why this is funny is because in theory you can set this number higher as well you know for the tree height people out there like guess this might be a gift for certain types of presentations in the future you will need to render to each layer separately though none of this is automated for you and to keep this simple we won't be rendering serious Copic image usage this tells the swap chain how to how this image is going to be used its primary use it is of course to present an image to the presentation engine but here we define how are we actually going to handle this image otherwise in this case we need to draw into it so we'll set it VK image usage color attachment bit but if we didn't render to this image directly and we would only copy into it we could also set it as VK image usage transfer DST bit image sharing mode here we tell Vulcan are we going to share this image between queue families VK sharing mode exclusive means that we plan to not share so option images between queue families VK sharing mode concurrent would mean that we do and you need this if you want to present on a different queue family that you render with it's possible to render using two GPUs from different manufacturers to some extent but this is not related to that queue family index count this is ignored if sharing mode acerbic a sharing sharing mode exclusive which is the one that we are going to use P Q family indices this is also ignoring if the sharing mode is VK sharing mode exclusive this is a pointer type and you give an array of Q family indices that the swap chain images are shared with Q family index count variable of Bob tells how long this list is pre transform describes the transform of the surface relative to the trip presentation engine's natural' orientation it tells how the surface should be rotated and if it should be mirrored I'm not completely sure how this information is used because my PC only supports VK surface transform identity bit I think this is a case with most systems Android might benefit the most from this feature but for now we'll just use the current transform which would be the case surface transform identity bit composites alpha I'm not completely sure what the effects of this are but my system requires and only accepts VK composites alpha opaque baked reading from the specification composites alpha indicates alpha composition mode to use when the surface is composed together with other surfaces on certain window systems for now we'll just use the VK composite alpha opaque bit present mode tells the presentation engine how the percentage requests should be processed and cute internally in all simplicity this is your vsync option first we need to figure out our available options but I'll do that later clicked if we set this to true the Vulcan implementation is able to not render parts of the swaption image that isn't visible if sets of false then the Vulcan implementation is forced to always render the whole image every single time there are no bad side effects from this and the best case it will save some battery life as the Vulcan implementation is able to choose if it will run the fragment shader on part of the image that aren't visible this is the most useful on hand health devices like cell phones but we can pretty much always leave this enabled old swab chain finally we can give a pointer to the old swap chain or the handle to the old swap chain if we are reckons reconstructing this swap chain this is useful when we are resizing the window but for simplicity I'm not going to use this so what is give it a null handle we might enable window resizing later in their tutorials but I'm going to be really crude about it I'll just destroy the whole window when we resize it so not going to touch this one the final thing we need to worry about is the percent mode first let's create a temporary variable which is a type of 3k present mode khr I'm gonna call this % mode but default FIFO is always supported so let's see here VK presents mode FIFO khr if everything else fails Vulcan guarantee is that this % mode is always available also I'm gonna give this percent mode here already I want to use the mailbox I want to or I need to know the current available present modes that our surface can support and how do you figure this out by using this function The Keg a physical device surface presents modes it wants a physical device so GPU or renderer gets physical device then it wants a surface or a handle to the surface after that it wants a present mode count or a pointer to you int 32 T this is how to call function again this presents mode count is going to tell us how many percent modes this surface supports and the last option in this case it's going to be a null pointer the next step is actually I'm gonna create a vector of type VK present mode khr I'm gonna call this vector true sense mode list and I'm gonna initialize it with the size of % mode count then I'm gonna copy this line and call this function again with the last parameter pointing to this vector after this this present mode list vector has all the presents modes in it that our surface can actually support and I want to pick the best one out of there if we go to the present mode khr structure or enumerator sorry actually I guess I should explain all of these first immediate mode when you present an image it's going to be presented immediately like the name suggests and the old image that's being presented it's going to go to unused images all of this is happening inside the presentation engine so you might guess that this causes tearing but it is the fastest option the next is FIFO of before well anyways it means first-in first-out when you present an image it's going to go into your queue it's going to go into the end of that list and vertical banking intervals it's going to fetch the first one of that lists present that on the screen at the same time it's going to release the previous picture back into the unused images there's also five of relaxed but I'm not gonna touch that too much I'll give you a link to their son you can read more about that later intel has a lot of really good examples and information about this on the website now the last one is the mailbox this is preferred for gaming when you present an image it's going to go into a buffer at vertical banking intervals it's going to fetch that and present that image on the screen if you present another image is going to replace the one in the buffer if the image and the buffer hasn't been presented yet and the whole image in the buffer is going to go into unused images and again at vertical banking intervals it's going to fetch that image or present that image and release the old one back into unused images if he came with FIFO it means that your cursor or the game world might black a little bit when you game with mailbox however that means that you won't experience any tearing and you will have the newest possible frame always it should be noted that you can only get the full advantage of the mailbox mode if you have more than two buffers so you have to have at least ripple buffering I'm going to check if my system supports in the mailbox I know that it does already but not every system might support it so I'm just going to go through this vector present mode list and within this loop I'm gonna check if M equals VK presence mode mailbox if it does I'm gonna set this percent mode variable that the temporary variable that I created to M so you might see from this that I want to use vertical synchronization you can use the immediate of course you need to modify this block of code to account for that part just again to keep it simple I'm just gonna enable the vertical sync vertical synchronization by default I'm just gonna check that if the mailbox is available on cannot use that instead and now should basically do it the last step I want to do is to get the actual amount of swap chain images I'm going to call a function called VK get swapped chain images khr first barometer is a device the second parameter is the swap gene and the third one is a pointer to you int 32 T which returns our amount of or swap Jane image count and I'm actually just going to store back store it back to this swap Jane image counts variable and the last one will be a null pointer will actually handle the images on the next tutorial okay so one more thing I'm going to include shared and check the results of these two functions as well as these two up in here like so okay let's try to run this and see what happens it should fail by the way there we go VK create swap gen KH are called even though the kv k KH r swap chain extension was not enabled for this device so what we need to do is we need to go back to the friend array dot cpp and within the function let's see there we go set up a layers and extensions we need to enter introduce a new function or extension sorry and this one will be a device extension so device extensions push back and this will be a macro again so VK k HR swap chain extension name and that should enable our swap chain extension and the program should work just fine and it does there are multiple types of extensions in vulcan khr is the most common one currently and it's the kind of extension that's supported by multiple manufacturers however if an extension is a khr it doesn't necessarily mean that every single GPU will support that specific extension let's actually set a breakpoint in here and see what happens when we run the code we do get our swap chain and the swap chain image count is still 2 so we got two images in the swap chain and we are ready to go and handle the images next but I guess that's the topic for the next tutorial so I'll see you later you
Info
Channel: Niko Kauppi
Views: 9,229
Rating: undefined out of 5
Keywords: vulkan, api, tutorial, specification, graphics, programming, gpu, graphics card, c++, cpp, code, coding, advanced, close to metal, glnext, swapchain, v-sync
Id: VQ-T1KTtb7k
Channel Id: undefined
Length: 30min 50sec (1850 seconds)
Published: Sun May 15 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.