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