vulkan,docs: Add documentation Vulkan command pools

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18324>
This commit is contained in:
Jason Ekstrand
2022-08-31 13:41:27 -05:00
committed by Marge Bot
parent f17f44b91a
commit faaf4f6c45
3 changed files with 105 additions and 1 deletions

View File

@@ -0,0 +1,78 @@
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

View File

@@ -11,5 +11,6 @@ hardware-agnostic bits in common code.
base-objs
dispatch
command-pools
graphics-state
renderpass

View File

@@ -31,6 +31,7 @@
extern "C" {
#endif
/** Base object for implementin VkCommandPool */
struct vk_command_pool {
struct vk_object_base base;
@@ -57,17 +58,41 @@ struct vk_command_pool {
};
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_command_pool, base, VkCommandPool,
VK_OBJECT_TYPE_COMMAND_POOL)
VK_OBJECT_TYPE_COMMAND_POOL);
/** Initialize a vk_command_pool
*
* @param[in] device The Vulkan device
* @param[out] pool The command pool to initialize
* @param[in] pCreateInfo VkCommandPoolCreateInfo pointer passed to
* `vkCreateCommandPool()`
* @param[in] pAllocator Allocation callbacks passed to
* `vkCreateCommandPool()`
*/
VkResult MUST_CHECK
vk_command_pool_init(struct vk_device *device,
struct vk_command_pool *pool,
const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator);
/** Tear down a vk_command_pool
*
* @param[inout] pool The command pool to tear down
*/
void
vk_command_pool_finish(struct vk_command_pool *pool);
/** Trim a vk_command_pool
*
* This discards any resources that may be cached by the common
* vk_command_pool code. For driver-implemented command pools, drivers should
* call this function inside their `vkTrimCommandPool()` implementation. This
* should be called before doing any driver-specific trimming in case it ends
* up returning driver-internal resources to the pool.
*
* @param[inout] pool The command pool to trim
* @param[in] flags Flags controling the trim operation
*/
void
vk_command_pool_trim(struct vk_command_pool *pool,
VkCommandPoolTrimFlags flags);