vulkan从小白到专家——RenderPassFramebuffer
渲染最重要的就是每帧的执行逻辑,一帧包含多个renderPass,renderPass是包含了一组pipeline,pipeline跟drawcall基本上一一对应。
RenderPass定义了vulkan渲染过程中要使用到的三种Object的细节,分别是
- Framebuffer Attachment,
- Subpass
- Subpass Dependency
1 Framebuffer
简称fb,渲染中的RenderTarget,rt。
渲染前创建的Framebuffer的个数必须跟交换链的图像个数保持一致。
Framebuffer跟交换链的区别
每个交换链都需要创建framebuffer。Vulkan中的swapchain实际没有持有具体图像数据ImageView。framebuffer不同于交换链 实际持有一组图像。
1)从技术上讲,交换链与帧缓冲毫无关系。交换链是一系列你并不拥有的图像。你可以请求显示引擎借用其中一幅图像一段时间,在此期间,你可以向其进行渲染,或者执行交换链允许你对其图像执行的任何其他操作。
过一段时间后,你可以告知显示引擎将你使用过的图像显示到特定显示器上,之后,在再次借用该图像之前,你无法再使用该交换链图像。
2)因此,尽管它们都有 “一系列图像”,但二者毫无相似之处。在渲染操作期间,帧缓冲会根据渲染通道的子通道附件使用规则,向其所有图像进行渲染。你无需同时借用交换链中的所有图像,只需一次借用一幅图像(每个显示表面一幅)。
3)由于交换链图像只能以显示引擎允许的方式使用,而显示引擎唯一允许的使用方式只有将其作为颜色附件,所以如果你确实想在显示设备上看到结果(Vulkan 并不要求必须这样做),那么交换链中的图像最终会在某个时候进入 VkFramebuffer。
参考
这里的显示引擎,不是渲染引擎,是Display System 专门负责把颜色缓冲区的内容发送上屏的模块,驱动再往下一层的概念。比如双缓存模式下,前缓冲图像被发送到显示器上,后缓存区作为渲染目标,被opengl/vulkan 读写操作。
第3点提及的想要在渲染过程中,使用交换链的图像,唯一的方式把颜色缓冲区附件作为pipeline的uniform对象作为输出,
Framebuffer的CreateInfo结构体如下:
VkFramebufferCreateInfo fbCreateInfo{
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.pNext = nullptr,
.renderPass = renderPass,
.attachmentCount = 1, // 2 if using depth
.pAttachments = attachments,
.width = static_cast<uint32_t>(swapchain.displaySize_.width),
.height = static_cast<uint32_t><