mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +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_bundle_init.c
|
||||||
vk_cmd.c
|
vk_cmd.c
|
||||||
vk_cmd.h
|
vk_cmd.h
|
||||||
|
vk_cmd_pool.c
|
||||||
|
vk_cmd_pool.h
|
||||||
vk_compositor_flags.c
|
vk_compositor_flags.c
|
||||||
vk_documentation.h
|
vk_documentation.h
|
||||||
vk_function_loaders.c
|
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