【问题标题】:How to handle a dynamic number of draw calls in vulkan如何在vulkan中处理动态数量的draw call
【发布时间】:2020-10-24 03:51:25
【问题描述】:

我目前正在尝试进入 Vulkan,我主要关注这个众所周知的Vulkan tutorial,同时尝试将它集成到我围绕​​ OpenGL 构建的框架中。我现在可以成功地在屏幕上渲染对象,并通过将转换矩阵传递给链接到我的着色器代码的统一缓冲区来移动对象。

在本教程中,作者专注于在屏幕上绘制一个对象,这是一个很好的起点,但我希望最终代码看起来像这样:

drawRect(position1, size1, color1);
drawRect(position2, size2, color2);
...

我第一次尝试实现这样的事情最终我提交了命令缓冲区,该缓冲区在开始时仅创建一次记录,为我想要渲染的每个对象创建一次,并确保更新统一数据 -在每个命令缓冲区提交之间。但是这不起作用,在使用 renderdoc 进行一些调试后,我意识到这是因为启动渲染通道会清除屏幕。

如果我正确理解我的情况,实现我想要的唯一方法是每帧重新创建命令缓冲区:

  • 记录n,我们想在屏幕上画东西的次数;
  • 在一帧结束时,分配n统一缓冲区,并用相应的数据填充;
  • 创建n 描述符集,以便能够将这些统一缓冲区与我的着色器链接;
  • 通过重复n 次使用vkCmdBindDescriptorSets 绑定描述符集并使用vkCmdDrawIndexed 绘制请求的数据的过程来记录命令缓冲区。

似乎每一帧都需要做很多工作。这是我应该如何处理动态数量的绘图调用吗?还是有一些我不知道/弄错的概念?

【问题讨论】:

    标签: c++ rendering vulkan


    【解决方案1】:
    1. 通常命令缓冲区实际上每帧都会重新记录,Vulkan 允许使用命令池进行多线程记录。
    2. 存在间接绘图:您将有关绘图命令的数据(索引计数、实例计数等)存储到单独的缓冲区中,然后驱动程序在您提交命令时从缓冲区中读取数据; vkCmdDraw*Indirect 要求您在录制时指定绘制命令的数量; vkCmdDraw*IndirectCount 还允许您在缓冲区中存储绘制命令的数量。

    我也看不出为什么你必须重新创建统一缓冲区,描述符设置每一帧;事实上,据我所知,Vulkan 鼓励你尽可能地预烘焙,而描述符集就是一个工具。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多