【问题标题】:How to get render result for next subpass in Vulkan?如何在 Vulkan 中获取下一个子通道的渲染结果?
【发布时间】:2018-01-20 08:00:48
【问题描述】:

现在,我想做后处理并使用 subpass 方式来做。我创建了两个子通道,并在第二个子通道的屏幕上绘制了一个大三角形。

但问题是我不知道如何获取第一个子通道的渲染结果,因为我需要将它提供给第二个子通道的片段着色器,然后我可以在第二个子通道的片段着色器中做一些效果次通道。

我猜结果是swapchain_imageView。但我不能使用它。 Vulkan 告诉我 Cannot use image 0x8 with specific layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL that doesn't match the actual current layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL。 估计方法不对。

如何为下一个子通道获得正确的渲染结果?

【问题讨论】:

  • VkAttachmentReference inputAttachmentRef = {}; inputAttachmentRef.attachment = 0; inputAttachmentRef.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkSubpassDescription subpass2 = {}; subpass2.inputAttachmentCount = 1; subpass2.pInputAttachments = &inputAttachmentRef; 因为我在 subpass 2 中设置了 inputAttachment,我猜系统应该自动将 subpass 1 的渲染结果发送到我的 subpass 2 的片段着色器。但我只是猜测。我真的不知道。

标签: graphics 3d vulkan


【解决方案1】:

您想要一个带有子通道附件引用和依赖项的渲染通道,如下所示:

pSubpasses = [
  {
    pInputAttachments = [],
    pColorAttachments = [{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}]
  },
  {
    pInputAttachments = [{0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}]
    pColorAttachments = [{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}]
  }
]

pDependencies = [
  {
    0, 1,
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
    VK_DEPENDENCY_BY_REGION_BIT,
  }
]

在第二个子通道中,您还需要使用 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT 描述符将附件 0 中的图像绑定到片段着色器。

在着色器中,输入附件的使用如下:

layout (input_attachment_index=i, set=m, binding=n) uniform subpassInput inputAttachment;
vec4 fragment = subpassLoad(inputAttachment);

【讨论】:

    【解决方案2】:

    您不能任意读取当前作为渲染通道附件的任何图像。请注意,我说的是“渲染通道”,而不是“子通道”。启动渲染过程图像后,这些图像对于任何不是显式附件操作的操作都是禁止的。

    如果你的后处理效果是只需要对图像的每个纹素进行读/修改/写操作,如果它不需要读取相邻像素来完成它的工作,那么你可以使用图像作为输入附件。这将用于色调映射等效果。

    但如果您确实需要从渲染图像中访问多个纹素,则此后处理效果必须存在于与创建它的渲染通道实例不同的渲染通道实例中。

    还有:

    因为我在 subpass 2 中设置了 inputAttachment,我猜系统应该自动将 subpass 1 的渲染结果发送到我的 subpass 2 的片段着色器。

    你“猜”?这是伏尔甘;这里没有“猜测”。除非您告诉系统这些操作之间存在依赖关系,否则不会存在。因此试图从中读取的是 UB。

    如果子通道 2 将读取由子通道 1 写入的输入附件,那么您必须将子通道依赖项从子通道 1 放置到子通道 2。最好使用“按区域”依赖项(除非您正在阅读以前子通道中编写的其他内容)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多