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