xref: /aosp_15_r20/external/mesa3d/src/gfxstream/guest/vulkan_enc/Resources.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2018 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 #include "Resources.h"
6 
7 #include <stdlib.h>
8 
9 #include "util/log.h"
10 
11 #define GOLDFISH_VK_OBJECT_DEBUG 0
12 
13 #if GOLDFISH_VK_OBJECT_DEBUG
14 #define D(fmt, ...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__);
15 #else
16 #ifndef D
17 #define D(fmt, ...)
18 #endif
19 #endif
20 
21 extern "C" {
22 
23 #if defined(__ANDROID__) || defined(__Fuchsia__)
24 #define SET_HWVULKAN_DISPATCH_MAGIC res->dispatch.magic = HWVULKAN_DISPATCH_MAGIC;
25 #elif defined(__linux__)
26 #define SET_HWVULKAN_DISPATCH_MAGIC res->loaderData.loaderMagic = ICD_LOADER_MAGIC;
27 #else
28 #define SET_HWVULKAN_DISPATCH_MAGIC
29 #endif
30 
31 #define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL(type)                   \
32     type new_from_host_##type(type underlying) {                            \
33         struct goldfish_##type* res =                                       \
34             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
35         if (!res) {                                                         \
36             mesa_loge("FATAL: Failed to alloc " #type " handle");           \
37             abort();                                                        \
38         }                                                                   \
39         SET_HWVULKAN_DISPATCH_MAGIC                                         \
40         res->underlying = (uint64_t)underlying;                             \
41         res->lastUsedEncoder = nullptr;                                     \
42         res->sequenceNumber = 0;                                            \
43         res->privateEncoder = 0;                                            \
44         res->privateStream = 0;                                             \
45         res->flags = 0;                                                     \
46         res->poolObjects = 0;                                               \
47         res->subObjects = 0;                                                \
48         res->superObjects = 0;                                              \
49         res->userPtr = 0;                                                   \
50         return reinterpret_cast<type>(res);                                 \
51     }
52 
53 #define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL(type)       \
54     type new_from_host_##type(type underlying) {                            \
55         struct goldfish_##type* res =                                       \
56             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
57         res->underlying = (uint64_t)underlying;                             \
58         res->poolObjects = 0;                                               \
59         res->subObjects = 0;                                                \
60         res->superObjects = 0;                                              \
61         res->userPtr = 0;                                                   \
62         return reinterpret_cast<type>(res);                                 \
63     }
64 
65 #define GOLDFISH_VK_AS_GOLDFISH_IMPL(type)                    \
66     struct goldfish_##type* as_goldfish_##type(type toCast) { \
67         return reinterpret_cast<goldfish_##type*>(toCast);    \
68     }
69 
70 #define GOLDFISH_VK_GET_HOST_IMPL(type)                  \
71     type get_host_##type(type toUnwrap) {                \
72         if (!toUnwrap) return VK_NULL_HANDLE;            \
73         auto as_goldfish = as_goldfish_##type(toUnwrap); \
74         return (type)(as_goldfish->underlying);          \
75     }
76 
77 #define GOLDFISH_VK_DELETE_GOLDFISH_IMPL(type)   \
78     void delete_goldfish_##type(type toDelete) { \
79         D("guest %p", toDelete);                 \
80         free(as_goldfish_##type(toDelete));      \
81     }
82 
83 #define GOLDFISH_VK_IDENTITY_IMPL(type) \
84     type vk_handle_identity_##type(type handle) { return handle; }
85 
86 #define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL(type)               \
87     type new_from_host_u64_##type(uint64_t underlying) {                    \
88         struct goldfish_##type* res =                                       \
89             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
90         if (!res) {                                                         \
91             mesa_loge("FATAL: Failed to alloc " #type " handle");           \
92             abort();                                                        \
93         }                                                                   \
94         SET_HWVULKAN_DISPATCH_MAGIC                                         \
95         res->underlying = underlying;                                       \
96         res->lastUsedEncoder = nullptr;                                     \
97         res->sequenceNumber = 0;                                            \
98         res->privateEncoder = 0;                                            \
99         res->privateStream = 0;                                             \
100         res->flags = 0;                                                     \
101         res->poolObjects = 0;                                               \
102         res->subObjects = 0;                                                \
103         res->superObjects = 0;                                              \
104         res->userPtr = 0;                                                   \
105         return reinterpret_cast<type>(res);                                 \
106     }
107 
108 #define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL(type)          \
109     type new_from_host_u64_##type(uint64_t underlying) {                           \
110         struct goldfish_##type* res =                                              \
111             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type)));        \
112         res->underlying = underlying;                                              \
113         D("guest %p: host u64: 0x%llx", res, (unsigned long long)res->underlying); \
114         res->poolObjects = 0;                                                      \
115         res->subObjects = 0;                                                       \
116         res->superObjects = 0;                                                     \
117         res->userPtr = 0;                                                          \
118         return reinterpret_cast<type>(res);                                        \
119     }
120 
121 #define GOLDFISH_VK_GET_HOST_U64_IMPL(type)                                                     \
122     uint64_t get_host_u64_##type(type toUnwrap) {                                               \
123         if (!toUnwrap) return 0;                                                                \
124         auto as_goldfish = as_goldfish_##type(toUnwrap);                                        \
125         D("guest %p: host u64: 0x%llx", toUnwrap, (unsigned long long)as_goldfish->underlying); \
126         return as_goldfish->underlying;                                                         \
127     }
128 
129 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)130 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)
131 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_IMPL)
132 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DELETE_GOLDFISH_IMPL)
133 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_IMPL)
134 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL)
135 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_IMPL)
136 
137 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)
138 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_IMPL)
139 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_IMPL)
140 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_IMPL)
141 GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(
142     GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL)
143 GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(
144     GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL)
145 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DELETE_GOLDFISH_IMPL)
146 
147 VkDescriptorPool new_from_host_VkDescriptorPool(VkDescriptorPool underlying) {
148     struct goldfish_VkDescriptorPool* res =
149         static_cast<goldfish_VkDescriptorPool*>(malloc(sizeof(goldfish_VkDescriptorPool)));
150     res->underlying = (uint64_t)underlying;
151     res->allocInfo = nullptr;
152     return reinterpret_cast<VkDescriptorPool>(res);
153 }
154 
new_from_host_u64_VkDescriptorPool(uint64_t underlying)155 VkDescriptorPool new_from_host_u64_VkDescriptorPool(uint64_t underlying) {
156     return new_from_host_VkDescriptorPool((VkDescriptorPool)underlying);
157 }
158 
new_from_host_VkDescriptorSet(VkDescriptorSet underlying)159 VkDescriptorSet new_from_host_VkDescriptorSet(VkDescriptorSet underlying) {
160     struct goldfish_VkDescriptorSet* res =
161         static_cast<goldfish_VkDescriptorSet*>(malloc(sizeof(goldfish_VkDescriptorSet)));
162     res->underlying = (uint64_t)underlying;
163     res->reified = nullptr;
164     return reinterpret_cast<VkDescriptorSet>(res);
165 }
166 
new_from_host_u64_VkDescriptorSet(uint64_t underlying)167 VkDescriptorSet new_from_host_u64_VkDescriptorSet(uint64_t underlying) {
168     return new_from_host_VkDescriptorSet((VkDescriptorSet)underlying);
169 }
170 
new_from_host_VkDescriptorSetLayout(VkDescriptorSetLayout underlying)171 VkDescriptorSetLayout new_from_host_VkDescriptorSetLayout(VkDescriptorSetLayout underlying) {
172     struct goldfish_VkDescriptorSetLayout* res = static_cast<goldfish_VkDescriptorSetLayout*>(
173         malloc(sizeof(goldfish_VkDescriptorSetLayout)));
174     res->underlying = (uint64_t)underlying;
175     res->layoutInfo = nullptr;
176     return reinterpret_cast<VkDescriptorSetLayout>(res);
177 }
178 
new_from_host_u64_VkDescriptorSetLayout(uint64_t underlying)179 VkDescriptorSetLayout new_from_host_u64_VkDescriptorSetLayout(uint64_t underlying) {
180     return new_from_host_VkDescriptorSetLayout((VkDescriptorSetLayout)underlying);
181 }
182 
183 }  // extern "C"
184 
185 namespace gfxstream {
186 namespace vk {
187 
appendObject(struct goldfish_vk_object_list ** begin,void * val)188 void appendObject(struct goldfish_vk_object_list** begin, void* val) {
189     D("for %p", val);
190     struct goldfish_vk_object_list* o = new goldfish_vk_object_list;
191     o->next = nullptr;
192     o->obj = val;
193     D("new ptr: %p", o);
194     if (!*begin) {
195         D("first");
196         *begin = o;
197         return;
198     }
199 
200     struct goldfish_vk_object_list* q = *begin;
201     struct goldfish_vk_object_list* p = q;
202 
203     while (q) {
204         p = q;
205         q = q->next;
206     }
207 
208     D("set next of %p to %p", p, o);
209     p->next = o;
210 }
211 
eraseObject(struct goldfish_vk_object_list ** begin,void * val)212 void eraseObject(struct goldfish_vk_object_list** begin, void* val) {
213     D("for val %p", val);
214     if (!*begin) {
215         D("val %p notfound", val);
216         return;
217     }
218 
219     struct goldfish_vk_object_list* q = *begin;
220     struct goldfish_vk_object_list* p = q;
221 
222     while (q) {
223         struct goldfish_vk_object_list* n = q->next;
224         if (val == q->obj) {
225             D("val %p found, delete", val);
226             delete q;
227             if (*begin == q) {
228                 D("val %p set begin to %p:", val, n);
229                 *begin = n;
230             } else {
231                 D("val %p set pnext to %p:", val, n);
232                 p->next = n;
233             }
234             return;
235         }
236         p = q;
237         q = n;
238     }
239 
240     D("val %p notfound after looping", val);
241 }
242 
eraseObjects(struct goldfish_vk_object_list ** begin)243 void eraseObjects(struct goldfish_vk_object_list** begin) {
244     struct goldfish_vk_object_list* q = *begin;
245     struct goldfish_vk_object_list* p = q;
246 
247     while (q) {
248         p = q;
249         q = q->next;
250         delete p;
251     }
252 
253     *begin = nullptr;
254 }
255 
forAllObjects(struct goldfish_vk_object_list * begin,std::function<void (void *)> func)256 void forAllObjects(struct goldfish_vk_object_list* begin, std::function<void(void*)> func) {
257     struct goldfish_vk_object_list* q = begin;
258     struct goldfish_vk_object_list* p = q;
259 
260     D("call");
261     while (q) {
262         D("iter");
263         p = q;
264         q = q->next;
265         func(p->obj);
266     }
267 }
268 
269 }  // namespace vk
270 }  // namespace gfxstream
271