xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_cmd_pool.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * Copyright 2024 Alyssa Rosenzweig
4  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5  * SPDX-License-Identifier: MIT
6  */
7 #include "hk_cmd_pool.h"
8 #include "asahi/lib/agx_bo.h"
9 
10 #include "hk_device.h"
11 #include "hk_entrypoints.h"
12 #include "hk_physical_device.h"
13 
14 static VkResult
hk_cmd_bo_create(struct hk_cmd_pool * pool,bool usc,struct hk_cmd_bo ** bo_out)15 hk_cmd_bo_create(struct hk_cmd_pool *pool, bool usc, struct hk_cmd_bo **bo_out)
16 {
17    struct hk_device *dev = hk_cmd_pool_device(pool);
18    struct hk_cmd_bo *bo;
19 
20    bo = vk_zalloc(&pool->vk.alloc, sizeof(*bo), 8,
21                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
22    if (bo == NULL)
23       return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
24 
25    bo->bo = agx_bo_create(&dev->dev, HK_CMD_BO_SIZE, 0, usc ? AGX_BO_LOW_VA : 0,
26                           "Command pool");
27    if (bo->bo == NULL) {
28       vk_free(&pool->vk.alloc, bo);
29       return vk_error(pool, VK_ERROR_OUT_OF_DEVICE_MEMORY);
30    }
31 
32    bo->map = bo->bo->map;
33 
34    *bo_out = bo;
35    return VK_SUCCESS;
36 }
37 
38 static void
hk_cmd_bo_destroy(struct hk_cmd_pool * pool,struct hk_cmd_bo * bo)39 hk_cmd_bo_destroy(struct hk_cmd_pool *pool, struct hk_cmd_bo *bo)
40 {
41    struct hk_device *dev = hk_cmd_pool_device(pool);
42    agx_bo_unreference(&dev->dev, bo->bo);
43    vk_free(&pool->vk.alloc, bo);
44 }
45 
46 VKAPI_ATTR VkResult VKAPI_CALL
hk_CreateCommandPool(VkDevice _device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCmdPool)47 hk_CreateCommandPool(VkDevice _device,
48                      const VkCommandPoolCreateInfo *pCreateInfo,
49                      const VkAllocationCallbacks *pAllocator,
50                      VkCommandPool *pCmdPool)
51 {
52    VK_FROM_HANDLE(hk_device, device, _device);
53    struct hk_cmd_pool *pool;
54 
55    pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
56                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
57    if (pool == NULL)
58       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
59 
60    VkResult result =
61       vk_command_pool_init(&device->vk, &pool->vk, pCreateInfo, pAllocator);
62    if (result != VK_SUCCESS) {
63       vk_free2(&device->vk.alloc, pAllocator, pool);
64       return result;
65    }
66 
67    list_inithead(&pool->free_bos);
68    list_inithead(&pool->free_usc_bos);
69 
70    *pCmdPool = hk_cmd_pool_to_handle(pool);
71 
72    return VK_SUCCESS;
73 }
74 
75 static void
hk_cmd_pool_destroy_bos(struct hk_cmd_pool * pool)76 hk_cmd_pool_destroy_bos(struct hk_cmd_pool *pool)
77 {
78    list_for_each_entry_safe(struct hk_cmd_bo, bo, &pool->free_bos, link)
79       hk_cmd_bo_destroy(pool, bo);
80 
81    list_inithead(&pool->free_bos);
82 
83    list_for_each_entry_safe(struct hk_cmd_bo, bo, &pool->free_usc_bos, link)
84       hk_cmd_bo_destroy(pool, bo);
85 
86    list_inithead(&pool->free_usc_bos);
87 }
88 
89 VkResult
hk_cmd_pool_alloc_bo(struct hk_cmd_pool * pool,bool usc,struct hk_cmd_bo ** bo_out)90 hk_cmd_pool_alloc_bo(struct hk_cmd_pool *pool, bool usc,
91                      struct hk_cmd_bo **bo_out)
92 {
93    struct hk_cmd_bo *bo = NULL;
94    if (usc) {
95       if (!list_is_empty(&pool->free_usc_bos))
96          bo = list_first_entry(&pool->free_usc_bos, struct hk_cmd_bo, link);
97    } else {
98       if (!list_is_empty(&pool->free_bos))
99          bo = list_first_entry(&pool->free_bos, struct hk_cmd_bo, link);
100    }
101    if (bo) {
102       list_del(&bo->link);
103       *bo_out = bo;
104       return VK_SUCCESS;
105    }
106 
107    return hk_cmd_bo_create(pool, usc, bo_out);
108 }
109 
110 void
hk_cmd_pool_free_bo_list(struct hk_cmd_pool * pool,struct list_head * bos)111 hk_cmd_pool_free_bo_list(struct hk_cmd_pool *pool, struct list_head *bos)
112 {
113    list_splicetail(bos, &pool->free_bos);
114    list_inithead(bos);
115 }
116 
117 void
hk_cmd_pool_free_usc_bo_list(struct hk_cmd_pool * pool,struct list_head * bos)118 hk_cmd_pool_free_usc_bo_list(struct hk_cmd_pool *pool, struct list_head *bos)
119 {
120    list_splicetail(bos, &pool->free_usc_bos);
121    list_inithead(bos);
122 }
123 
124 VKAPI_ATTR void VKAPI_CALL
hk_DestroyCommandPool(VkDevice _device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)125 hk_DestroyCommandPool(VkDevice _device, VkCommandPool commandPool,
126                       const VkAllocationCallbacks *pAllocator)
127 {
128    VK_FROM_HANDLE(hk_device, device, _device);
129    VK_FROM_HANDLE(hk_cmd_pool, pool, commandPool);
130 
131    if (!pool)
132       return;
133 
134    vk_command_pool_finish(&pool->vk);
135    hk_cmd_pool_destroy_bos(pool);
136    vk_free2(&device->vk.alloc, pAllocator, pool);
137 }
138 
139 VKAPI_ATTR void VKAPI_CALL
hk_TrimCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolTrimFlags flags)140 hk_TrimCommandPool(VkDevice device, VkCommandPool commandPool,
141                    VkCommandPoolTrimFlags flags)
142 {
143    VK_FROM_HANDLE(hk_cmd_pool, pool, commandPool);
144 
145    vk_command_pool_trim(&pool->vk, flags);
146    hk_cmd_pool_destroy_bos(pool);
147 }
148