mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
a/vk: Add command pool helpers
This commit is contained in:
parent
4d3c1cf7c5
commit
68b8a2f371
|
@ -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
|
||||
|
|
143
src/xrt/auxiliary/vk/vk_cmd_pool.c
Normal file
143
src/xrt/auxiliary/vk/vk_cmd_pool.c
Normal 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;
|
||||
}
|
228
src/xrt/auxiliary/vk/vk_cmd_pool.h
Normal file
228
src/xrt/auxiliary/vk/vk_cmd_pool.h
Normal 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
|
Loading…
Reference in a new issue