a/vk: Add command pool helpers

This commit is contained in:
Jakob Bornecrantz 2023-04-01 19:44:57 +01:00
parent 4d3c1cf7c5
commit 68b8a2f371
3 changed files with 373 additions and 0 deletions

View file

@ -6,6 +6,8 @@ add_library(
vk_bundle_init.c
vk_cmd.c
vk_cmd.h
vk_cmd_pool.c
vk_cmd_pool.h
vk_compositor_flags.c
vk_documentation.h
vk_function_loaders.c

View file

@ -0,0 +1,143 @@
// Copyright 2019-2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Command pool helpers.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
* @ingroup aux_vk
*/
#include "vk/vk_cmd.h"
#include "vk/vk_cmd_pool.h"
/*
*
* 'Exported' functions.
*
*/
XRT_CHECK_RESULT VkResult
vk_cmd_pool_init(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandPoolCreateFlags flags)
{
VkResult ret;
XRT_MAYBE_UNUSED int iret = os_mutex_init(&pool->mutex);
assert(iret == 0);
VkCommandPoolCreateInfo cmd_pool_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = flags,
.queueFamilyIndex = vk->queue_family_index,
};
ret = vk->vkCreateCommandPool(vk->device, &cmd_pool_info, NULL, &pool->pool);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkCreateCommandPool: %s", vk_result_string(ret));
os_mutex_destroy(&pool->mutex);
}
return ret;
}
void
vk_cmd_pool_destroy(struct vk_bundle *vk, struct vk_cmd_pool *pool)
{
// Early out if never created.
if (pool->pool == VK_NULL_HANDLE) {
return;
}
vk->vkDestroyCommandPool(vk->device, pool->pool, NULL);
pool->pool = VK_NULL_HANDLE;
os_mutex_destroy(&pool->mutex);
}
XRT_CHECK_RESULT VkResult
vk_cmd_pool_create_cmd_buffer_locked(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer *out_cmd_buffer)
{
VkCommandBuffer cmd_buffer;
VkResult ret;
// Allocate the command buffer.
VkCommandBufferAllocateInfo cmd_buffer_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = pool->pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
};
ret = vk->vkAllocateCommandBuffers(vk->device, &cmd_buffer_info, &cmd_buffer);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkAllocateCommandBuffers: %s", vk_result_string(ret));
// Nothing to cleanup
return ret;
}
*out_cmd_buffer = cmd_buffer;
return VK_SUCCESS;
}
XRT_CHECK_RESULT VkResult
vk_cmd_pool_create_and_begin_cmd_buffer_locked(struct vk_bundle *vk,
struct vk_cmd_pool *pool,
VkCommandBufferUsageFlags flags,
VkCommandBuffer *out_cmd_buffer)
{
VkCommandBuffer cmd_buffer;
VkResult ret;
ret = vk_cmd_pool_create_cmd_buffer_locked(vk, pool, &cmd_buffer);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vk_cmd_pool_create_cmd_buffer_locked: %s", vk_result_string(ret));
// Nothing to cleanup
return ret;
}
// Start the command buffer as well.
VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = flags,
};
ret = vk->vkBeginCommandBuffer(cmd_buffer, &begin_info);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vkBeginCommandBuffer: %s", vk_result_string(ret));
goto err_buffer;
}
*out_cmd_buffer = cmd_buffer;
return VK_SUCCESS;
err_buffer:
vk->vkFreeCommandBuffers(vk->device, pool->pool, 1, &cmd_buffer);
return ret;
}
XRT_CHECK_RESULT VkResult
vk_cmd_pool_submit_cmd_buffer_locked(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer cmd_buffer)
{
VkResult ret;
// Do the submit.
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.commandBufferCount = 1,
.pCommandBuffers = &cmd_buffer,
};
ret = vk_cmd_submit_locked(vk, 1, &submitInfo, VK_NULL_HANDLE);
if (ret != VK_SUCCESS) {
VK_ERROR(vk, "vk_cmd_submit_locked: %s", vk_result_string(ret));
}
return ret;
}

View file

