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