You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vulkan多网格独用纹理绘制报错:描述符集已销毁或更新

解决Vulkan中「descriptorset is destroyed or updated」报错问题

兄弟,你这明显踩了Vulkan里Descriptor Set同步的经典坑了!咱们先把问题掰碎了说:

为什么原来的流程没问题?

之前你先调用UpdateDescriptorSets(texture)把全局纹理绑定到同一个Descriptor Set,再遍历网格录制Draw命令——这时候整个命令缓冲录制过程中,这个Set的内容是完全稳定的,所有Draw命令引用的都是同一个“固定版本”的Set,Vulkan完全认可这种操作,自然不会报错。

你的修改错在哪?

现在你把UpdateDescriptorSets(textures[meshindex])塞进了命令缓冲录制的循环里,这就犯了Vulkan的大忌:

  • 第一次循环:绑定UBO → 更新Set → 录制Draw命令(此时命令缓冲已经记下了对这个Set的引用)
  • 第二次循环:你又去更新同一个Set——这直接让之前命令缓冲里的引用失效了!Vulkan规定:一旦一个Descriptor Set被记录到命令缓冲中,在这个命令缓冲执行完成之前,绝对不能修改它的内容,否则就会触发你看到的「descriptorset is destroyed or updated」错误。

说白了就是:你给GPU递了一份“操作清单”(命令缓冲),清单里说要用某份文件(Descriptor Set),结果GPU还没执行到那一步,你就把文件内容改了,系统当然要报错。

正确的解决办法

方案1:为每个网格分配独立的Descriptor Set(首推)

这是最贴合Vulkan设计思路的做法,操作也清晰:

  1. 提前基于同一个Descriptor Set Layout,为每个纹理分配一个独立的Descriptor Set
  2. 录制命令缓冲时,遍历每个网格:
    • 绑定该网格的Transform UBO
    • 用vkCmdBindDescriptorSets绑定这个网格专属的Descriptor Set
    • 执行Draw命令

每个网格用自己的Set,互相完全不干扰,再也不会出现修改已被引用的Set的问题。

方案2:用Descriptor Set模板(适合纹理极多的场景)

如果你的场景里纹理数量特别大,不想提前分配大量Set,可以试试VK_EXT_descriptor_template扩展。它允许你在录制命令缓冲时快速更新Set的内容,但必须做好同步(比如用Fence确保上一帧的命令完全执行完后,再更新Set)。不过这个方案复杂度高,新手还是优先选方案1。

额外提醒

  • 分配Descriptor Set前,要确保你的Descriptor Pool有足够的容量,不然会分配失败
  • 所有网格的Descriptor Set必须基于兼容的Descriptor Set Layout,不然没法绑定到同一个Pipeline

内容的提问来源于stack exchange,提问作者IAS0601

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:29:35