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