xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pvr_bo.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * based in part on tu driver which is:
5  * Copyright © 2016 Red Hat.
6  * Copyright © 2016 Bas Nieuwenhuizen
7  * Copyright © 2015 Intel Corporation
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  */
28 
29 #ifndef PVR_BO_H
30 #define PVR_BO_H
31 
32 #include <stddef.h>
33 #include <stdint.h>
34 #include <vulkan/vulkan.h>
35 
36 #include "pvr_types.h"
37 #include "pvr_winsys.h"
38 #include "util/list.h"
39 #include "util/macros.h"
40 #include "util/simple_mtx.h"
41 
42 struct pvr_device;
43 struct pvr_dump_ctx;
44 struct pvr_winsys_bo;
45 struct pvr_winsys_vma;
46 struct pvr_winsys_heap;
47 
48 struct pvr_bo {
49    /* Since multiple components (csb, caching logic, etc.) can make use of
50     * linking buffers in a list, we add 'link' in pvr_bo to avoid an extra
51     * level of structure inheritance. It's the responsibility of the buffer
52     * user to manage the list and remove the buffer from the list before
53     * freeing it.
54     */
55    struct list_head link;
56 
57    struct pvr_winsys_bo *bo;
58    struct pvr_winsys_vma *vma;
59    uint32_t ref_count;
60 };
61 
62 struct pvr_suballocator {
63    /* Pointer to the pvr_device this allocator is associated with */
64    struct pvr_device *device;
65    /* Pointer to one heap type (e.g. general, pds or usc) */
66    struct pvr_winsys_heap *heap;
67    /* Minimum size of the pvr_bo shared across multiple sub-allocations */
68    uint32_t default_size;
69 
70    /* Mutex to protect access to all of the members below this point */
71    simple_mtx_t mtx;
72 
73    /* Current buffer object where sub-allocations are made from */
74    struct pvr_bo *bo;
75    /* Previous buffer that can be used when a new buffer object is needed */
76    struct pvr_bo *bo_cached;
77    /* Track from where to start the next sub-allocation */
78    uint32_t next_offset;
79 };
80 
81 struct pvr_suballoc_bo {
82    /* Since multiple components (command buffer, clear, descriptor sets,
83     * pipeline, SPM, etc.) can make use of linking sub-allocated bo(s), we
84     * add 'link' in pvr_suballoc_bo and avoid one extra level of structure
85     * inheritance. It is users' responsibility to manage the linked list,
86     * to remove sub-allocations before freeing it.
87     */
88    struct list_head link;
89 
90    struct pvr_suballocator *allocator;
91    struct pvr_bo *bo;
92    pvr_dev_addr_t dev_addr;
93    uint64_t offset;
94    uint32_t size;
95 };
96 
97 /**
98  * \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should be
99  * CPU accessible. This is required in order to map a buffer with
100  * #pvr_bo_cpu_map().
101  */
102 #define PVR_BO_ALLOC_FLAG_CPU_ACCESS BITFIELD_BIT(0U)
103 /**
104  * \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should
105  * be mapped to the CPU. Implies #PVR_BO_ALLOC_FLAG_CPU_ACCESS.
106  */
107 #define PVR_BO_ALLOC_FLAG_CPU_MAPPED BITFIELD_BIT(1U)
108 /**
109  * \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should be
110  * mapped to the GPU as uncached.
111  */
112 #define PVR_BO_ALLOC_FLAG_GPU_UNCACHED BITFIELD_BIT(2U)
113 /**
114  * \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer GPU mapping
115  * should be restricted to only allow access to the Parameter Manager unit and
116  * firmware processor.
117  */
118 #define PVR_BO_ALLOC_FLAG_PM_FW_PROTECT BITFIELD_BIT(3U)
119 
120 VkResult pvr_bo_alloc(struct pvr_device *device,
121                       struct pvr_winsys_heap *heap,
122                       uint64_t size,
123                       uint64_t alignment,
124                       uint64_t flags,
125                       struct pvr_bo **const bo_out);
126 VkResult pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo);
127 void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *bo);
128 void pvr_bo_free(struct pvr_device *device, struct pvr_bo *bo);
129 
130 void pvr_bo_suballocator_init(struct pvr_suballocator *allocator,
131                               struct pvr_winsys_heap *heap,
132                               struct pvr_device *device,
133                               uint32_t default_size);
134 void pvr_bo_suballocator_fini(struct pvr_suballocator *suballoc);
135 VkResult pvr_bo_suballoc(struct pvr_suballocator *allocator,
136                          uint32_t size,
137                          uint32_t alignment,
138                          bool zero_on_alloc,
139                          struct pvr_suballoc_bo **const suballoc_bo_out);
140 void pvr_bo_suballoc_free(struct pvr_suballoc_bo *suballoc_bo);
141 void *pvr_bo_suballoc_get_map_addr(const struct pvr_suballoc_bo *suballoc_bo);
142 
143 #if defined(HAVE_VALGRIND)
144 VkResult pvr_bo_cpu_map_unchanged(struct pvr_device *device,
145                                   struct pvr_bo *pvr_bo);
146 #else /* defined(HAVE_VALGRIND) */
147 static ALWAYS_INLINE VkResult
pvr_bo_cpu_map_unchanged(struct pvr_device * device,struct pvr_bo * pvr_bo)148 pvr_bo_cpu_map_unchanged(struct pvr_device *device, struct pvr_bo *pvr_bo)
149 {
150    return pvr_bo_cpu_map(device, pvr_bo);
151 }
152 #endif /* defined(HAVE_VALGRIND) */
153 
154 struct pvr_bo_store;
155 
156 VkResult pvr_bo_store_create(struct pvr_device *device);
157 void pvr_bo_store_destroy(struct pvr_device *device);
158 struct pvr_bo *pvr_bo_store_lookup(struct pvr_device *device,
159                                    pvr_dev_addr_t addr);
160 bool pvr_bo_store_dump(struct pvr_device *device);
161 
162 void pvr_bo_list_dump(struct pvr_dump_ctx *ctx,
163                       const struct list_head *bo_list,
164                       uint32_t bo_size);
165 
166 #endif /* PVR_BO_H */
167