panvk: Use common code for command buffer lifecycle management

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16922>
This commit is contained in:
Jason Ekstrand
2022-09-09 19:14:13 -05:00
committed by Marge Bot
parent 2126bb6c92
commit 84cd81e104
5 changed files with 40 additions and 161 deletions

View File

@@ -388,9 +388,6 @@ panvk_CreateCommandPool(VkDevice _device,
return result;
}
list_inithead(&pool->active_cmd_buffers);
list_inithead(&pool->free_cmd_buffers);
panvk_bo_pool_init(&pool->desc_bo_pool);
panvk_bo_pool_init(&pool->varying_bo_pool);
panvk_bo_pool_init(&pool->tls_bo_pool);
@@ -509,14 +506,14 @@ panvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
cmdbuf->state.subpass = pass->subpasses;
cmdbuf->state.framebuffer = fb;
cmdbuf->state.render_area = pRenderPassBegin->renderArea;
cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
cmdbuf->state.batch = vk_zalloc(&cmdbuf->vk.pool->alloc,
sizeof(*cmdbuf->state.batch), 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
util_dynarray_init(&cmdbuf->state.batch->jobs, NULL);
util_dynarray_init(&cmdbuf->state.batch->event_ops, NULL);
assert(pRenderPassBegin->clearValueCount <= pass->attachment_count);
cmdbuf->state.clear =
vk_zalloc(&cmdbuf->pool->vk.alloc,
vk_zalloc(&cmdbuf->vk.pool->alloc,
sizeof(*cmdbuf->state.clear) * pass->attachment_count,
8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
@@ -551,7 +548,7 @@ struct panvk_batch *
panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf)
{
assert(!cmdbuf->state.batch);
cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
cmdbuf->state.batch = vk_zalloc(&cmdbuf->vk.pool->alloc,
sizeof(*cmdbuf->state.batch), 8,
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
assert(cmdbuf->state.batch);

View File

@@ -894,14 +894,17 @@ panvk_CreateDevice(VkPhysicalDevice physicalDevice,
return vk_error(physical_device, VK_ERROR_OUT_OF_HOST_MEMORY);
const struct vk_device_entrypoint_table *dev_entrypoints;
const struct vk_command_buffer_ops *cmd_buffer_ops;
struct vk_device_dispatch_table dispatch_table;
switch (physical_device->pdev.arch) {
case 6:
dev_entrypoints = &panvk_v6_device_entrypoints;
cmd_buffer_ops = &panvk_v6_cmd_buffer_ops;
break;
case 7:
dev_entrypoints = &panvk_v7_device_entrypoints;
cmd_buffer_ops = &panvk_v7_cmd_buffer_ops;
break;
default:
unreachable("Unsupported architecture");
@@ -947,6 +950,7 @@ panvk_CreateDevice(VkPhysicalDevice physicalDevice,
* whole struct.
*/
device->vk.command_dispatch_table = &device->cmd_dispatch;
device->vk.command_buffer_ops = cmd_buffer_ops;
device->instance = physical_device->instance;
device->physical_device = physical_device;

View File

@@ -727,8 +727,6 @@ struct panvk_cmd_state {
struct panvk_cmd_pool {
struct vk_command_pool vk;
struct list_head active_cmd_buffers;
struct list_head free_cmd_buffers;
struct panvk_bo_pool desc_bo_pool;
struct panvk_bo_pool varying_bo_pool;
struct panvk_bo_pool tls_bo_pool;
@@ -752,8 +750,6 @@ struct panvk_cmd_buffer {
struct panvk_device *device;
struct panvk_cmd_pool *pool;
struct list_head pool_link;
struct panvk_pool desc_pool;
struct panvk_pool varying_pool;
struct panvk_pool tls_pool;

View File

@@ -84,7 +84,7 @@ panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf)
if (!clear && !batch->scoreboard.first_job) {
if (util_dynarray_num_elements(&batch->event_ops, struct panvk_event_op) == 0) {
/* Content-less batch, let's drop it */
vk_free(&cmdbuf->pool->vk.alloc, batch);
vk_free(&cmdbuf->vk.pool->alloc, batch);
} else {
/* Batch has no jobs but is needed for synchronization, let's add a
* NULL job so the SUBMIT ioctl doesn't choke on it.
@@ -921,7 +921,7 @@ panvk_per_arch(CmdEndRenderPass2)(VkCommandBuffer commandBuffer,
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
panvk_per_arch(cmd_close_batch)(cmdbuf);
vk_free(&cmdbuf->pool->vk.alloc, cmdbuf->state.clear);
vk_free(&cmdbuf->vk.pool->alloc, cmdbuf->state.clear);
cmdbuf->state.batch = NULL;
cmdbuf->state.pass = NULL;
cmdbuf->state.subpass = NULL;
@@ -1066,9 +1066,13 @@ panvk_per_arch(CmdWaitEvents2)(VkCommandBuffer commandBuffer,
}
}
static VkResult
panvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
static void
panvk_reset_cmdbuf(struct vk_command_buffer *vk_cmdbuf,
VkCommandBufferResetFlags flags)
{
struct panvk_cmd_buffer *cmdbuf =
container_of(vk_cmdbuf, struct panvk_cmd_buffer, vk);
vk_command_buffer_reset(&cmdbuf->vk);
list_for_each_entry_safe(struct panvk_batch, batch, &cmdbuf->batches, node) {
@@ -1076,7 +1080,7 @@ panvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
util_dynarray_fini(&batch->jobs);
util_dynarray_fini(&batch->event_ops);
vk_free(&cmdbuf->pool->vk.alloc, batch);
vk_free(&cmdbuf->vk.pool->alloc, batch);
}
panvk_pool_reset(&cmdbuf->desc_pool);
@@ -1086,23 +1090,21 @@ panvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
for (unsigned i = 0; i < MAX_BIND_POINTS; i++)
memset(&cmdbuf->bind_points[i].desc_state.sets, 0, sizeof(cmdbuf->bind_points[0].desc_state.sets));
return vk_command_buffer_get_record_result(&cmdbuf->vk);
}
static void
panvk_destroy_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
panvk_destroy_cmdbuf(struct vk_command_buffer *vk_cmdbuf)
{
struct panvk_cmd_buffer *cmdbuf =
container_of(vk_cmdbuf, struct panvk_cmd_buffer, vk);
struct panvk_device *device = cmdbuf->device;
list_del(&cmdbuf->pool_link);
list_for_each_entry_safe(struct panvk_batch, batch, &cmdbuf->batches, node) {
list_del(&batch->node);
util_dynarray_fini(&batch->jobs);
util_dynarray_fini(&batch->event_ops);
vk_free(&cmdbuf->pool->vk.alloc, batch);
vk_free(&cmdbuf->vk.pool->alloc, batch);
}
panvk_pool_cleanup(&cmdbuf->desc_pool);
@@ -1113,11 +1115,13 @@ panvk_destroy_cmdbuf(struct panvk_cmd_buffer *cmdbuf)
}
static VkResult
panvk_create_cmdbuf(struct panvk_device *device,
struct panvk_cmd_pool *pool,
VkCommandBufferLevel level,
struct panvk_cmd_buffer **cmdbuf_out)
panvk_create_cmdbuf(struct vk_command_pool *vk_pool,
struct vk_command_buffer **cmdbuf_out)
{
struct panvk_device *device =
container_of(vk_pool->base.device, struct panvk_device, vk);
struct panvk_cmd_pool *pool =
container_of(vk_pool, struct panvk_cmd_pool, vk);
struct panvk_cmd_buffer *cmdbuf;
cmdbuf = vk_zalloc(&device->vk.alloc, sizeof(*cmdbuf),
@@ -1125,131 +1129,48 @@ panvk_create_cmdbuf(struct panvk_device *device,
if (!cmdbuf)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk,
NULL, level);
VkResult result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk, NULL, 0);
if (result != VK_SUCCESS) {
vk_free(&device->vk.alloc, cmdbuf);
return result;
}
cmdbuf->device = device;
cmdbuf->pool = pool;
if (pool) {
list_addtail(&cmdbuf->pool_link, &pool->active_cmd_buffers);
} else {
/* Init the pool_link so we can safely call list_del when we destroy
* the command buffer
*/
list_inithead(&cmdbuf->pool_link);
}
panvk_pool_init(&cmdbuf->desc_pool, &device->physical_device->pdev,
pool ? &pool->desc_bo_pool : NULL, 0, 64 * 1024,
&pool->desc_bo_pool, 0, 64 * 1024,
"Command buffer descriptor pool", true);
panvk_pool_init(&cmdbuf->tls_pool, &device->physical_device->pdev,
pool ? &pool->tls_bo_pool : NULL,
&pool->tls_bo_pool,
panvk_debug_adjust_bo_flags(device, PAN_BO_INVISIBLE),
64 * 1024, "TLS pool", false);
panvk_pool_init(&cmdbuf->varying_pool, &device->physical_device->pdev,
pool ? &pool->varying_bo_pool : NULL,
&pool->varying_bo_pool,
panvk_debug_adjust_bo_flags(device, PAN_BO_INVISIBLE),
64 * 1024, "Varyings pool", false);
list_inithead(&cmdbuf->batches);
cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL;
*cmdbuf_out = cmdbuf;
*cmdbuf_out = &cmdbuf->vk;
return VK_SUCCESS;
}
VkResult
panvk_per_arch(AllocateCommandBuffers)(VkDevice _device,
const VkCommandBufferAllocateInfo *pAllocateInfo,
VkCommandBuffer *pCommandBuffers)
{
VK_FROM_HANDLE(panvk_device, device, _device);
VK_FROM_HANDLE(panvk_cmd_pool, pool, pAllocateInfo->commandPool);
VkResult result = VK_SUCCESS;
unsigned i;
for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
struct panvk_cmd_buffer *cmdbuf = NULL;
if (!list_is_empty(&pool->free_cmd_buffers)) {
cmdbuf = list_first_entry(
&pool->free_cmd_buffers, struct panvk_cmd_buffer, pool_link);
list_del(&cmdbuf->pool_link);
list_addtail(&cmdbuf->pool_link, &pool->active_cmd_buffers);
vk_command_buffer_finish(&cmdbuf->vk);
result = vk_command_buffer_init(&pool->vk, &cmdbuf->vk, NULL,
pAllocateInfo->level);
} else {
result = panvk_create_cmdbuf(device, pool, pAllocateInfo->level, &cmdbuf);
}
if (result != VK_SUCCESS)
goto err_free_cmd_bufs;
pCommandBuffers[i] = panvk_cmd_buffer_to_handle(cmdbuf);
}
return VK_SUCCESS;
err_free_cmd_bufs:
panvk_per_arch(FreeCommandBuffers)(_device, pAllocateInfo->commandPool, i,
pCommandBuffers);
for (unsigned j = 0; j < i; j++)
pCommandBuffers[j] = VK_NULL_HANDLE;
return result;
}
void
panvk_per_arch(FreeCommandBuffers)(VkDevice device,
VkCommandPool commandPool,
uint32_t commandBufferCount,
const VkCommandBuffer *pCommandBuffers)
{
for (uint32_t i = 0; i < commandBufferCount; i++) {
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, pCommandBuffers[i]);
if (cmdbuf) {
if (cmdbuf->pool) {
list_del(&cmdbuf->pool_link);
panvk_reset_cmdbuf(cmdbuf);
list_addtail(&cmdbuf->pool_link,
&cmdbuf->pool->free_cmd_buffers);
} else
panvk_destroy_cmdbuf(cmdbuf);
}
}
}
VkResult
panvk_per_arch(ResetCommandBuffer)(VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
return panvk_reset_cmdbuf(cmdbuf);
}
const struct vk_command_buffer_ops panvk_per_arch(cmd_buffer_ops) = {
.create = panvk_create_cmdbuf,
.reset = panvk_reset_cmdbuf,
.destroy = panvk_destroy_cmdbuf,
};
VkResult
panvk_per_arch(BeginCommandBuffer)(VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo *pBeginInfo)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VkResult result = VK_SUCCESS;
if (cmdbuf->status != PANVK_CMD_BUFFER_STATUS_INITIAL) {
/* If the command buffer has already been reset with
* vkResetCommandBuffer, no need to do it again.
*/
result = panvk_reset_cmdbuf(cmdbuf);
if (result != VK_SUCCESS)
return result;
panvk_reset_cmdbuf(&cmdbuf->vk, 0);
}
memset(&cmdbuf->state, 0, sizeof(cmdbuf->state));
@@ -1267,56 +1188,15 @@ panvk_per_arch(DestroyCommandPool)(VkDevice _device,
VK_FROM_HANDLE(panvk_device, device, _device);
VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
&pool->active_cmd_buffers, pool_link)
panvk_destroy_cmdbuf(cmdbuf);
list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
&pool->free_cmd_buffers, pool_link)
panvk_destroy_cmdbuf(cmdbuf);
vk_command_pool_finish(&pool->vk);
panvk_bo_pool_cleanup(&pool->desc_bo_pool);
panvk_bo_pool_cleanup(&pool->varying_bo_pool);
panvk_bo_pool_cleanup(&pool->tls_bo_pool);
vk_command_pool_finish(&pool->vk);
vk_free2(&device->vk.alloc, pAllocator, pool);
}
VkResult
panvk_per_arch(ResetCommandPool)(VkDevice device,
VkCommandPool commandPool,
VkCommandPoolResetFlags flags)
{
VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
VkResult result;
list_for_each_entry(struct panvk_cmd_buffer, cmdbuf, &pool->active_cmd_buffers,
pool_link)
{
result = panvk_reset_cmdbuf(cmdbuf);
if (result != VK_SUCCESS)
return result;
}
return VK_SUCCESS;
}
void
panvk_per_arch(TrimCommandPool)(VkDevice device,
VkCommandPool commandPool,
VkCommandPoolTrimFlags flags)
{
VK_FROM_HANDLE(panvk_cmd_pool, pool, commandPool);
if (!pool)
return;
list_for_each_entry_safe(struct panvk_cmd_buffer, cmdbuf,
&pool->free_cmd_buffers, pool_link)
panvk_destroy_cmdbuf(cmdbuf);
}
void
panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer,
uint32_t x,

View File

@@ -32,6 +32,8 @@
#include <vulkan/vulkan.h>
#include "compiler/shader_enums.h"
extern const struct vk_command_buffer_ops panvk_per_arch(cmd_buffer_ops);
void
panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf);