首页 > 解决方案 > Vulkan 描述符绑定

问题描述

在我的 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

解决方案


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

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

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

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

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


推荐阅读