RenderPass可能是Vulkan API中最复杂的部分,尤其是结合subpass使用时。“VK_KHR_dynamic_rendering”扩展的引入简化了这一点,不过依旧没有替代RenderPass的所有使用场景。dynamic rendering相当于单个subpass的RenderPass,无法在移动端Tile-Based的架构中享受到subpass带来的提升。”VK_EXT_shader_tile_image”扩展可以解决这个问题,不过这个扩展今年5月份才添加到Vulkan SDK中,目前还没有被GPU Info收录,应该还没有设备支持。
对于想要了解dynamic rendering如何使用的可以参考《Vulkan动态渲染(dynamic rendering)教程》,本文仅仅是对比RenderPass和dynamic rendering使用方式的不同,不涉及具体细节。
RenderPass
上面是和RenderPass有关的类型,大致的用法是:
- 创建VkRenderPass,需要在VkRenderPassCreateInfo中指定包含的attachment和subpass,这里的attachment是VkFormat,subpass中需要指定输入和输出attachment
- 创建每个attachment对应的VkImage和VkImageView
- 为swapchian中的每个image创建一个VkFramebuffer,需要在VkFramebufferCreateInfo中指定前面创建好的VkRenderPass和全部attachment,这里的attachment是VkImageView
- 为VkRenderPass中的每一个subpass创建一个VkPipeline,在VkGraphicsPipelineCreateInfo中指定VkRenderPass和subpass
以延迟渲染为例,假设我们需要创建geometry pass和lighting pass两个subpass,geometry pass输出position, albedo, normal,lighting pass输入position, albedo, normal,输出color, depth,并且支持3缓冲。
那么我们一共需要创建:
- 7个VkImage和VkImageView,3个color+position+albedo+normal+depth
dynamic rendering
上面是和dynamic rendering有关的类型,可以看到简单了非常多😂,完全去掉了VkRenderPass和VkFramebuffer。
基本的用法是:
- 创建VkPipeline时不再需要指定VkRenderPass和subpass,而是通过pNext指定VkPipelineRenderingCreateInfo,在VkPipelineRenderingCreateInfo中填写attachment的VkFormat
- 为每个attachment创建VkImage和VkImageView
- 最后在函数vkCmdBeginRendering的参数VkRenderingInfo中指定attachment的VkImageView
还是以延迟渲染为例,使用dynamic rendering后仅需要创建:
可以看到在功能相同的基础上(假设使用了”VK_EXT_shader_tile_image”),dynamic rendering比RenderPass简单了不只一个数量级。可以想象再过几年dynamic rendering很可能会完全取代RenderPass,我们不再需要去了解RenderPass了。但很遗憾目前还不行,至少面向移动端的游戏还不行。
另外,dynamic rendering如果结合VK_EXT_shader_object使用的话还可以省去VkPipelineRenderingCreateInfo,只保留VkRenderingInfo,这样可以说真正简单到无以复加。