• 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 #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             ALOGE("FATAL: Failed to alloc " #type " handle"); \
37             abort(); \
38         } \
39         res->dispatch.magic = 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) { \
85         return handle; \
86     } \
87 
88 #define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL(type) \
89     type new_from_host_u64_##type(uint64_t underlying) { \
90         struct goldfish_##type* res = \
91             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
92         if (!res) { \
93             ALOGE("FATAL: Failed to alloc " #type " handle"); \
94             abort(); \
95         } \
96         res->dispatch.magic = HWVULKAN_DISPATCH_MAGIC; \
97         res->underlying = underlying; \
98         res->lastUsedEncoder = nullptr; \
99         res->sequenceNumber = 0; \
100         res->privateEncoder = 0; \
101         res->privateStream = 0; \
102         res->flags = 0; \
103         res->poolObjects = 0; \
104         res->subObjects = 0; \
105         res->superObjects = 0; \
106         res->userPtr = 0; \
107         return reinterpret_cast<type>(res); \
108     } \
109 
110 #define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL(type) \
111     type new_from_host_u64_##type(uint64_t underlying) { \
112         struct goldfish_##type* res = \
113             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
114         res->underlying = underlying; \
115         D("guest %p: host u64: 0x%llx", res, (unsigned long long)res->underlying); \
116         res->poolObjects = 0; \
117         res->subObjects = 0; \
118         res->superObjects = 0; \
119         res->userPtr = 0; \
120         return reinterpret_cast<type>(res); \
121     } \
122 
123 #define GOLDFISH_VK_GET_HOST_U64_IMPL(type) \
124     uint64_t get_host_u64_##type(type toUnwrap) { \
125         if (!toUnwrap) return 0; \
126         auto as_goldfish = as_goldfish_##type(toUnwrap); \
127         D("guest %p: host u64: 0x%llx", toUnwrap, (unsigned long long)as_goldfish->underlying); \
128         return as_goldfish->underlying; \
129     } \
130 
131 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)132 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)
133 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_IMPL)
134 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DELETE_GOLDFISH_IMPL)
135 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_IMPL)
136 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL)
137 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_IMPL)
138 
139 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)
140 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_IMPL)
141 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_IMPL)
142 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_IMPL)
143 GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL)
144 GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(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 =
173         static_cast<goldfish_VkDescriptorSetLayout*>(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 goldfish_vk {
186 
appendObject(struct goldfish_vk_object_list ** begin,void * val)187 void appendObject(struct goldfish_vk_object_list** begin, void* val) {
188     D("for %p", val);
189     struct goldfish_vk_object_list* o = new goldfish_vk_object_list;
190     o->next = nullptr;
191     o->obj = val;
192     D("new ptr: %p", o);
193     if (!*begin) { D("first"); *begin = o; return; }
194 
195     struct goldfish_vk_object_list* q = *begin;
196     struct goldfish_vk_object_list* p = q;
197 
198     while (q) {
199         p = q;
200         q = q->next;
201     }
202 
203     D("set next of %p to %p", p, o);
204     p->next = o;
205 }
206 
eraseObject(struct goldfish_vk_object_list ** begin,void * val)207 void eraseObject(struct goldfish_vk_object_list** begin, void* val) {
208         D("for val %p", val);
209     if (!*begin) {
210         D("val %p notfound", val);
211         return;
212     }
213 
214     struct goldfish_vk_object_list* q = *begin;
215     struct goldfish_vk_object_list* p = q;
216 
217     while (q) {
218         struct goldfish_vk_object_list* n = q->next;
219         if (val == q->obj) {
220             D("val %p found, delete", val);
221             delete q;
222             if (*begin == q) {
223                 D("val %p set begin to %p:", val, n);
224                 *begin = n;
225             } else {
226                 D("val %p set pnext to %p:", val, n);
227                 p->next = n;
228             }
229             return;
230         }
231         p = q;
232         q = n;
233     }
234 
235         D("val %p notfound after looping", val);
236 }
237 
eraseObjects(struct goldfish_vk_object_list ** begin)238 void eraseObjects(struct goldfish_vk_object_list** begin) {
239     struct goldfish_vk_object_list* q = *begin;
240     struct goldfish_vk_object_list* p = q;
241 
242     while (q) {
243         p = q;
244         q = q->next;
245         delete p;
246     }
247 
248     *begin = nullptr;
249 }
250 
forAllObjects(struct goldfish_vk_object_list * begin,std::function<void (void *)> func)251 void forAllObjects(struct goldfish_vk_object_list* begin, std::function<void(void*)> func) {
252     struct goldfish_vk_object_list* q = begin;
253     struct goldfish_vk_object_list* p = q;
254 
255     D("call");
256     while (q) {
257         D("iter");
258         p = q;
259         q = q->next;
260         func(p->obj);
261     }
262 }
263 
264 } // namespace goldfish_vk
265