可以说我有多个要使用不同 Material 渲染的网格。我知道我可以在此示例中使用push constants,但是这个问题更多的是为了了解vkDescriptorset应该如何工作。

struct Material {
    vec4 color;
    vkDescriptorset descriptorSet;
    VkDescriptorBufferInfo descriptorBufferInfo;
};

创建数据缓冲区后,我才将vkUpdateDescriptorSets称为_descriptorBufferInfo。一切正常。

我测试了另一个解决方案。我没有为每种 Material 设置一个vkDescriptorset,而是为所有这些设置了一个。在rendepass内部,我将每种 Material vkUpdateDescriptorSets称为VkDescriptorBufferInfo
vkDescriptorset globalDescriptorSet;
struct Material {
  vec4 color;
  VkDescriptorBufferInfo descriptorBufferInfo;
};

beginCommandBuffer
beginRenderPass
for (auto &mesh : meshes) {
    ...
    writeDescriptorSets.dstSet = globalDescriptorSet;
    writeDescriptorSets.pBufferInfo = &mesh.material.descriptorBufferInfo;
    ....
    vkUpdateDescriptorSets(device, 1, &writeDescriptorSets, 0, nullptr);
    renderMesh(mesh);
}
endRenderPass
endCommandBuffer

但是,当我这样做时,它是行不通的。验证层说,在我渲染的第二个网格物体调用任何命令beginCommandBuffervkCmdBindDescriptorSets等之前,必须先调用vkCmdBindPipeline

那么,这里的问题是什么,我不能在多个VkDescriptorBufferInfo之间共享一个vkDescriptorset,还是不能在renderPass中更新它?

最佳答案

根据Vulkan规范:



(强调)

大概,您的renderMesh调用将描述符集绑定(bind)到命令缓冲区。从那一刻起,您将无法以任何方式修改该描述符集,直到该命令缓冲区中的命令完成(或CB被销毁)为止。

这就是为什么存在动态统一/存储缓冲区的原因。它们使您可以更改统一/存储缓冲区的基本偏移,而无需考虑对实际描述符集的修改。因此,您可以在多个位置使用相同的描述符集,并使用不同的缓冲区偏移量。

关于c++ - 更新renderPass中的VkDescriptorSet,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38284735/

10-10 17:29