@ -0,0 +1,228 @@
// Copyright 2019-2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Command pool helpers.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
* @ingroup aux_vk
*/
#pragma once
#include "vk/vk_helpers.h"
#include "vk/vk_cmd.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
*
* Struct(s)
*
*/
/*!
* Small helper to manage lock around a command pool.
*
* @ingroup aux_vk
*/
struct vk_cmd_pool
{
VkCommandPool pool;
struct os_mutex mutex;
};
/*
*
* Functions.
*
*/
/*!
* Create a command buffer pool.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT VkResult
vk_cmd_pool_init(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandPoolCreateFlags flags);
/*!
* Destroy a command buffer pool, lock must not be held, externally
* synchronizable with all other pool commands.
*
* @public @memberof vk_cmd_pool
*/
void
vk_cmd_pool_destroy(struct vk_bundle *vk, struct vk_cmd_pool *pool);
/*!
* Create a command buffer, call with the pool mutex held.
*
* @pre Command pool lock must be held, see @ref vk_cmd_pool_lock.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT VkResult
vk_cmd_pool_create_cmd_buffer_locked(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer *out_cmd_buffer);
/*!
* Create a command buffer and also begin it, call with the pool mutex held.
*
* @pre Command pool lock must be held.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT VkResult
vk_cmd_pool_create_and_begin_cmd_buffer_locked(struct vk_bundle *vk,
struct vk_cmd_pool *pool,
VkCommandBufferUsageFlags flags,
VkCommandBuffer *out_cmd_buffer);
/*!
* Submit to the vulkan queue, will take the queue mutex.
*
* @pre Command pool lock must be held, see @ref vk_cmd_pool_lock.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT VkResult
vk_cmd_pool_submit_cmd_buffer_locked(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer cmd_buffer);
/*!
* A do everything submit function, will take the queue mutex. Will create a
* fence and wait on the commands to complete. Will also end and destroy the
* passed in command buffer.
*
* @pre Command pool lock must be held, see @ref vk_cmd_pool_lock.
*
* Calls:
* * vkEndCommandBuffer
* * vkCreateFence
* * vkWaitForFences
* * vkDestroyFence
* * vkFreeCommandBuffers
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked(struct vk_bundle *vk,
struct vk_cmd_pool *pool,
VkCommandBuffer cmd_buffer)
{
return vk_cmd_end_submit_wait_and_free_cmd_buffer_locked(vk, pool->pool, cmd_buffer);
}
/*!
* Lock the command pool, needed for creating command buffers, filling out
* commands on any command buffers created from this pool and submitting any
* command buffers created from this pool to a VkQueue.
*
* @public @memberof vk_cmd_pool
*/
static inline void
vk_cmd_pool_lock(struct vk_cmd_pool *pool)
{
os_mutex_lock(&pool->mutex);
}
/*!
* Unlock the command pool.
*
* @public @memberof vk_cmd_pool
*/
static inline void
vk_cmd_pool_unlock(struct vk_cmd_pool *pool)
{
os_mutex_unlock(&pool->mutex);
}
/*!
* Locks, calls @ref vk_cmd_pool_create_cmd_buffer_locked, and then unlocks the
* command pool.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_create_cmd_buffer(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer *out_cmd_buffer)
{
vk_cmd_pool_lock(pool);
VkResult ret = vk_cmd_pool_create_cmd_buffer_locked(vk, pool, out_cmd_buffer);
vk_cmd_pool_unlock(pool);
return ret;
}
/*!
* Locks, calls @ref vk_cmd_pool_create_and_begin_cmd_buffer_locked, and then
* unlocks the command pool.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_create_and_begin_cmd_buffer(struct vk_bundle *vk,
struct vk_cmd_pool *pool,
VkCommandBufferUsageFlags flags,
VkCommandBuffer *out_cmd_buffer)
{
vk_cmd_pool_lock(pool);
VkResult ret = vk_cmd_pool_create_and_begin_cmd_buffer_locked(vk, pool, flags, out_cmd_buffer);
vk_cmd_pool_unlock(pool);
return ret;
}
/*!
* Locks, calls @ref vk_cmd_pool_submit_locked, and then unlocks the command
* pool. Will during the call take the queue lock and release it.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_submit(
struct vk_bundle *vk, struct vk_cmd_pool *pool, uint32_t count, const VkSubmitInfo *infos, VkFence fence)
{
vk_cmd_pool_lock(pool);
VkResult ret = vk_cmd_submit_locked(vk, count, infos, fence);
vk_cmd_pool_unlock(pool);
return ret;
}
/*!
* Locks, calls @ref vk_cmd_pool_submit_cmd_buffer_locked, and then unlocks the
* command pool. Will during the call take the queue lock and release it.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_submit_cmd_buffer(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandBuffer cmd_buffer)
{
vk_cmd_pool_lock(pool);
VkResult ret = vk_cmd_pool_submit_cmd_buffer_locked(vk, pool, cmd_buffer);
vk_cmd_pool_unlock(pool);
return ret;
}
/*!
* Locks, calls @ref vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked, and
* then unlocks the command pool. Will during the call take the queue lock and
* release it.
*
* @public @memberof vk_cmd_pool
*/
XRT_CHECK_RESULT static inline VkResult
vk_cmd_pool_end_submit_wait_and_free_cmd_buffer(struct vk_bundle *vk,
struct vk_cmd_pool *pool,
VkCommandBuffer cmd_buffer)
{
vk_cmd_pool_lock(pool);
VkResult ret = vk_cmd_pool_end_submit_wait_and_free_cmd_buffer_locked(vk, pool, cmd_buffer);
vk_cmd_pool_unlock(pool);
return ret;
}
#ifdef __cplusplus
}
#endif