Vulkan MultiThread Tips

Vulkan RenderPass 整体的执行流程

Untitled

Vulkan多线程压力分析

When one of the render passes in the application contains a lot of draw calls, such as the gbuffer pass, for CPU submission efficiency it’s important to split the draw calls into multiple groups and record them on multiple threads. There are two ways to do this:

  • Record primary command buffers that render chunks of draw calls into the same framebuffer, using vkCmdBeginRenderPass and vkCmdEndRenderPass; execute the resulting command buffers using vkQueueSubmit (batching submits for efficiency)
  • Record secondary command buffers that render chunks of draw calls, passing the render pass to vkBeginCommandBuffer along with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; use vkCmdBeginRenderPass with VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS in the primary command buffer, followed by vkCmdExecuteCommands to execute all recorded secondary command buffers

While on immediate mode GPUs the first approach can be viable, and it can be a bit easier to manage wrt synchronization points on the CPU, it’s vital to use the second approach on GPUs that use tiled rendering instead. Using the first approach on tilers would require that the contents of the tiles is flushed to memory and loaded back from memory between each command buffer, which is catastrophic for performance.

上述分析主要讲述了一个RenderPass中DrawCall压力过高时,应该如何进行优化。在移动端上不利用多条Primary Command Buffer的原因是Primary Command Buffer的提交会把Tile中的数据写回到主存中,这肯定是dame的。

引用

Writing an efficient Vulkan renderer