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