• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2022 Collabora Ltd. and Red Hat Inc.
3  * SPDX-License-Identifier: MIT
4  */
5 #include "nvk_cmd_pool.h"
6 
7 #include "nvk_device.h"
8 #include "nvk_entrypoints.h"
9 #include "nvk_physical_device.h"
10 
11 static VkResult
nvk_cmd_bo_create(struct nvk_cmd_pool * pool,bool force_gart,struct nvk_cmd_bo ** bo_out)12 nvk_cmd_bo_create(struct nvk_cmd_pool *pool, bool force_gart, struct nvk_cmd_bo **bo_out)
13 {
14    struct nvk_device *dev = nvk_cmd_pool_device(pool);
15    struct nvk_cmd_bo *bo;
16 
17    bo = vk_zalloc(&pool->vk.alloc, sizeof(*bo), 8,
18                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
19    if (bo == NULL)
20       return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
21 
22    uint32_t flags = NOUVEAU_WS_BO_GART | NOUVEAU_WS_BO_MAP | NOUVEAU_WS_BO_NO_SHARE;
23    if (force_gart)
24       assert(flags & NOUVEAU_WS_BO_GART);
25    bo->bo = nouveau_ws_bo_new_mapped(dev->ws_dev, NVK_CMD_BO_SIZE, 0,
26                                      flags, NOUVEAU_WS_BO_WR, &bo->map);
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_out = bo;
33    return VK_SUCCESS;
34 }
35 
36 static void
nvk_cmd_bo_destroy(struct nvk_cmd_pool * pool,struct nvk_cmd_bo * bo)37 nvk_cmd_bo_destroy(struct nvk_cmd_pool *pool, struct nvk_cmd_bo *bo)
38 {
39    nouveau_ws_bo_unmap(bo->bo, bo->map);
40    nouveau_ws_bo_destroy(bo->bo);
41    vk_free(&pool->vk.alloc, bo);
42 }
43 
44 VKAPI_ATTR VkResult VKAPI_CALL
nvk_CreateCommandPool(VkDevice _device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCmdPool)45 nvk_CreateCommandPool(VkDevice _device,
46                       const VkCommandPoolCreateInfo *pCreateInfo,
47                       const VkAllocationCallbacks *pAllocator,
48                       VkCommandPool *pCmdPool)
49 {
50    VK_FROM_HANDLE(nvk_device, device, _device);
51    struct nvk_cmd_pool *pool;
52 
53    pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
54                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
55    if (pool == NULL)
56       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
57 
58    VkResult result = vk_command_pool_init(&device->vk, &pool->vk,
59                                           pCreateInfo, pAllocator);
60    if (result != VK_SUCCESS) {
61       vk_free2(&device->vk.alloc, pAllocator, pool);
62       return result;
63    }
64 
65    list_inithead(&pool->free_bos);
66    list_inithead(&pool->free_gart_bos);
67 
68    *pCmdPool = nvk_cmd_pool_to_handle(pool);
69 
70    return VK_SUCCESS;
71 }
72 
73 static void
nvk_cmd_pool_destroy_bos(struct nvk_cmd_pool * pool)74 nvk_cmd_pool_destroy_bos(struct nvk_cmd_pool *pool)
75 {
76    list_for_each_entry_safe(struct nvk_cmd_bo, bo, &pool->free_bos, link)
77       nvk_cmd_bo_destroy(pool, bo);
78 
79    list_inithead(&pool->free_bos);
80 
81    list_for_each_entry_safe(struct nvk_cmd_bo, bo, &pool->free_gart_bos, link)
82       nvk_cmd_bo_destroy(pool, bo);
83 
84    list_inithead(&pool->free_gart_bos);
85 }
86 
87 VkResult
nvk_cmd_pool_alloc_bo(struct nvk_cmd_pool * pool,bool force_gart,struct nvk_cmd_bo ** bo_out)88 nvk_cmd_pool_alloc_bo(struct nvk_cmd_pool *pool, bool force_gart, struct nvk_cmd_bo **bo_out)
89 {
90    struct nvk_cmd_bo *bo = NULL;
91    if (force_gart) {
92       if (!list_is_empty(&pool->free_gart_bos))
93          bo = list_first_entry(&pool->free_gart_bos, struct nvk_cmd_bo, link);
94    } else {
95       if (!list_is_empty(&pool->free_bos))
96          bo = list_first_entry(&pool->free_bos, struct nvk_cmd_bo, link);
97    }
98    if (bo) {
99       list_del(&bo->link);
100       *bo_out = bo;
101       return VK_SUCCESS;
102    }
103 
104    return nvk_cmd_bo_create(pool, force_gart, bo_out);
105 }
106 
107 void
nvk_cmd_pool_free_bo_list(struct nvk_cmd_pool * pool,struct list_head * bos)108 nvk_cmd_pool_free_bo_list(struct nvk_cmd_pool *pool, struct list_head *bos)
109 {
110    list_splicetail(bos, &pool->free_bos);
111    list_inithead(bos);
112 }
113 
114 void
nvk_cmd_pool_free_gart_bo_list(struct nvk_cmd_pool * pool,struct list_head * bos)115 nvk_cmd_pool_free_gart_bo_list(struct nvk_cmd_pool *pool, struct list_head *bos)
116 {
117    list_splicetail(bos, &pool->free_gart_bos);
118    list_inithead(bos);
119 }
120 
121 VKAPI_ATTR void VKAPI_CALL
nvk_DestroyCommandPool(VkDevice _device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)122 nvk_DestroyCommandPool(VkDevice _device,
123                        VkCommandPool commandPool,
124                        const VkAllocationCallbacks *pAllocator)
125 {
126    VK_FROM_HANDLE(nvk_device, device, _device);
127    VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
128 
129    if (!pool)
130       return;
131 
132    vk_command_pool_finish(&pool->vk);
133    nvk_cmd_pool_destroy_bos(pool);
134    vk_free2(&device->vk.alloc, pAllocator, pool);
135 }
136 
137 VKAPI_ATTR void VKAPI_CALL
nvk_TrimCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolTrimFlags flags)138 nvk_TrimCommandPool(VkDevice device,
139                     VkCommandPool commandPool,
140                     VkCommandPoolTrimFlags flags)
141 {
142    VK_FROM_HANDLE(nvk_cmd_pool, pool, commandPool);
143 
144    vk_command_pool_trim(&pool->vk, flags);
145    nvk_cmd_pool_destroy_bos(pool);
146 }
147