mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
nvk: add cmd buffer framework
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
decb8c6fd4
commit
6e0089307e
4 changed files with 254 additions and 1 deletions
|
|
@ -1,6 +1,8 @@
|
|||
nvk_files = files(
|
||||
'nvk_buffer.c',
|
||||
'nvk_buffer.h',
|
||||
'nvk_cmd_buffer.c',
|
||||
'nvk_cmd_buffer.h',
|
||||
'nvk_device.c',
|
||||
'nvk_device.h',
|
||||
'nvk_device_memory.c',
|
||||
|
|
|
|||
211
src/nouveau/vulkan/nvk_cmd_buffer.c
Normal file
211
src/nouveau/vulkan/nvk_cmd_buffer.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#include "nvk_cmd_buffer.h"
|
||||
|
||||
#include "nvk_device.h"
|
||||
#include "nvk_physical_device.h"
|
||||
|
||||
#include "nouveau_push.h"
|
||||
|
||||
static void
|
||||
nvk_destroy_cmd_buffer(struct nvk_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
list_del(&cmd_buffer->pool_link);
|
||||
|
||||
nouveau_ws_push_destroy(cmd_buffer->push);
|
||||
vk_command_buffer_finish(&cmd_buffer->vk);
|
||||
vk_free(&cmd_buffer->pool->vk.alloc, cmd_buffer);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
nvk_create_cmd_buffer(struct nvk_device *device, struct nvk_cmd_pool *pool,
|
||||
VkCommandBufferLevel level, VkCommandBuffer *pCommandBuffer)
|
||||
{
|
||||
struct nvk_cmd_buffer *cmd_buffer;
|
||||
|
||||
cmd_buffer = vk_zalloc(&pool->vk.alloc, sizeof(*cmd_buffer), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (cmd_buffer == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
VkResult result =
|
||||
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL, level);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_free(&cmd_buffer->pool->vk.alloc, cmd_buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
cmd_buffer->pool = pool;
|
||||
list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
|
||||
|
||||
cmd_buffer->push = nouveau_ws_push_new(device->pdev->dev, NVK_CMD_BUF_SIZE);
|
||||
*pCommandBuffer = nvk_cmd_buffer_to_handle(cmd_buffer);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
nvk_reset_cmd_buffer(struct nvk_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
vk_command_buffer_reset(&cmd_buffer->vk);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_CreateCommandPool(VkDevice _device, const VkCommandPoolCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkCommandPool *pCmdPool)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_device, device, _device);
|
||||
struct nvk_cmd_pool *pool;
|
||||
|
||||
pool =
|
||||
vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (pool == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
VkResult result = vk_command_pool_init(&device->vk, &pool->vk, pCreateInfo, pAllocator);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_free2(&device->vk.alloc, pAllocator, pool);
|
||||
return result;
|
||||
}
|
||||
|
||||
list_inithead(&pool->cmd_buffers);
|
||||
list_inithead(&pool->free_cmd_buffers);
|
||||
|
||||
*pCmdPool = nvk_cmd_pool_to_handle(pool);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
nvk_DestroyCommandPool(VkDevice _device, VkCommandPool commandPool,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_device, device, _device);
|
||||
VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(struct nvk_cmd_buffer, cmd_buffer, &pool->cmd_buffers, pool_link)
|
||||
{
|
||||
nvk_destroy_cmd_buffer(cmd_buffer);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(struct nvk_cmd_buffer, cmd_buffer, &pool->free_cmd_buffers, pool_link)
|
||||
{
|
||||
nvk_destroy_cmd_buffer(cmd_buffer);
|
||||
}
|
||||
|
||||
vk_command_pool_finish(&pool->vk);
|
||||
vk_free2(&device->vk.alloc, pAllocator, pool);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
|
||||
VkResult result;
|
||||
|
||||
list_for_each_entry(struct nvk_cmd_buffer, cmd_buffer, &pool->cmd_buffers, pool_link)
|
||||
{
|
||||
result = nvk_reset_cmd_buffer(cmd_buffer);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
nvk_TrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
|
||||
|
||||
list_for_each_entry_safe(struct nvk_cmd_buffer, cmd_buffer, &pool->free_cmd_buffers, pool_link)
|
||||
{
|
||||
nvk_destroy_cmd_buffer(cmd_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_AllocateCommandBuffers(VkDevice _device,
|
||||
const VkCommandBufferAllocateInfo *pAllocateInfo,
|
||||
VkCommandBuffer *pCommandBuffers)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_device, device, _device);
|
||||
VK_FROM_HANDLE(nvk_cmd_pool, pool, pAllocateInfo->commandPool);
|
||||
uint32_t i;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
|
||||
if (!list_is_empty(&pool->free_cmd_buffers)) {
|
||||
struct nvk_cmd_buffer *cmd_buffer =
|
||||
list_first_entry(&pool->free_cmd_buffers, struct nvk_cmd_buffer, pool_link);
|
||||
|
||||
list_del(&cmd_buffer->pool_link);
|
||||
list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
|
||||
|
||||
result = nvk_reset_cmd_buffer(cmd_buffer);
|
||||
vk_command_buffer_finish(&cmd_buffer->vk);
|
||||
VkResult init_result =
|
||||
vk_command_buffer_init(&pool->vk, &cmd_buffer->vk, NULL,
|
||||
pAllocateInfo->level);
|
||||
if (init_result != VK_SUCCESS)
|
||||
result = init_result;
|
||||
|
||||
pCommandBuffers[i] = nvk_cmd_buffer_to_handle(cmd_buffer);
|
||||
} else {
|
||||
result = nvk_create_cmd_buffer(device, pool, pAllocateInfo->level, &pCommandBuffers[i]);
|
||||
}
|
||||
if (result != VK_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
nvk_FreeCommandBuffers(_device, pAllocateInfo->commandPool, i, pCommandBuffers);
|
||||
/* From the Vulkan 1.0.66 spec:
|
||||
*
|
||||
* "vkAllocateCommandBuffers can be used to create multiple
|
||||
* command buffers. If the creation of any of those command
|
||||
* buffers fails, the implementation must destroy all
|
||||
* successfully created command buffer objects from this
|
||||
* command, set all entries of the pCommandBuffers array to
|
||||
* NULL and return the error."
|
||||
*/
|
||||
memset(pCommandBuffers, 0, sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
nvk_FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
|
||||
const VkCommandBuffer *pCommandBuffers)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
|
||||
for (uint32_t i = 0; i < commandBufferCount; i++) {
|
||||
VK_FROM_HANDLE(nvk_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
|
||||
|
||||
if (!cmd_buffer)
|
||||
continue;
|
||||
assert(cmd_buffer->pool == pool);
|
||||
|
||||
list_del(&cmd_buffer->pool_link);
|
||||
list_addtail(&cmd_buffer->pool_link, &pool->free_cmd_buffers);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags)
|
||||
{
|
||||
VK_FROM_HANDLE(nvk_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
return nvk_reset_cmd_buffer(cmd_buffer);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_EndCommandBuffer(VkCommandBuffer commandBuffer)
|
||||
{
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
31
src/nouveau/vulkan/nvk_cmd_buffer.h
Normal file
31
src/nouveau/vulkan/nvk_cmd_buffer.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef NVK_CMD_BUFFER_H
|
||||
#define NVK_CMD_BUFFER_H 1
|
||||
|
||||
#include "nvk_private.h"
|
||||
|
||||
#include "vulkan/runtime/vk_command_buffer.h"
|
||||
#include "vulkan/runtime/vk_command_pool.h"
|
||||
|
||||
#define NVK_CMD_BUF_SIZE 64*1024
|
||||
|
||||
struct nvk_cmd_pool {
|
||||
struct vk_command_pool vk;
|
||||
struct list_head cmd_buffers;
|
||||
struct list_head free_cmd_buffers;
|
||||
};
|
||||
|
||||
struct nvk_cmd_buffer {
|
||||
struct vk_command_buffer vk;
|
||||
|
||||
struct nvk_cmd_pool *pool;
|
||||
struct list_head pool_link;
|
||||
|
||||
struct nouveau_ws_push *push;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(nvk_cmd_buffer, vk.base, VkCommandBuffer,
|
||||
VK_OBJECT_TYPE_COMMAND_BUFFER)
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_cmd_pool, vk.base, VkCommandPool,
|
||||
VK_OBJECT_TYPE_COMMAND_POOL)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,15 +1,24 @@
|
|||
#include "nvk_device.h"
|
||||
|
||||
#include "nvk_cmd_buffer.h"
|
||||
#include "nvk_instance.h"
|
||||
#include "nvk_physical_device.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_push.h"
|
||||
|
||||
#include "vulkan/wsi/wsi_common.h"
|
||||
|
||||
static VkResult
|
||||
nvk_queue_submit(struct vk_queue *vqueue, struct vk_queue_submit *submission)
|
||||
nvk_queue_submit(struct vk_queue *queue, struct vk_queue_submit *submission)
|
||||
{
|
||||
struct nvk_device *device = container_of(queue->base.device, struct nvk_device, vk);
|
||||
|
||||
for (unsigned i = 0; i < submission->command_buffer_count; i++) {
|
||||
struct nvk_cmd_buffer *cmd = (struct nvk_cmd_buffer *)submission->command_buffers[i];
|
||||
nouveau_ws_push_submit(cmd->push, device->pdev->dev, device->ctx);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue