Vulkan Cookbook 第三章 3 开始命令缓冲区记录操作

开始命令缓冲区记录操作

译者注:示例代码点击此处

当我们想要使用硬件执行操作时,需要记录命令并将他们提交到队列中。命令记录在缓冲区中,因此当我们想要记录它们时,需要开始所选命令缓冲区的记录操作,有效地将其设置为记录状态。

怎么做...

1.获取命令缓冲区句柄,其中应记录命令,并将其储存在名为command_buffer的VkCommandBuffer类型变量中,确保从设置了VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT标志的池中分配命令缓冲区,或者它处于初始状态(已重置)。
2.创建名为usage的VkCommandBufferUsageFlags位字段类型的变量,并根据满足的条件设置以下位:
  1.如果命令缓冲区只提交一次然后重置或重新记录,请设置VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT位。
  2.如果它是辅助命令缓冲区并且被认为完全在渲染过程内,则设置VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT位。
  3.如果命令缓冲区仍在设备上执行时(在此命令缓冲区上一次提交结束之前)需要重新提交到队列,请设置VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT位。
3.创建一个名为secondary_command_buffer_info的VkCommandBufferInheritanceInfo *类型变量,如果它是主命令缓冲区,则使用nullptr值初始化变量。如果它是辅助命令缓冲区,则使用VkCommandBufferInheritanceInfo类型变量的地址初始化它,该变量的成员使用以下值初始化:
  ·sType为VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO
  ·pNext为nullptr
  ·对于renderPass,使用兼容渲染过程的句柄,其中将执行命令缓冲区;如果命令缓冲区不会在渲染过程中执行,则忽略该值(请参阅第六章创建渲染过程内容,渲染过程和帧缓冲区)
  ·  对于subpass,为渲染过程中的子通道索引(其中将执行命令缓冲区)(如果命令缓冲区不在渲染过程中执行,则忽略该值)
  ·对于framebuffer,使用命令缓冲区将呈现的帧缓冲区的可选句柄,如果缓冲区未知或者不在渲染过程中执行命令缓冲区,则使用VK_NULL_HANDLE值
  ·对于occlusionQueryEnable成员,如果可以在执行该辅助命令缓冲区的主命令缓冲区中活动遮挡查询的同时执行命令缓冲区,则使用VK_TRUE值。否则,使用VK_FALSE值指示命令缓冲区不能与启用的遮挡查询一起执行
  ·为queryFlags设置一组标志可由活动遮挡查询使用
  ·为pipelineStatistics设置一组统计信息,可由活动查询计数
4.创建名为command_buffer_begin_info的VkCommandBufferBeginInfo类型变量。使用以下值初始化成员:
  ·sType为VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
  ·nullptr为pNext
  ·可以由queryFlags的活动遮挡查询使用的一组标志
  ·可以由pipelineStatistics的活动查询计算的一组统计信息
5.调用vkBeginCommandBuffer( command_buffer, &command_buffer_begin_info ),第一个参数中提供缓冲区句柄,并在第二个参数中提供指向command_buffer_begin_info变量的指针。
6.通过检查调用返回值是否等于VK_SUCCESS,确保调用成功。

这个怎么运作...

记录命令缓冲区是我们在Vulkan中可以执行的最重要的操作。这是告诉硬件应该做什么以及如何做的唯一方法。当我们开始记录命令缓冲区时,它们的状态是未定义的。通常,命令缓冲区不会继承任何状态(与Openl相反,其中维持当前状态)。因此当我们记录操作时还需要记住设置与这些操作相关的状态。这种状态的一个例子是绘图命令,它使用顶点属性和索引。在我们记录绘图操作之前,需要将适当的缓冲区与顶点数据和具有顶点索引的缓冲区绑定。
主命令缓冲区可以调用(执行)辅助命令缓冲区中的记录命令。执行的辅助命令缓冲区不会从执行它们的主命令缓冲区继承状态。最重要的是,在记录执行辅助命令缓冲区之后,主命令缓冲区的状态也是未定义的(当我们记录主命令缓冲区并在其中执行辅助命令缓冲区时,我们需要再次设置窗台)。状态继承规则只有一个例外-当主命令缓冲区位于渲染过程中并且我们从中执行辅助命令缓冲区时,将保留主命令缓冲区的渲染过程和子过程状态。
在我们开始绘制之前,我们需要准备一个VkCommandBufferBeginInfo类型的变量,通过它我们提供记录参数:

VkCommandBufferBeginInfo command_buffer_begin_info = { V  
  K_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 
  nullptr,
  usage,
  secondary_command_buffer_info 
};

出于性能原因我们应该避免使用VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT标志记录命令缓冲区。
下面我们可以开始记录操作。

VkResult result = vkBeginCommandBuffer( command_buffer, &command_buffer_begin_info ); if( VK_SUCCESS != result ) {
  std::cout << "Could not begin command buffer recording operation." << std::endl;
  return false; 
}
return true;

从现在开始,我们可以将选定的操作记录到命令缓冲区中。但是如何知道哪些命令可以记录到命令缓冲区?所有这些函数的名称都以vkCmd前缀开头,它们的第一个参数始终是命令缓冲区(VkCommandBuffer类型的变量)。但是,我们需要记住,并非所有命令都可以记录到主命令缓冲区和辅助命令缓冲区中。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值