Vulkan每帧更新描述符

时间:2018-05-21 16:35:02

标签: vulkan

我想将场景渲染到纹理,然后在着色器中使用该纹理,因此我使用imageview创建了一个frambuffer,并为此记录了一个命令缓冲区。我成功上传并执行了gpu上的命令缓冲区,但是imageview的描述符是黑色的。我在渲染循环之前从imageview创建描述符。它是黑色的,因为我在渲染到帧缓冲区之前创建了它吗?如果是这样,我将不得不每帧更新描述符。我是否必须每帧从imageview创建一个新的描述符?或者还有另一种方法可以做到这一点吗?

我已阅读此标题的其他帖子。不要将此标记为重复,因为线程是关于纹理的,这是来自imageview的纹理。

感谢。

1 个答案:

答案 0 :(得分:2)

@ IAS0601我将通过答案回答您的评论中的问题,因为它允许写入更长的文本,并且其格式更好。我希望这也能回答你原来的问题,但你不必像答案一样对待。正如我写的那样,我不确定你在问什么。

1)在几乎所有情况下,GPU都通过图像视图访问图像。它们指定了定义如何访问图像的附加参数(例如,访问图像的哪个部分),但仍然是访问的原始图像。顾名思义,图像视图只是一个视图,访问参数列表。它没有绑定任何内存,它不包含任何数据(除了在图像视图创建期间指定的参数)。

因此,当您创建帧缓冲并渲染到帧缓冲区时,您将渲染为原始图像,或者更具体地说,渲染到图像视图中指定的原始图像的那些部分。例如,您有一个包含3个数组图层的2D纹理。您为中间(第二)图层创建2D图像视图。然后在帧缓冲区创建期间使用此图像视图。现在,当您渲染到此帧缓冲区时,实际上您正在渲染到原始2D纹理数组的第二层。

另一件事 - 当您稍后访问同一图像时,以及当您使用相同的图像视图时,您仍然可以访问原始图像。如果您在图像中渲染了某些内容,那么您将获得更新的数据(前提是您已正确完成所有操作,例如执行适当的同步操作,必要时进行布局转换等)。我希望这是更新图像视图的意思。

2)我不确定更新描述符集是什么意思。在Vulkan中,当我们更新描述符集时,这意味着我们指定应该通过给定描述符集使用的Vulkan资源的句柄。

如果我理解正确 - 您想要将某些内容渲染到图像中。您可以为该图像创建图像视图,并在创建帧缓冲期间提供该图像视图。然后你在框架缓冲区中渲染一些东西。现在您想要从该图像中读取数据。你有两个选择。如果您只想访问与片段着色器位置关联的一个样本位置,则可以通过同一渲染过程的下一个子通道中的输入附件来执行此操作。但这样您只能执行不需要访问多个纹素的操作,例如颜色校正。

但是如果你想做更先进的事情,比如模糊或阴影贴图,如果你需要访问几个纹素,你必须结束渲染过程并启动另一个。在第二个渲染过程中,您可以通过描述符集从原始图像中读取数据。创建和更新此描述符集时(指定图像视图的句柄时)并不重要。如果您没有更改资源句柄 - 这意味着,如果您不创建新图像或新图像视图,则可以使用相同的描述符集,并且您将访问在第一个渲染中呈现的数据通过。

如果您在访问数据时遇到问题,例如(正如您所写)您只得到黑色,这表示您没有正确执行所有操作 - 渲染传递加载或存储操作不正确,或初始和最终布局不对。或者同步没有正确执行。遗憾的是,如果无法访问您的项目,我们无法确定错误。