Vulkan编程指南翻译 第三章 队列和命令 第4节 回收利用命令缓冲区

2017-02-28

3.4  回收利用命令缓冲区

在许多应用程序中,在所有或者一部分渲染帧中,存在一些相似的命令序列。因此,你很可能会一遍又一遍地记录相同的命令缓冲区。使用当前介绍过的命令,你将调用vkAllocateCommandBuffers()来获取一个或者多个命令缓冲区的handle,记录命令到命令缓冲区,然后调用vkFreeCommandBuffers()来把缓冲区归还到各自的pool。这是一个重量级的操作,如果你提早就知道会重用命令缓冲区来连续多次做相似的工作,重置命令缓冲区或许会高效率的多。这会把命令缓冲区恢复到初始状态,但并不需要和pool之间做任何操作。因此,如果命令缓冲区动态的从pool分配资源,它可以一直持有这些资源,避免后续多次的冲洗分配资源的工作。可调用vkResetCommandBuffer()来重置命令缓冲区,原型:

VkResult vkResetCommandBuffer (

VkCommandBuffer  commandBuffer,

VkCommandBufferResetFlags  flags);

将被重置的命令缓冲区通过commandBuffer参数传递。flags参数指定了重置时的附加操作。现在仅定义了一个可用的标志位VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT。如果这个标志位被设置了,很有可能调用vkResetCommandBuffer()的效率会比释放后再重新分配新的内存缓冲区更高。

也有方式能够把从一个pool的命令缓冲区一次性的重置掉。可以调用vkResetCommandPool()函数达到此目的,其原型如下:

VkResult vkResetCommandPool (

VkDevice  device,

VkCommandPool  commandPool,

VkCommandPoolResetFlags  flags);

拥有这个命令缓冲区的设备是被device参数指定的,需要被重置的pool被commandPool参数指定。和vkResetCommandBuffer()类似,flgas参数指定了重置pool时的附加操作。再有,当前被定义的标志位只有VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT。当这个标志位被设置时,动态的从pool分配的资源都会被当作重置操作的部分被执行。

从pool分配出的命令缓冲区并不被vkResetCommandPool()所释放,但是,会使他们重新变为初始状态,如同是重新分配出来的一样。vkResetCommandPool()典型被用在每一帧的最后,把一个可重用的命令缓冲区归还到pool而不是单独的重置每个命令缓冲区。

依靠重置且不把资源归还给pool的方式下,在多次重复使用命令缓冲区时,需要注意保持命令缓冲区的复杂程度。随着命令缓冲区的增长,它可能会动态地从pool分配资源,pool又可能从系统级别的pool来分配资源。命令缓冲区消耗的资源量就没有限制了,因为放入一个命令缓冲区的命令数量并没有硬性的上限。如果应用程序使用混合的使用非常小和非常大的命令缓冲区,有可能到最后所有的命令缓冲区都会变得和最复杂的命令缓冲区一样大。为了避免这个状况,要么在重置命令缓冲区或其所属的pool使周期性的设置VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT或VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT标志位,要么尝试保证同样的命令缓冲区总是被一样的方式使用—小而精简的或大而复杂的命令缓冲区。避免混用。

如果有任何意见,欢迎留言讨论。


[ 主页 ]
COMMENTS
POST A COMMENT

(optional)



(optional)