【问题标题】:Vulkan descriptor bindingVulkan 描述符绑定
【发布时间】:2018-12-04 01:43:17
【问题描述】:

在我的 vulkan 应用程序中,当所有网格都使用相同的纹理时,我曾经这样绘制网格

Updatedescriptorsets(texture)

Command buffer record
{
 For each mesh
        Bind transformubo
        Draw mesh
}

但现在我希望每个网格都有一个独特的纹理,所以我尝试了这个

Command buffer record
{
 For each mesh
        Bind transformubo
        Updatedescriptorsets (textures[meshindex])
        Draw mesh
}

但它给出了一个错误,说明描述符集被破坏或更新。我查看了 vulkan 文档,发现我无法在命令缓冲区记录期间更新描述符集。那么如何才能让每个网格都有独特的纹理呢?

【问题讨论】:

    标签: vulkan


    【解决方案1】:

    vkUpdateDescriptorSets 没有与任何东西同步。因此,您无法在使用描述符集时对其进行更新。您必须确保所有使用相关描述符集的渲染操作都已完成,并且未将任何命令放入使用相关描述符集的命令缓冲区中。

    它基本上就像一个全局变量;在没有某种同步的情况下,您不能让人们从众多线程中访问全局变量。而且 Vulkan 不会同步对描述符集的访问。

    有几种方法可以解决这个问题。您可以为每个对象提供自己的描述符集。这通常是通过使频繁更改的描述符集数据具有比更改频率较低的数据更高的索引来完成的。这样,您不会更改每个对象的每个描述符,而只会更改每个对象的描述符。

    您可以使用推送常量数据来索引大型表/数组纹理。所以描述符集将有一个纹理数组或纹理数组(如果你有纹理数组的动态索引)。推送常量将提供一个索引,着色器使用该索引从纹理数组/纹理数组中获取特定对象的纹理。这使得频繁更改变得相当便宜,并且相同的索引也可用于为每个对象提供其自己的转换矩阵(通过获取矩阵数组)。

    如果您有可用的扩展 VK_KHR_push_descriptor,那么您可以将描述符的更改直接集成到命令缓冲区中。这比推送常量机制要好多少,当然是依赖于实现的。

    【讨论】:

      【解决方案2】:

      如果更新描述符集,则该描述符集绑定到的所有命令缓冲区都将变为无效。无效的命令缓冲区不能被 GPU 提交或执行。

      您基本上需要做的是在绑定之前更新描述符集。

      出现这种奇怪的行为是因为在vkCmdBindDescriptorSets 中,一些实现采用了 vulkan 描述符集,将其转换为本地描述符表,然后将其存储在命令缓冲区中。因此,如果您在vkCmdBindDescriptorSets 之后更新描述符集,命令缓冲区将看到陈旧的数据。 VK_EXT_descriptor_indexing 扩展在某些情况下放宽了这种行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-13
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多