如何在 vulkan 中处理动态数量的绘制调用
How to handle a dynamic number of draw calls in vulkan
我目前正在尝试进入 Vulkan,并且我主要遵循这个众所周知的 Vulkan tutorial,一直在尝试将其集成到我围绕 OpenGL 构建的框架中。我现在可以在屏幕上成功渲染对象,并通过将转换矩阵传递到统一缓冲区来让对象四处移动 linked 到我的着色器代码。
在本教程中,作者专注于将一个对象绘制到屏幕上,这是一个很好的起点,但我希望结束代码如下所示:
drawRect(position1, size1, color1);
drawRect(position2, size2, color2);
...
我第一次尝试实现这样的东西以提交命令缓冲区而告终,它在开始时只创建并记录一次,我想渲染的每个对象一次,并确保更新统一数据在每个命令缓冲区提交之间。然而,这没有用,在使用 renderdoc 进行一些调试后,我意识到这是因为启动渲染过程会清除屏幕。
如果我正确理解我的情况,实现我想要的唯一方法是每帧重新创建命令缓冲区:
- 记录
n
,我们想在屏幕上画东西的次数;
- 在一帧结束时,分配
n
个统一缓冲区,并填充相应的数据;
- 创建
n
描述符集,以便能够 link 这些统一缓冲区与我的着色器;
- 通过重复
n
次使用 vkCmdBindDescriptorSets
绑定描述符集并使用 vkCmdDrawIndexed
绘制请求数据的过程来记录命令缓冲区。
每一帧似乎都需要做很多工作。这是我应该如何处理动态数量的绘制调用吗?还是有什么我不知道的概念about/got错了?
- 通常命令缓冲区实际上每帧 re-recorded,Vulkan 允许使用命令池进行多线程记录。
- 存在间接绘制:将有关绘制命令的数据(索引计数、实例计数等)存储到单独的缓冲区中,然后驱动程序在您提交命令时从缓冲区中读取数据;
vkCmdDraw*Indirect
要求您在录制时指定绘制命令的数量; vkCmdDraw*IndirectCount
还允许您在缓冲区中存储绘制命令的数量。
我也看不出为什么你必须 re-create 统一缓冲区,描述符设置每个帧;事实上,据我所知,Vulkan 鼓励您 pre-bake 做您力所能及的事情,而描述符集就是一个工具。
我目前正在尝试进入 Vulkan,并且我主要遵循这个众所周知的 Vulkan tutorial,一直在尝试将其集成到我围绕 OpenGL 构建的框架中。我现在可以在屏幕上成功渲染对象,并通过将转换矩阵传递到统一缓冲区来让对象四处移动 linked 到我的着色器代码。
在本教程中,作者专注于将一个对象绘制到屏幕上,这是一个很好的起点,但我希望结束代码如下所示:
drawRect(position1, size1, color1);
drawRect(position2, size2, color2);
...
我第一次尝试实现这样的东西以提交命令缓冲区而告终,它在开始时只创建并记录一次,我想渲染的每个对象一次,并确保更新统一数据在每个命令缓冲区提交之间。然而,这没有用,在使用 renderdoc 进行一些调试后,我意识到这是因为启动渲染过程会清除屏幕。
如果我正确理解我的情况,实现我想要的唯一方法是每帧重新创建命令缓冲区:
- 记录
n
,我们想在屏幕上画东西的次数; - 在一帧结束时,分配
n
个统一缓冲区,并填充相应的数据; - 创建
n
描述符集,以便能够 link 这些统一缓冲区与我的着色器; - 通过重复
n
次使用vkCmdBindDescriptorSets
绑定描述符集并使用vkCmdDrawIndexed
绘制请求数据的过程来记录命令缓冲区。
每一帧似乎都需要做很多工作。这是我应该如何处理动态数量的绘制调用吗?还是有什么我不知道的概念about/got错了?
- 通常命令缓冲区实际上每帧 re-recorded,Vulkan 允许使用命令池进行多线程记录。
- 存在间接绘制:将有关绘制命令的数据(索引计数、实例计数等)存储到单独的缓冲区中,然后驱动程序在您提交命令时从缓冲区中读取数据;
vkCmdDraw*Indirect
要求您在录制时指定绘制命令的数量;vkCmdDraw*IndirectCount
还允许您在缓冲区中存储绘制命令的数量。
我也看不出为什么你必须 re-create 统一缓冲区,描述符设置每个帧;事实上,据我所知,Vulkan 鼓励您 pre-bake 做您力所能及的事情,而描述符集就是一个工具。