1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
3bf215546Sopenharmony_ci * Copyright © 2022 Collabora, Ltd
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22bf215546Sopenharmony_ci * IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "vk_command_pool.h"
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include "vk_alloc.h"
28bf215546Sopenharmony_ci#include "vk_command_buffer.h"
29bf215546Sopenharmony_ci#include "vk_common_entrypoints.h"
30bf215546Sopenharmony_ci#include "vk_device.h"
31bf215546Sopenharmony_ci#include "vk_log.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ciVkResult MUST_CHECK
34bf215546Sopenharmony_civk_command_pool_init(struct vk_command_pool *pool,
35bf215546Sopenharmony_ci                     struct vk_device *device,
36bf215546Sopenharmony_ci                     const VkCommandPoolCreateInfo *pCreateInfo,
37bf215546Sopenharmony_ci                     const VkAllocationCallbacks *pAllocator)
38bf215546Sopenharmony_ci{
39bf215546Sopenharmony_ci   memset(pool, 0, sizeof(*pool));
40bf215546Sopenharmony_ci   vk_object_base_init(device, &pool->base,
41bf215546Sopenharmony_ci                       VK_OBJECT_TYPE_COMMAND_POOL);
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci   pool->flags = pCreateInfo->flags;
44bf215546Sopenharmony_ci   pool->queue_family_index = pCreateInfo->queueFamilyIndex;
45bf215546Sopenharmony_ci   pool->alloc = pAllocator ? *pAllocator : device->alloc;
46bf215546Sopenharmony_ci   list_inithead(&pool->command_buffers);
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci   return VK_SUCCESS;
49bf215546Sopenharmony_ci}
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_civoid
52bf215546Sopenharmony_civk_command_pool_finish(struct vk_command_pool *pool)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   list_for_each_entry_safe(struct vk_command_buffer, cmd_buffer,
55bf215546Sopenharmony_ci                            &pool->command_buffers, pool_link) {
56bf215546Sopenharmony_ci      cmd_buffer->destroy(cmd_buffer);
57bf215546Sopenharmony_ci   }
58bf215546Sopenharmony_ci   assert(list_is_empty(&pool->command_buffers));
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci   vk_object_base_finish(&pool->base);
61bf215546Sopenharmony_ci}
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
64bf215546Sopenharmony_civk_common_CreateCommandPool(VkDevice _device,
65bf215546Sopenharmony_ci                            const VkCommandPoolCreateInfo *pCreateInfo,
66bf215546Sopenharmony_ci                            const VkAllocationCallbacks *pAllocator,
67bf215546Sopenharmony_ci                            VkCommandPool *pCommandPool)
68bf215546Sopenharmony_ci{
69bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_device, device, _device);
70bf215546Sopenharmony_ci   struct vk_command_pool *pool;
71bf215546Sopenharmony_ci   VkResult result;
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
74bf215546Sopenharmony_ci                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
75bf215546Sopenharmony_ci   if (pool == NULL)
76bf215546Sopenharmony_ci      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   result = vk_command_pool_init(pool, device, pCreateInfo, pAllocator);
79bf215546Sopenharmony_ci   if (unlikely(result != VK_SUCCESS)) {
80bf215546Sopenharmony_ci      vk_free2(&device->alloc, pAllocator, pool);
81bf215546Sopenharmony_ci      return result;
82bf215546Sopenharmony_ci   }
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   *pCommandPool = vk_command_pool_to_handle(pool);
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   return VK_SUCCESS;
87bf215546Sopenharmony_ci}
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
90bf215546Sopenharmony_civk_common_DestroyCommandPool(VkDevice _device,
91bf215546Sopenharmony_ci                             VkCommandPool commandPool,
92bf215546Sopenharmony_ci                             const VkAllocationCallbacks *pAllocator)
93bf215546Sopenharmony_ci{
94bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_device, device, _device);
95bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_pool, pool, commandPool);
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   if (pool == NULL)
98bf215546Sopenharmony_ci      return;
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci   vk_command_pool_finish(pool);
101bf215546Sopenharmony_ci   vk_free2(&device->alloc, pAllocator, pool);
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
105bf215546Sopenharmony_civk_common_ResetCommandPool(VkDevice device,
106bf215546Sopenharmony_ci                           VkCommandPool commandPool,
107bf215546Sopenharmony_ci                           VkCommandPoolResetFlags flags)
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_pool, pool, commandPool);
110bf215546Sopenharmony_ci   const struct vk_device_dispatch_table *disp =
111bf215546Sopenharmony_ci      &pool->base.device->dispatch_table;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci#define COPY_FLAG(flag) \
114bf215546Sopenharmony_ci   if (flags & VK_COMMAND_POOL_RESET_##flag) \
115bf215546Sopenharmony_ci      cb_flags |= VK_COMMAND_BUFFER_RESET_##flag
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   VkCommandBufferResetFlags cb_flags = 0;
118bf215546Sopenharmony_ci   COPY_FLAG(RELEASE_RESOURCES_BIT);
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci#undef COPY_FLAG
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci   list_for_each_entry_safe(struct vk_command_buffer, cmd_buffer,
123bf215546Sopenharmony_ci                            &pool->command_buffers, pool_link) {
124bf215546Sopenharmony_ci      VkResult result =
125bf215546Sopenharmony_ci         disp->ResetCommandBuffer(vk_command_buffer_to_handle(cmd_buffer),
126bf215546Sopenharmony_ci                                  cb_flags);
127bf215546Sopenharmony_ci      if (result != VK_SUCCESS)
128bf215546Sopenharmony_ci         return result;
129bf215546Sopenharmony_ci   }
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci   return VK_SUCCESS;
132bf215546Sopenharmony_ci}
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
135bf215546Sopenharmony_civk_common_FreeCommandBuffers(VkDevice device,
136bf215546Sopenharmony_ci                             VkCommandPool commandPool,
137bf215546Sopenharmony_ci                             uint32_t commandBufferCount,
138bf215546Sopenharmony_ci                             const VkCommandBuffer *pCommandBuffers)
139bf215546Sopenharmony_ci{
140bf215546Sopenharmony_ci   for (uint32_t i = 0; i < commandBufferCount; i++) {
141bf215546Sopenharmony_ci      VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, pCommandBuffers[i]);
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci      if (cmd_buffer == NULL)
144bf215546Sopenharmony_ci         continue;
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci      cmd_buffer->destroy(cmd_buffer);
147bf215546Sopenharmony_ci   }
148bf215546Sopenharmony_ci}
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
151bf215546Sopenharmony_civk_common_TrimCommandPool(VkDevice device,
152bf215546Sopenharmony_ci                          VkCommandPool commandPool,
153bf215546Sopenharmony_ci                          VkCommandPoolTrimFlags flags)
154bf215546Sopenharmony_ci{
155bf215546Sopenharmony_ci   /* No-op is a valid implementation but may not be optimal */
156bf215546Sopenharmony_ci}
157