Vulkan, Wanna Be Friends? #3 Window Resize and SwapChain Recreation

We want to be able to resize our window. 
Many Games don't let dynamic and flexible resize maybe because of the check and additional work each frame and It's not logical to change windows size and resolution so often, so It's a win-win!
After one resize we are freeing and allocating memory which has cost, thus hard to do each frame when resizing dynamically.

Here's a version where we don't handle Resize:

Handling Resize In Vulkan To Resize our window we have to Recreate our whole SwapChain and thus these below as before when initiating Vulkan: ReCreate Image Views Because of New SwapChain Images.ReCreate FrameBuffers Because Width and Height and Image Views(Views to SwapChain Images) ChangedReCreate Graphics Pipeline Because viewport and scissor need to change.ReCreate and Record new Command Buffers Because of New SwapChain ImagesVulkan Tutorial: The render pass needs to be recreated because it depends on the format of the swap chain images.Note (Step 5): It's …

Vulkan, Wanna be Friends? #1

After I rendered my first Triangle (see post) with Vulkan, a lot of questions grew in my head and made me more confused. So this post is about getting more comfortable and familiar with VulkanAPI and my questions and the answers I found for them.

First, let's talk about Unity πŸ˜‹

Unity GDC

I just saw the Unity GDC 2019 Keynotes esp the DOTS feature and a lot of new awesome features.

I question myself now with so many bad feelings in me:
- "Why go through all this problem when Unity does it in few clicks(and a billion more awesome things like shader graphs)?",

well, the answer is "I don't want to use Unity, I want to work at unity or even be part of something bigger."

The things that got most of my attention was Unity's partnership with Havoc which Is a really powerful physics engine. And their new compiler that transforms C# into efficient assembly code.
It made me want to write compilers and physics engine and do a million more cool things in this beautiful non-ending industry (this is the part when I hate timeπŸ˜’).

Let's Get Back To Learning Vulkan 

Some of my questions may seem stupid but nothing to be ashamed of, that's part of the learning.

  • What does vkBindGraphicsPipeline do?
    • Well, I thought (so wrong) that Graphics Pipeline is run once per frame but I just realized that a Vulkan app can have many Graphics Pipelines for different shaders and it's run per DrawCall (you can get that by just looking at RenderDoc results 😊😊 )

  • I didn't completely understand the whole render passes and especially dependency between subpasses.

RenderPass: render pass represents a collection of attachments, subpasses, and dependencies between the subpasses, and describes how the attachments are used over the course of the subpasses. The use of a render pass in a command buffer is a render pass instance.

SubPass: Subpasses describe access to attachmentsDependencies can be defined between the subpasses, 

I need to code to actually understand it but this is enough for me now, but one more thing! why the hell a single subpass needs dependency? 

This is the question that I spent a lot of time searching and found out there are many others having a hard time understanding it too, the answer is simple first let's explain what  VK_SUBPASS_EXTERNAL is.

There are 2 built-in subpasses that take of transition at the beginning and the end of the renderpass.

(According to Ekzuzy is this post)
VK_SUBPASS_EXTERNAL means anything outside of a given render pass scope. When used for srcSubpass it specifies anything that happened before the render pass. And when used for dstSubpass it specifies anything that happens after the render pass.


My current wait stage in submit_info was VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT  meaning that when it is at the top of the pipeline it waits until the image from swap chain is acquired through vkAcquireNextImageKHR but We want to wait with writing colors to the image until it's available, so we should specify the stage of the graphics pipeline that writes to the color attachment. so it is better if the wait stage is  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT.
but the transition (from before built-in subpass to subpass 0) occurs at the start of the pipeline but we haven't acquired the image then so we must specify a dependency as follows :
/* Only need a dependency coming in to ensure that the first
   layout transition happens at the right time.
   Second external dependency is implied by having a different
   finalLayout and subpass layout. */
VkSubpassDependency dependency = {
    .srcSubpass = VK_SUBPASS_EXTERNAL,
    .dstSubpass = 0,
    // .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
    .srcAccessMask = 0,
    .dependencyFlags = 0};

/* Normally, we would need an external dependency at the end as well since we are changing layout in finalLayout,
   but since we are signalling a semaphore, we can rely on Vulkan's default behavior,
   which injects an external dependency here with
   dstAccessMask = 0. */
Of course, there are a lot more questions in my mind about subpasses but I'll leave it here to go actually code.

See these links for more info: 

  2. Specs
  3. Vulkan-Tutorial
  4. Reddit
  5. Subpass dependencies for a single subpass. How to?
  6. Synchronization Examples by KhronosGroup
  7. RenderPasses In Vulkan (YouTube)

  • Why we need 4 Command Buffers for 4 ImageViews?

    • Well, that's obvious we write to each of the swap chains' ImageView's (I actually understood that by watching this video which is somehow relevant) 

  • What exactly a surface instance extension is? Is it OS dependent?
    • Vulkan is a platform agnostic API so the surface is an extension and for example in Windows systems, it needs a handle(HWND) to the window.

  • What if the formats in ImageView or SwapChain or Render and Sub Passes don't match? 

    • Next Section 😊
I have many other questions but I decided to go actually code instead of research and see samples and change them to better understand Vulkan.

And btw this blog's awesome (I Am Graphics And So Can You!)

Samples and Changing Code😎

  1. So I changed the renderpass format a bit, didn't see any change in some cases and crashes (access violation 😭) in some other. I figured it's all about memory and Data.
  2. Changed Vertex Buffer and Index Buffer of Triangle Sample of Sascha Williems to draw a cool 3D triangle(ish) you can see in the gif below. Although I haven't implemented vertex and index buffer in my own project it helped me get into the mindset and see the project.
  3. Changed the shaders in triangle sample to pass data between stages (out of vert -> in of frag) and Also learned about the 3 famous matrices and UBO a little by looking at the shaders

I was streaming me writing Vulkan and made my friend watch it πŸ˜›

Anyways it helped me a lot getting more comfortable with Vulkan API and I ran a lot more samples and tried to change them. It's so satisfying πŸ˜„.

I hope I'll be able to write a cooler program than these samples one day (blog post #infinityπŸ˜‚)

Have a Nice Day!