Vulkan中不同subpass能否渲染到同一纹理的不同mipmap层级渲染目标?
问题结论
- 不同subpass完全可以将同一纹理的不同mip层级作为渲染目标,不需要强制使用
VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT - 你遇到的验证错误基本都是附件描述、subpass依赖配置不当导致的,和是否用imageless帧缓存没有直接关系
正确实现要点
帧缓存附件配置
你当前每个帧缓存附件绑定到纹理不同mip层级的做法是正确的,不需要调整,仅需确认每个绑定的image view的subresourceRange.levelCount设为1,baseMipLevel对应到正确的mip层级即可。渲染流程附件描述配置
你需要为4个mip层级分别定义4个独立的VkAttachmentDescription:
- 对应mip 0的附件:初始布局设为
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL(因为初始仅mip 0有有效数据),最终布局按需设置 - 对应mip 1~mip 3的附件:初始布局设为
VK_IMAGE_LAYOUT_UNDEFINED,最终布局按需设置 - 所有附件的
samples都设为VK_SAMPLE_COUNT_1_BIT,loadOp/storeOp按你的业务需求配置即可
- Subpass配置
每个subpass的输入附件、颜色附件对应绑定正确的附件索引即可:
- Subpass 0:输入附件绑定mip 0对应的附件索引,颜色附件绑定mip 1对应的附件索引
- Subpass 1:输入附件绑定mip 1对应的附件索引,颜色附件绑定mip 2对应的附件索引
- 后续subpass以此类推
- Subpass依赖配置(最容易出错的点)
必须为相邻subpass配置正确的依赖,保证前一个subpass写入mip层级的操作完成后,后一个subpass才能读取该层级,示例配置如下:
VkSubpassDependency dep = { .srcSubpass = 前序subpass的索引, .dstSubpass = 后续subpass的索引, .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT // 下采样是1:1区域对应时可开启优化性能 };
该依赖会自动处理两个subpass之间对应mip层级的布局转换,不需要你手动做图像布局转换。
关于VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT的说明
这个flag的作用是创建帧缓存的时候不绑定具体的image view,等到vkCmdBeginRenderPass的时候再通过VkRenderPassAttachmentBeginInfo动态指定附件的image view,一般用于附件需要动态切换的场景,你当前的场景不需要用到这个特性,无需刻意添加。
内容的提问来源于stack exchange,提问作者wangsy
相关产品推荐
相关产品推荐

