Tag Archives: command

Mipmap generation : Transfers, transition layout

Hi guys !
This article will deal with Mipmap’s generation.

What is a Mipmap ?

A mipmap is a kind of loop rescaling on a texture.
For example, take one 512×128 texture, you will divide the size by 4 at each level :

  1. level 0 : 512×128
  2. level 1: 256×64
  3. level 2: 128×32
  4. level 3: 64×16
  5. level 4: 32×8
  6. level 5: 16×4
  7. level 6: 8×2
  8. level 7: 4×1
  9. level 8: 2×1
  10. level 9: 1×1

Mipmap

Why do we need Mipmap ?

It can be seen as a Level of Detail (LoD). If the object is far from the camera, you do not need to use all details but only some. So, instead to send to the GPU all the texture, you can send a mipmap with a different level that is far away lighter than the original (level 0).

How to generate Mipmap in Vulkan ?

Contrary to OpenGL which provide glGenerateTextureMipmap function, Vulkan does not provide function to build mipmap by itself. You have to deal with it by yourself. There are two ways.

  1. Using the shaders and framebuffers. You use the shader to draw into the framebuffer which is half the size of the texture, and half of the half…
  2. Using the transfer queue and vkCmdBlitImage which blit one image into another.

We are going to see the second way.
To do it, we are going to use the Transferer class we saw prior.

First, the number of mipmaps level for one image is :
levels=floor(log_2(max(width, height))) + 1

The idea of the algorithm to create the differents mipmap levels is easy.

  1. You initialize the level 0 (from a file for example) and put the layout to TRANSFER_SRC
  2. You set the level 1 to TRANSFER_DST
  3. You blit the level 0 to the level 1
  4. You set the level 1 to TRANSFER_SRC
  5. You reitere 2 3 4 for each level.
  6. You transition all levels to the layout you need.

So, here is our code :

Beginning with the CommandBuffer

Prepare the blit !

The loop begins from 1 because the level 0 is already initialized.
After, you explain to Vulkan which level you will use as the source, and which one you will use as the destination.
Do not forget to use max when you compute the offset because if you do not use it, you will be unable to build mipmap for the last levels if your image is not with a 1:1 ratio.

Transition and Blit

After, you have to transition your mipmap level image layout you want to draw into to TRANSFER_DST

And you just use blitImage to blit it.

After, you have to transition the mipmap level image layout to TRANSFER_SRC

Finish

You have to transition all mipmap levels to the layout you want to use

Conclusion

This article was short, but mipmap are not that difficult to handle. Do you like this kind of short article?
Maybe the next article will be about descriptor set management.

Reference

Sascha Willems Mipmap