以延迟渲染器为例。
它可能有这个图像附件列表
0: depth
1: swapchain
2: position
3: normal
4: albedo
5: resolve
以及使用其使用的绑定和附件列表定义的以下子通道:
0: [0, 2, 3, 4]
1: [0, 5]
2: [0, 1]
使用此设置,图像
2, 3, 4
需要位于第一个布局的 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
中,然后转换到 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
以在第二个子通道中使用。
我知道这可以通过使用
VkSubpassDependency
和隐式布局转换来完成。我还了解 VkAttachmentReference::layout
中的 VkSubpassDescription::pColorAttachments
是该子通道所需的布局。
我如何创建
VkSubpassDescription
来反映这一点?
我目前在伪代码中的尝试
descriptions := vector<VkSubpassDescription>
for each subpass in subpasses {
references:= std::vector<VkAttachmentReference>
depth_attachment := optional<int>
for each attachment in image_attachments {
if attachment is depth:
depth_attachment = attachment.binding
continue
}
reference := VkAttachmentReference
reference.attachment = attachment.binding
reference.layout = contains(subpass.attachments, attachment) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
references.push_back(reference)
}
descriptions.push_back(create_description(VK_PIPELINE_BIND_POINT_GRAPHICS, references, depth_attachment)
}
其中
create_description
创建 VkSubpassDescription
并可选择填写 VkSubpassDescription::pDepthStencilAttachment
此设置的问题是,第一个子通道中未使用的附件与
VkAttachmentDescription::loadOp
的 VK_ATTACHMENT_LOAD_OP_CLEAR
冲突,因为它们位于 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
中且无法写入。
我的核心概念是否正确?我使用这种具有多个子通道的渲染通道方法是否朝着正确的方向前进?
我已经阅读过有关
VkSubpassDescription::pInputAttachments
的内容,他们可能会帮助解决一些问题。但当我想添加另一个处理例如的子通道时,不会有用。后处理效果,因为输入附件只能在当前片段查询x, y, layer
我已经阅读过有关
的内容,他们可能会帮助解决一些问题。但当我想添加另一个处理例如的子通道时,不会有用。后处理效果,因为输入附件只能在当前片段查询VkSubpassDescription::pInputAttachments
x, y, layer
这是你的问题。
在渲染通道实例的持续时间内,用作附件的图像子资源只能作为附件进行访问。如果要将它们作为着色器输出写入,则必须在子通道中将它们用作颜色或深度/模板附件。如果您想在着色器中读取它们,您必须将它们用作输入附件。 您不能任意读取作为当前渲染通道实例附件的图像子资源。
如果您想读取任意写入的图像(即:不仅仅是从当前片段的位置),您必须
打破渲染通道。也就是说,您需要结束渲染通道并开始一个新的渲染通道,其中该图像不再是附件。并且您需要在两个渲染通道之间使用所有适当的依赖关系。 对于延迟渲染,输入附件非常有用,您应该使用它们。您的设置需要更改。子通道 1 需要使用附件 2-4 作为输入附件(另外,从深度缓冲区重建位置,而不是将其存储在大纹理中)。
但是,如果您正在进行需要从颜色缓冲区中任意读取的后处理,则需要一个新的渲染通道。