79 lines
3.2 KiB
ReStructuredText
79 lines
3.2 KiB
ReStructuredText
|
Command Pools
|
||
|
=============
|
||
|
|
||
|
The Vulkan runtime code provides a common ``VkCommandPool`` implementation
|
||
|
which makes managing the lifetimes of command buffers and recycling their
|
||
|
internal state easier. To use the common command pool a driver needs to
|
||
|
fill out a :cpp:struct:`vk_command_buffer_ops` struct and set the
|
||
|
``command_buffer_ops`` field of :cpp:struct:`vk_device`.
|
||
|
|
||
|
.. doxygenstruct:: vk_command_buffer_ops
|
||
|
:members:
|
||
|
|
||
|
By reducing the entirety of command buffer lifetime management to these
|
||
|
three functions, much of the complexity of command pools can be implemented
|
||
|
in common code, providing better, more consistent behavior across Mesa.
|
||
|
|
||
|
|
||
|
Command Buffer Recycling
|
||
|
------------------------
|
||
|
|
||
|
The common command pool provides automatic command buffer recycling as long
|
||
|
as the driver uses the common ``vkAllocateCommandBuffers()`` and
|
||
|
``vkFreeCommandBuffers()`` implementations. The driver must also provide the
|
||
|
``reset`` function pointer in :cpp:struct:`vk_command_buffer_ops`.
|
||
|
|
||
|
With the common command buffer pool, when the client calls
|
||
|
``vkFreeCommandBuffers()``, the command buffers are not immediately freed.
|
||
|
Instead, they are reset with
|
||
|
``VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT``, their base object is
|
||
|
recycled, and they are added to a free list inside the pool. When the
|
||
|
client then calls ``vkAllocateCommandBuffers()``, we check the free list
|
||
|
and return a recycled command buffer, if any are available. This provides
|
||
|
some basic command buffer pooling without the driver doing any additional
|
||
|
work.
|
||
|
|
||
|
|
||
|
Custom command pools
|
||
|
--------------------
|
||
|
|
||
|
If a driver wishes to recycle at a finer granularity than whole command
|
||
|
buffers, they can do so by providing their own command pool implementation
|
||
|
which wraps :cpp:struct:`vk_command_pool`. The common use-case here is if
|
||
|
the driver wants to pool command-buffer-internal objects at a finer
|
||
|
granularity than whole command buffers. The command pool provides a place
|
||
|
where things like GPU command buffers or upload buffers can be cached
|
||
|
without having to take a lock.
|
||
|
|
||
|
When implementing a custom command pool, drivers need only implement three
|
||
|
entrypoints:
|
||
|
|
||
|
- ``vkCreateCommandPool()``
|
||
|
- ``vkDestroyCommandPool()``
|
||
|
- ``vkTrimCommandPool()``
|
||
|
|
||
|
All of the other entrypoints will be handled by common code so long as the
|
||
|
driver's command pool derives from :cpp:struct:`vk_command_pool`.
|
||
|
|
||
|
The driver implementation of the command buffer ``recycle()`` function
|
||
|
should respect ``VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT`` and, when
|
||
|
set, return any recyclable resources to the command pool. This may be set
|
||
|
by the client when it calls ``vkResetCommandBuffer()``, come from a
|
||
|
whole-pool reset via ``VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT``, or
|
||
|
come from the common command buffer code when a command buffer is recycled.
|
||
|
|
||
|
The driver's implementation of ``vkTrimCommandPool()`` should free any
|
||
|
resources that have been cached within the command pool back to the device
|
||
|
or back to the OS. It **must** also call :cpp:func:`vk_command_pool_trim`
|
||
|
to allow the common code to free any recycled command buffers.
|
||
|
|
||
|
Reference
|
||
|
---------
|
||
|
|
||
|
.. doxygenstruct:: vk_command_pool
|
||
|
:members:
|
||
|
|
||
|
.. doxygenfunction:: vk_command_pool_init
|
||
|
.. doxygenfunction:: vk_command_pool_finish
|
||
|
.. doxygenfunction:: vk_command_pool_trim
|