绑定每个对象统一缓冲区(例如相机矩阵)的有效方法是什么?

时间:2019-05-21 08:11:24

标签: vulkan

我有一些简单的vulkan应用,具有:

  • 每个交换链映像(#1,#2,#3)的3个命令缓冲区

  • 1个具有投影矩阵数据的均匀缓冲区

我想绑定一次统一缓冲区。我正在使用命令缓冲区1来绑定统一缓冲区:

   begin();
   bindDescriptorSets();
   end();
   submit();
   waitIdle();
   reset();

然后我为每个交换链图像记录命令(3次):

   begin()
   bindVertexBuffers()
   beginRenderPass()
   bindPipeline()
   draw()
   endRenderPass()
   end();

工程图正常,但是验证层记录了一个错误:

[ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object: 0x1a57aad7910 (Type = 6) | VkPipeline 0x21 uses set #0 but that set is not bound.

如果我将bindDescriptorSets();行移至第二个记录块,如下所示:

   begin()
   bindDescriptorSets();
   bindVertexBuffers()
   beginRenderPass()
   bindPipeline()
   draw()
   endRenderPass()
   end();

可以进行验证,但是渲染没有区别。

所以,问题是:是否必须为每个缓冲区记录绑定描述符集?如果是,我绑定描述符集一次后,为什么该应用程序能正常工作?

1 个答案:

答案 0 :(得分:0)

我认为这与Vulkan应用程序的当前状态有关。让我们看看有关状态的规范:

  

2.2.1。队列操作

     

记录在命令缓冲区中的命令可以执行操作(...),设置状态(绑定管道,描述符集,   和缓冲区,设置动态状态,推送常量,设置渲染   通过/子通过状态),或执行同步(...)。一些命令   执行以上任务之一。状态设置命令更新   命令缓冲区的当前状态。

注意,我用粗体标记了绑定描述符集是一个 state命令

您将描述符集绑定到该缓冲区的命令缓冲区末端并提交。接下来,启动其他命令缓冲区。让我们再次看看什么规格告诉我们有关命令缓冲区的信息:

  
      
  1. 命令缓冲区
  2.   
     

每个命令缓冲区独立于其他命令缓冲区管理状态。在主要对象之间没有状态继承   和辅助命令缓冲区,或在辅助命令缓冲区之间。   当命令缓冲区开始记录时,该命令中的所有状态   缓冲区未定义。

因此,规范和层告诉您,必须将描述符绑定到使用该状态的每个命令缓冲区。为什么即使有警告也能起作用?我不知道,可能您的实现允许它,但是我不建议保持原样。