创建命令池
译者注:示例代码点击此处
命令池是命令缓冲区获取内存的对象。内存本身是隐式并动态分配的,但如果没有它,命令缓冲区将没有任何存储空间来保存记录的命令。这就是为什么在我们分配命令缓冲区之前首先需要为它们创建一个内存池。
怎么做...
1.创建一个名为logical_device的VkDevice类型变量,并使用创建的逻辑设备句柄对其进行初始化。
2.获取为逻辑设备逻辑设备请求的其中一个队列族的索引。将次索引储存在名为queue_family的uint32_t类型变量中。
3.创建名为command_pool_create_info的VkCommandPoolCreateInfo类型的变量。为此变量的成员分配一下纸:
·sType为VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
·pNext为nullpt
·flags为VkCommandPoolCreateFlags的位字段所选参数
·queueFamilyIndex为queue_family
4.创建一个名为command_pool的VkCommandPool类型变量,其中将存储命令池的句柄。
5.调用vkCreateCommandPool( logical_device, &command_pool_create_info, nullptr, &command_pool )。第一个参数为逻辑设备句柄,第二个参数command_pool_create_info变量的指针。第三个参数为nullptr,最后一个参数指向command_pool对象。
6.确保调用返回VK_SUCCESS值。
这个怎么运作...
命令池主要用作命令缓冲区的内存源,但这不是创建他们的唯一原因。它们告知驱动程序从它们分配的命令缓冲区的预期用途,以及是否必须批量重置或释放它们,或者是否可以按照每个命令缓冲区单独执行它们。这些参数是通过VkCommandPoolCreateInfo类型变量的flags成员(参数变量表示如下)指定的,如下所示:
VkCommandPoolCreateInfo command_pool_create_info = {
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
nullptr,
parameters,
queue_family
};
当我们指定VK_COMMAND_POOL_CREATE_TRANSIENT_BIT位时,这意味着从给定池分配的命令缓冲区将在非常短的时间内存活,它们将被提交很少次,并将立即重置或释放。当我们使用VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT时,可以单独重置命令缓冲区。如果没有此标志,我们只能在组中执行此操作-在从给定分配的所有命令缓冲区上。记录命令缓冲区会隐式重置它,因此如果没有此标志,我们只能记录一次命令缓冲区,如果想再次记录它,需要重置分配它的整个池。
命令池还控制可以提交命令缓冲区的队列。这是通过队列族索引实现的,我们必须在池创建期间提供该索引(只能提供在创建逻辑设备期间请求的族)。从给定池分配的命令缓冲区只能提交到给定族的队列。
要创建池,我们需要准备以下代码:
VkResult result = vkCreateCommandPool( logical_device, &command_pool_create_info, nullptr, &command_pool );
if( VK_SUCCESS != result ) {
std::cout << "Could not create command pool." << std::endl;
return false;
}
return true;
提示:无法从多个线程(命令)同时访问命令池(同一池中的每个缓冲区不能同时记录在多个线程上)。这就是为什么要记录命令缓冲区的每个应用程序线程应该使用单独的命令池。
现在,我们已准备好分配命令缓冲区。