Vulkan on Android 3 — Render Nothing with Lots of Hidden Details Part 5

Jin-Long Wu
3 min readOct 17, 2018

--

Photo by Markus Spiske on Unsplash

The post is about command buffers and pools and synchronization primitives. We usually use them together but in this post, we are about to inspect them individually and we’ll see how they work with each other in the next article.

Command Buffer and Command Pool

We can view command buffers as display lists in OpenGL on ancient times, which though have deprecated now. However, it does not mean it is an outdated mechanism, and just because OpenGL is such a huge state machine that it is so hard to keep display lists valid as time goes by. But in Vulkan, everything is explicit. We build our own command and specify our states and hence, its modern successor command buffer can show off its ability again. Here an example of command buffer from NVIDIA and command buffers’ life cycle.

https://developer.nvidia.com/engaging-voyage-vulkan
https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#commandbuffers-lifecycle

Two types of command buffers exist, one is VK_COMMAND_BUFFER_LEVEL_-PRIMARY , and the other is VK_COMMAND_BUFFER_LEVEL_SECONDARY. Secondary buffers can only be executed by primary buffers and primary buffers can be submitted to queues. CreateAndBeginCommandBuffer and EndAndSubmitCommandBuffer are paired to create a flow of allocating, recording, submitting, and freeing command buffers.

Command pools are opaque objects that command buffer memory is allocated from, and which allow the implementation to amortize the cost of resource creation across multiple command buffers.

We separate pools based on queue operation types, they are graphics, compute, transfer, and sparse memory management, and furthur, we subdivide them into General*Pool and ShortLived*Pool based on VkCommandPoolCreateFlagBits.

  • BuildCommandPools : Creates ShortLived*Pool and General*Pool with and without additionalVK_COMMAND_POOL_CREATE_TRANSIENT_BIT.
  • CreateCommandPoolImpl : Creates four types of command pools at most based on queue operations and only dedicated queue family will be considered to prevent duplicated destruction in destructor.
  • EndAndSubmitCommandBuffer : End recording and submit a command buffer. VkFence is used as the CPU-GPU synchronization for waiting for GPU side to complete.

Fence and Semaphore

Fences are synchronization primitives that can be used to insert a dependency from a queue to the host. While semaphores are synchronization primitives that can be used to insert a dependency between batches submitted to queues. We can roughly understand that fences are used for CPU-GPU or GPU-CPU synchronization and semaphore are used for GPU-GPU synchronization.

Fences and semaphores are of two states, signaled or unsignaled. The difference is that we can specify the state of a fence on creation, and reset its state to unsignaled manually while for a semaphore the state change is the side effect of Vulkan function waiting for it being signaled.

--

--