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 <hardware/hwvulkan.h>
15
16 #include <log/log.h>
17
18 #include <errno.h>
19 #include <string.h>
20 #ifdef VK_USE_PLATFORM_FUCHSIA
21 #include <fidl/fuchsia.logger/cpp/wire.h>
22 #include <lib/syslog/global.h>
23 #include <lib/zx/channel.h>
24 #include <lib/zx/socket.h>
25 #include <lib/zxio/zxio.h>
26 #include <unistd.h>
27
28 #include "TraceProviderFuchsia.h"
29 #include "services/service_connector.h"
30 #endif
31
32 #include "HostConnection.h"
33 #include "ProcessPipe.h"
34 #include "ResourceTracker.h"
35 #include "VkEncoder.h"
36 #include "func_table.h"
37
38 // Used when there is no Vulkan support on the host.
39 // Copied from frameworks/native/vulkan/libvulkan/stubhal.cpp
40 namespace vkstubhal {
41
NoOp()42 [[noreturn]] VKAPI_ATTR void NoOp() {
43 LOG_ALWAYS_FATAL("invalid stub function called");
44 }
45
46 VkResult
EnumerateInstanceExtensionProperties(const char *,uint32_t * count,VkExtensionProperties *)47 EnumerateInstanceExtensionProperties(const char* /*layer_name*/,
48 uint32_t* count,
49 VkExtensionProperties* /*properties*/) {
50 AEMU_SCOPED_TRACE("vkstubhal::EnumerateInstanceExtensionProperties");
51 *count = 0;
52 return VK_SUCCESS;
53 }
54
55 VkResult
EnumerateInstanceLayerProperties(uint32_t * count,VkLayerProperties *)56 EnumerateInstanceLayerProperties(uint32_t* count,
57 VkLayerProperties* /*properties*/) {
58 AEMU_SCOPED_TRACE("vkstubhal::EnumerateInstanceLayerProperties");
59 *count = 0;
60 return VK_SUCCESS;
61 }
62
CreateInstance(const VkInstanceCreateInfo *,const VkAllocationCallbacks *,VkInstance * instance)63 VkResult CreateInstance(const VkInstanceCreateInfo* /*create_info*/,
64 const VkAllocationCallbacks* /*allocator*/,
65 VkInstance* instance) {
66 AEMU_SCOPED_TRACE("vkstubhal::CreateInstance");
67 auto dispatch = new hwvulkan_dispatch_t;
68 dispatch->magic = HWVULKAN_DISPATCH_MAGIC;
69 *instance = reinterpret_cast<VkInstance>(dispatch);
70 return VK_SUCCESS;
71 }
72
DestroyInstance(VkInstance instance,const VkAllocationCallbacks *)73 void DestroyInstance(VkInstance instance,
74 const VkAllocationCallbacks* /*allocator*/) {
75 AEMU_SCOPED_TRACE("vkstubhal::DestroyInstance");
76 auto dispatch = reinterpret_cast<hwvulkan_dispatch_t*>(instance);
77 ALOG_ASSERT(dispatch->magic == HWVULKAN_DISPATCH_MAGIC,
78 "DestroyInstance: invalid instance handle");
79 delete dispatch;
80 }
81
EnumeratePhysicalDevices(VkInstance,uint32_t * count,VkPhysicalDevice *)82 VkResult EnumeratePhysicalDevices(VkInstance /*instance*/,
83 uint32_t* count,
84 VkPhysicalDevice* /*gpus*/) {
85 AEMU_SCOPED_TRACE("vkstubhal::EnumeratePhysicalDevices");
86 *count = 0;
87 return VK_SUCCESS;
88 }
89
EnumerateInstanceVersion(uint32_t * pApiVersion)90 VkResult EnumerateInstanceVersion(uint32_t* pApiVersion) {
91 AEMU_SCOPED_TRACE("vkstubhal::EnumerateInstanceVersion");
92 *pApiVersion = VK_API_VERSION_1_0;
93 return VK_SUCCESS;
94 }
95
96 VkResult
EnumeratePhysicalDeviceGroups(VkInstance,uint32_t * count,VkPhysicalDeviceGroupProperties *)97 EnumeratePhysicalDeviceGroups(VkInstance /*instance*/,
98 uint32_t* count,
99 VkPhysicalDeviceGroupProperties* /*properties*/) {
100 AEMU_SCOPED_TRACE("vkstubhal::EnumeratePhysicalDeviceGroups");
101 *count = 0;
102 return VK_SUCCESS;
103 }
104
105 VkResult
CreateDebugReportCallbackEXT(VkInstance,const VkDebugReportCallbackCreateInfoEXT *,const VkAllocationCallbacks *,VkDebugReportCallbackEXT * pCallback)106 CreateDebugReportCallbackEXT(VkInstance /*instance*/,
107 const VkDebugReportCallbackCreateInfoEXT* /*pCreateInfo*/,
108 const VkAllocationCallbacks* /*pAllocator*/,
109 VkDebugReportCallbackEXT* pCallback)
110 {
111 AEMU_SCOPED_TRACE("vkstubhal::CreateDebugReportCallbackEXT");
112 *pCallback = VK_NULL_HANDLE;
113 return VK_SUCCESS;
114 }
115
116 void
DestroyDebugReportCallbackEXT(VkInstance,VkDebugReportCallbackEXT,const VkAllocationCallbacks *)117 DestroyDebugReportCallbackEXT(VkInstance /*instance*/,
118 VkDebugReportCallbackEXT /*callback*/,
119 const VkAllocationCallbacks* /*pAllocator*/)
120 {
121 AEMU_SCOPED_TRACE("vkstubhal::DestroyDebugReportCallbackEXT");
122 }
123
124 void
DebugReportMessageEXT(VkInstance,VkDebugReportFlagsEXT,VkDebugReportObjectTypeEXT,uint64_t,size_t,int32_t,const char *,const char *)125 DebugReportMessageEXT(VkInstance /*instance*/,
126 VkDebugReportFlagsEXT /*flags*/,
127 VkDebugReportObjectTypeEXT /*objectType*/,
128 uint64_t /*object*/,
129 size_t /*location*/,
130 int32_t /*messageCode*/,
131 const char* /*pLayerPrefix*/,
132 const char* /*pMessage*/)
133 {
134 AEMU_SCOPED_TRACE("vkstubhal::DebugReportMessageEXT");
135 }
136
137 VkResult
CreateDebugUtilsMessengerEXT(VkInstance,const VkDebugUtilsMessengerCreateInfoEXT *,const VkAllocationCallbacks *,VkDebugUtilsMessengerEXT * pMessenger)138 CreateDebugUtilsMessengerEXT(VkInstance /*instance*/,
139 const VkDebugUtilsMessengerCreateInfoEXT* /*pCreateInfo*/,
140 const VkAllocationCallbacks* /*pAllocator*/,
141 VkDebugUtilsMessengerEXT* pMessenger)
142 {
143 AEMU_SCOPED_TRACE("vkstubhal::CreateDebugUtilsMessengerEXT");
144 *pMessenger = VK_NULL_HANDLE;
145 return VK_SUCCESS;
146 }
147
148 void
DestroyDebugUtilsMessengerEXT(VkInstance,VkDebugUtilsMessengerEXT,const VkAllocationCallbacks *)149 DestroyDebugUtilsMessengerEXT(VkInstance /*instance*/,
150 VkDebugUtilsMessengerEXT /*messenger*/,
151 const VkAllocationCallbacks* /*pAllocator*/)
152 {
153 AEMU_SCOPED_TRACE("vkstubhal::DestroyDebugUtilsMessengerkEXT");
154 }
155
156 void
SubmitDebugUtilsMessageEXT(VkInstance,VkDebugUtilsMessageSeverityFlagBitsEXT,VkDebugUtilsMessageTypeFlagsEXT,const VkDebugUtilsMessengerCallbackDataEXT *)157 SubmitDebugUtilsMessageEXT(VkInstance /*instance*/,
158 VkDebugUtilsMessageSeverityFlagBitsEXT /*messageSeverity*/,
159 VkDebugUtilsMessageTypeFlagsEXT /*messageTypes*/,
160 const VkDebugUtilsMessengerCallbackDataEXT* /*pCallbackData*/)
161 {
162 AEMU_SCOPED_TRACE("vkstubhal::SubmitDebugUtilsMessageEXT");
163 }
164
165 #ifdef VK_USE_PLATFORM_FUCHSIA
166 VkResult
GetMemoryZirconHandleFUCHSIA(VkDevice,const VkMemoryGetZirconHandleInfoFUCHSIA *,uint32_t * pHandle)167 GetMemoryZirconHandleFUCHSIA(VkDevice /*device*/,
168 const VkMemoryGetZirconHandleInfoFUCHSIA* /*pInfo*/,
169 uint32_t* pHandle) {
170 AEMU_SCOPED_TRACE("vkstubhal::GetMemoryZirconHandleFUCHSIA");
171 *pHandle = 0;
172 return VK_SUCCESS;
173 }
174
175 VkResult
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice,VkExternalMemoryHandleTypeFlagBits,uint32_t,VkMemoryZirconHandlePropertiesFUCHSIA *)176 GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice /*device*/,
177 VkExternalMemoryHandleTypeFlagBits /*handleType*/,
178 uint32_t /*handle*/,
179 VkMemoryZirconHandlePropertiesFUCHSIA* /*pProperties*/) {
180 AEMU_SCOPED_TRACE("vkstubhal::GetMemoryZirconHandlePropertiesFUCHSIA");
181 return VK_SUCCESS;
182 }
183
184 VkResult
GetSemaphoreZirconHandleFUCHSIA(VkDevice,const VkSemaphoreGetZirconHandleInfoFUCHSIA *,uint32_t * pHandle)185 GetSemaphoreZirconHandleFUCHSIA(VkDevice /*device*/,
186 const VkSemaphoreGetZirconHandleInfoFUCHSIA* /*pInfo*/,
187 uint32_t* pHandle) {
188 AEMU_SCOPED_TRACE("vkstubhal::GetSemaphoreZirconHandleFUCHSIA");
189 *pHandle = 0;
190 return VK_SUCCESS;
191 }
192
193 VkResult
ImportSemaphoreZirconHandleFUCHSIA(VkDevice,const VkImportSemaphoreZirconHandleInfoFUCHSIA *)194 ImportSemaphoreZirconHandleFUCHSIA(VkDevice /*device*/,
195 const VkImportSemaphoreZirconHandleInfoFUCHSIA* /*pInfo*/) {
196 AEMU_SCOPED_TRACE("vkstubhal::ImportSemaphoreZirconHandleFUCHSIA");
197 return VK_SUCCESS;
198 }
199
CreateBufferCollectionFUCHSIA(VkDevice,const VkBufferCollectionCreateInfoFUCHSIA *,const VkAllocationCallbacks *,VkBufferCollectionFUCHSIA *)200 VkResult CreateBufferCollectionFUCHSIA(
201 VkDevice /*device*/,
202 const VkBufferCollectionCreateInfoFUCHSIA* /*pInfo*/,
203 const VkAllocationCallbacks* /*pAllocator*/,
204 VkBufferCollectionFUCHSIA* /*pCollection*/) {
205 AEMU_SCOPED_TRACE("vkstubhal::CreateBufferCollectionFUCHSIA");
206 return VK_SUCCESS;
207 }
208
DestroyBufferCollectionFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,const VkAllocationCallbacks *)209 void DestroyBufferCollectionFUCHSIA(
210 VkDevice /*device*/,
211 VkBufferCollectionFUCHSIA /*collection*/,
212 const VkAllocationCallbacks* /*pAllocator*/) {
213 AEMU_SCOPED_TRACE("vkstubhal::DestroyBufferCollectionFUCHSIA");
214 }
215
SetBufferCollectionImageConstraintsFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,const VkImageConstraintsInfoFUCHSIA *)216 VkResult SetBufferCollectionImageConstraintsFUCHSIA(
217 VkDevice /*device*/,
218 VkBufferCollectionFUCHSIA /*collection*/,
219 const VkImageConstraintsInfoFUCHSIA* /*pImageConstraintsInfo*/) {
220 AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionImageConstraintsFUCHSIA");
221 return VK_SUCCESS;
222 }
223
SetBufferCollectionBufferConstraintsFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,const VkBufferConstraintsInfoFUCHSIA *)224 VkResult SetBufferCollectionBufferConstraintsFUCHSIA(
225 VkDevice /*device*/,
226 VkBufferCollectionFUCHSIA /*collection*/,
227 const VkBufferConstraintsInfoFUCHSIA* /*pBufferConstraintsInfo*/) {
228 AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIA");
229 return VK_SUCCESS;
230 }
231
GetBufferCollectionPropertiesFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,VkBufferCollectionPropertiesFUCHSIA *)232 VkResult GetBufferCollectionPropertiesFUCHSIA(
233 VkDevice /*device*/,
234 VkBufferCollectionFUCHSIA /*collection*/,
235 VkBufferCollectionPropertiesFUCHSIA* /*pProperties*/) {
236 AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionPropertiesFUCHSIA");
237 return VK_SUCCESS;
238 }
239
CreateBufferCollectionFUCHSIAX(VkDevice,const VkBufferCollectionCreateInfoFUCHSIAX *,const VkAllocationCallbacks *,VkBufferCollectionFUCHSIAX *)240 VkResult CreateBufferCollectionFUCHSIAX(
241 VkDevice /*device*/,
242 const VkBufferCollectionCreateInfoFUCHSIAX* /*pInfo*/,
243 const VkAllocationCallbacks* /*pAllocator*/,
244 VkBufferCollectionFUCHSIAX* /*pCollection*/) {
245 AEMU_SCOPED_TRACE("vkstubhal::CreateBufferCollectionFUCHSIAX");
246 return VK_SUCCESS;
247 }
248
DestroyBufferCollectionFUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,const VkAllocationCallbacks *)249 void DestroyBufferCollectionFUCHSIAX(
250 VkDevice /*device*/,
251 VkBufferCollectionFUCHSIAX /*collection*/,
252 const VkAllocationCallbacks* /*pAllocator*/) {
253 AEMU_SCOPED_TRACE("vkstubhal::DestroyBufferCollectionFUCHSIAX");
254 }
255
SetBufferCollectionConstraintsFUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,const VkImageCreateInfo *)256 VkResult SetBufferCollectionConstraintsFUCHSIAX(
257 VkDevice /*device*/,
258 VkBufferCollectionFUCHSIAX /*collection*/,
259 const VkImageCreateInfo* /*pImageInfo*/) {
260 AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionConstraintsFUCHSIAX");
261 return VK_SUCCESS;
262 }
263
SetBufferCollectionImageConstraintsFUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,const VkImageConstraintsInfoFUCHSIAX *)264 VkResult SetBufferCollectionImageConstraintsFUCHSIAX(
265 VkDevice /*device*/,
266 VkBufferCollectionFUCHSIAX /*collection*/,
267 const VkImageConstraintsInfoFUCHSIAX* /*pImageConstraintsInfo*/) {
268 AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionImageConstraintsFUCHSIAX");
269 return VK_SUCCESS;
270 }
271
SetBufferCollectionBufferConstraintsFUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,const VkBufferConstraintsInfoFUCHSIAX *)272 VkResult SetBufferCollectionBufferConstraintsFUCHSIAX(
273 VkDevice /*device*/,
274 VkBufferCollectionFUCHSIAX /*collection*/,
275 const VkBufferConstraintsInfoFUCHSIAX* /*pBufferConstraintsInfo*/) {
276 AEMU_SCOPED_TRACE(
277 "vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIAX");
278 return VK_SUCCESS;
279 }
280
GetBufferCollectionPropertiesFUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,VkBufferCollectionPropertiesFUCHSIAX *)281 VkResult GetBufferCollectionPropertiesFUCHSIAX(
282 VkDevice /*device*/,
283 VkBufferCollectionFUCHSIAX /*collection*/,
284 VkBufferCollectionPropertiesFUCHSIAX* /*pProperties*/) {
285 AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionPropertiesFUCHSIAX");
286 return VK_SUCCESS;
287 }
288
GetBufferCollectionProperties2FUCHSIAX(VkDevice,VkBufferCollectionFUCHSIAX,VkBufferCollectionProperties2FUCHSIAX *)289 VkResult GetBufferCollectionProperties2FUCHSIAX(
290 VkDevice /*device*/,
291 VkBufferCollectionFUCHSIAX /*collection*/,
292 VkBufferCollectionProperties2FUCHSIAX* /*pProperties*/) {
293 AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionProperties2FUCHSIAX");
294 return VK_SUCCESS;
295 }
296 #endif
297
GetInstanceProcAddr(VkInstance instance,const char * name)298 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
299 const char* name) {
300 AEMU_SCOPED_TRACE("vkstubhal::GetInstanceProcAddr");
301 if (strcmp(name, "vkCreateInstance") == 0)
302 return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
303 if (strcmp(name, "vkDestroyInstance") == 0)
304 return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
305 if (strcmp(name, "vkEnumerateInstanceExtensionProperties") == 0)
306 return reinterpret_cast<PFN_vkVoidFunction>(
307 EnumerateInstanceExtensionProperties);
308 if (strcmp(name, "vkEnumeratePhysicalDevices") == 0)
309 return reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices);
310 if (strcmp(name, "vkEnumerateInstanceVersion") == 0)
311 return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceVersion);
312 if (strcmp(name, "vkEnumeratePhysicalDeviceGroups") == 0)
313 return reinterpret_cast<PFN_vkVoidFunction>(
314 EnumeratePhysicalDeviceGroups);
315 if (strcmp(name, "vkEnumeratePhysicalDeviceGroupsKHR") == 0)
316 return reinterpret_cast<PFN_vkVoidFunction>(
317 EnumeratePhysicalDeviceGroups);
318 if (strcmp(name, "vkGetInstanceProcAddr") == 0)
319 return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
320 if (strcmp(name, "vkCreateDebugReportCallbackEXT") == 0)
321 return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT);
322 if (strcmp(name, "vkDestroyDebugReportCallbackEXT") == 0)
323 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT);
324 if (strcmp(name, "vkDebugReportMessageEXT") == 0)
325 return reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT);
326 if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0)
327 return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
328 if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0)
329 return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
330 if (strcmp(name, "vkSubmitDebugUtilsMessageEXT") == 0)
331 return reinterpret_cast<PFN_vkVoidFunction>(SubmitDebugUtilsMessageEXT);
332 #ifdef VK_USE_PLATFORM_FUCHSIA
333 if (strcmp(name, "vkGetMemoryZirconHandleFUCHSIA") == 0)
334 return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandleFUCHSIA);
335 if (strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA") == 0)
336 return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandlePropertiesFUCHSIA);
337 if (strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA") == 0)
338 return reinterpret_cast<PFN_vkVoidFunction>(GetSemaphoreZirconHandleFUCHSIA);
339 if (strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA") == 0)
340 return reinterpret_cast<PFN_vkVoidFunction>(ImportSemaphoreZirconHandleFUCHSIA);
341 if (strcmp(name, "vkCreateBufferCollectionFUCHSIA") == 0)
342 return reinterpret_cast<PFN_vkVoidFunction>(
343 CreateBufferCollectionFUCHSIA);
344 if (strcmp(name, "vkDestroyBufferCollectionFUCHSIA") == 0)
345 return reinterpret_cast<PFN_vkVoidFunction>(
346 DestroyBufferCollectionFUCHSIA);
347 if (strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIA") == 0)
348 return reinterpret_cast<PFN_vkVoidFunction>(
349 SetBufferCollectionImageConstraintsFUCHSIA);
350 if (strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA") == 0)
351 return reinterpret_cast<PFN_vkVoidFunction>(
352 SetBufferCollectionBufferConstraintsFUCHSIA);
353 if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0)
354 return reinterpret_cast<PFN_vkVoidFunction>(
355 GetBufferCollectionPropertiesFUCHSIA);
356 if (strcmp(name, "vkCreateBufferCollectionFUCHSIAX") == 0)
357 return reinterpret_cast<PFN_vkVoidFunction>(
358 CreateBufferCollectionFUCHSIAX);
359 if (strcmp(name, "vkDestroyBufferCollectionFUCHSIAX") == 0)
360 return reinterpret_cast<PFN_vkVoidFunction>(
361 DestroyBufferCollectionFUCHSIAX);
362 if (strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIAX") == 0)
363 return reinterpret_cast<PFN_vkVoidFunction>(
364 SetBufferCollectionConstraintsFUCHSIAX);
365 if (strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIAX") == 0)
366 return reinterpret_cast<PFN_vkVoidFunction>(
367 SetBufferCollectionImageConstraintsFUCHSIAX);
368 if (strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIAX") == 0)
369 return reinterpret_cast<PFN_vkVoidFunction>(
370 SetBufferCollectionBufferConstraintsFUCHSIAX);
371 if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIAX") == 0)
372 return reinterpret_cast<PFN_vkVoidFunction>(
373 GetBufferCollectionPropertiesFUCHSIAX);
374 if (strcmp(name, "vkGetBufferCollectionProperties2FUCHSIAX") == 0)
375 return reinterpret_cast<PFN_vkVoidFunction>(
376 GetBufferCollectionProperties2FUCHSIAX);
377 #endif
378 // Return NoOp for entrypoints that should never be called.
379 if (strcmp(name, "vkGetPhysicalDeviceFeatures") == 0 ||
380 strcmp(name, "vkGetPhysicalDeviceProperties") == 0 ||
381 strcmp(name, "vkGetPhysicalDeviceFormatProperties") == 0 ||
382 strcmp(name, "vkGetPhysicalDeviceImageFormatProperties") == 0 ||
383 strcmp(name, "vkGetPhysicalDeviceMemoryProperties") == 0 ||
384 strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties") == 0 ||
385 strcmp(name, "vkGetDeviceProcAddr") == 0 ||
386 strcmp(name, "vkCreateDevice") == 0 ||
387 strcmp(name, "vkEnumerateDeviceExtensionProperties") == 0 ||
388 strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties") == 0 ||
389 strcmp(name, "vkGetPhysicalDeviceFeatures2") == 0 ||
390 strcmp(name, "vkGetPhysicalDeviceProperties2") == 0 ||
391 strcmp(name, "vkGetPhysicalDeviceFormatProperties2") == 0 ||
392 strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2") == 0 ||
393 strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2") == 0 ||
394 strcmp(name, "vkGetPhysicalDeviceMemoryProperties2") == 0 ||
395 strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2") == 0 ||
396 strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties") == 0 ||
397 strcmp(name, "vkGetPhysicalDeviceExternalFenceProperties") == 0 ||
398 strcmp(name, "vkGetPhysicalDeviceExternalSemaphoreProperties") == 0)
399 return reinterpret_cast<PFN_vkVoidFunction>(NoOp);
400
401 // Per the spec, return NULL for nonexistent entrypoints.
402 return nullptr;
403 }
404
405 } // namespace vkstubhal
406
407 namespace {
408
409 #ifdef VK_USE_PLATFORM_ANDROID_KHR
410
411 int OpenDevice(const hw_module_t* module, const char* id, hw_device_t** device);
412
413 hw_module_methods_t goldfish_vulkan_module_methods = {
414 .open = OpenDevice
415 };
416
417 extern "C" __attribute__((visibility("default"))) hwvulkan_module_t HAL_MODULE_INFO_SYM = {
418 .common = {
419 .tag = HARDWARE_MODULE_TAG,
420 .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
421 .hal_api_version = HARDWARE_HAL_API_VERSION,
422 .id = HWVULKAN_HARDWARE_MODULE_ID,
423 .name = "Goldfish Vulkan Driver",
424 .author = "The Android Open Source Project",
425 .methods = &goldfish_vulkan_module_methods,
426 },
427 };
428
CloseDevice(struct hw_device_t *)429 int CloseDevice(struct hw_device_t* /*device*/) {
430 AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
431 // nothing to do - opening a device doesn't allocate any resources
432 return 0;
433 }
434
435 #endif
436
437 #define VK_HOST_CONNECTION(ret) \
438 HostConnection *hostCon = HostConnection::getOrCreate(VIRTIO_GPU_CAPSET_GFXSTREAM); \
439 if (!hostCon) { \
440 ALOGE("vulkan: Failed to get host connection\n"); \
441 return ret; \
442 } \
443 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
444 if (!rcEnc) { \
445 ALOGE("vulkan: Failed to get renderControl encoder context\n"); \
446 return ret; \
447 } \
448 goldfish_vk::ResourceTracker::ThreadingCallbacks threadingCallbacks = { \
449 [] { \
450 auto hostCon = HostConnection::get(); \
451 hostCon->rcEncoder(); \
452 return hostCon; \
453 }, \
454 [](HostConnection* hostCon) { return hostCon->vkEncoder(); }, \
455 }; \
456 goldfish_vk::ResourceTracker::get()->setThreadingCallbacks(threadingCallbacks); \
457 goldfish_vk::ResourceTracker::get()->setupFeatures(rcEnc->featureInfo_const()); \
458 goldfish_vk::ResourceTracker::get()->setSeqnoPtr(getSeqnoPtrForProcess()); \
459 auto hostSupportsVulkan = goldfish_vk::ResourceTracker::get()->hostSupportsVulkan(); \
460 goldfish_vk::VkEncoder *vkEnc = hostCon->vkEncoder(); \
461 if (!vkEnc) { \
462 ALOGE("vulkan: Failed to get Vulkan encoder\n"); \
463 return ret; \
464 } \
465
466 VKAPI_ATTR
EnumerateInstanceExtensionProperties(const char * layer_name,uint32_t * count,VkExtensionProperties * properties)467 VkResult EnumerateInstanceExtensionProperties(
468 const char* layer_name,
469 uint32_t* count,
470 VkExtensionProperties* properties) {
471 AEMU_SCOPED_TRACE("goldfish_vulkan::EnumerateInstanceExtensionProperties");
472
473 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
474
475 if (!hostSupportsVulkan) {
476 return vkstubhal::EnumerateInstanceExtensionProperties(layer_name, count, properties);
477 }
478
479 if (layer_name) {
480 ALOGW(
481 "Driver vkEnumerateInstanceExtensionProperties shouldn't be called "
482 "with a layer name ('%s')",
483 layer_name);
484 }
485
486 VkResult res = goldfish_vk::ResourceTracker::get()->on_vkEnumerateInstanceExtensionProperties(
487 vkEnc, VK_SUCCESS, layer_name, count, properties);
488
489 return res;
490 }
491
492 VKAPI_ATTR
CreateInstance(const VkInstanceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkInstance * out_instance)493 VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
494 const VkAllocationCallbacks* allocator,
495 VkInstance* out_instance) {
496 AEMU_SCOPED_TRACE("goldfish_vulkan::CreateInstance");
497
498 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
499
500 if (!hostSupportsVulkan) {
501 return vkstubhal::CreateInstance(create_info, allocator, out_instance);
502 }
503
504 VkResult res = vkEnc->vkCreateInstance(create_info, nullptr, out_instance, true /* do lock */);
505
506 return res;
507 }
508
509 #ifdef VK_USE_PLATFORM_FUCHSIA
510 VKAPI_ATTR
GetMemoryZirconHandleFUCHSIA(VkDevice device,const VkMemoryGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)511 VkResult GetMemoryZirconHandleFUCHSIA(
512 VkDevice device,
513 const VkMemoryGetZirconHandleInfoFUCHSIA* pInfo,
514 uint32_t* pHandle) {
515 AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandleFUCHSIA");
516
517 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
518
519 if (!hostSupportsVulkan) {
520 return vkstubhal::GetMemoryZirconHandleFUCHSIA(device, pInfo, pHandle);
521 }
522
523 VkResult res = goldfish_vk::ResourceTracker::get()->
524 on_vkGetMemoryZirconHandleFUCHSIA(
525 vkEnc, VK_SUCCESS,
526 device, pInfo, pHandle);
527
528 return res;
529 }
530
531 VKAPI_ATTR
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice device,VkExternalMemoryHandleTypeFlagBits handleType,uint32_t handle,VkMemoryZirconHandlePropertiesFUCHSIA * pProperties)532 VkResult GetMemoryZirconHandlePropertiesFUCHSIA(
533 VkDevice device,
534 VkExternalMemoryHandleTypeFlagBits handleType,
535 uint32_t handle,
536 VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
537 AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandlePropertiesFUCHSIA");
538
539 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
540
541 if (!hostSupportsVulkan) {
542 return vkstubhal::GetMemoryZirconHandlePropertiesFUCHSIA(
543 device, handleType, handle, pProperties);
544 }
545
546 VkResult res = goldfish_vk::ResourceTracker::get()->
547 on_vkGetMemoryZirconHandlePropertiesFUCHSIA(
548 vkEnc, VK_SUCCESS, device, handleType, handle, pProperties);
549
550 return res;
551 }
552
553 VKAPI_ATTR
GetSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkSemaphoreGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)554 VkResult GetSemaphoreZirconHandleFUCHSIA(
555 VkDevice device,
556 const VkSemaphoreGetZirconHandleInfoFUCHSIA* pInfo,
557 uint32_t* pHandle) {
558 AEMU_SCOPED_TRACE("goldfish_vulkan::GetSemaphoreZirconHandleFUCHSIA");
559
560 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
561
562 if (!hostSupportsVulkan) {
563 return vkstubhal::GetSemaphoreZirconHandleFUCHSIA(device, pInfo, pHandle);
564 }
565
566 VkResult res = goldfish_vk::ResourceTracker::get()->
567 on_vkGetSemaphoreZirconHandleFUCHSIA(
568 vkEnc, VK_SUCCESS, device, pInfo, pHandle);
569
570 return res;
571 }
572
573 VKAPI_ATTR
ImportSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkImportSemaphoreZirconHandleInfoFUCHSIA * pInfo)574 VkResult ImportSemaphoreZirconHandleFUCHSIA(
575 VkDevice device,
576 const VkImportSemaphoreZirconHandleInfoFUCHSIA* pInfo) {
577 AEMU_SCOPED_TRACE("goldfish_vulkan::ImportSemaphoreZirconHandleFUCHSIA");
578
579 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
580
581 if (!hostSupportsVulkan) {
582 return vkstubhal::ImportSemaphoreZirconHandleFUCHSIA(device, pInfo);
583 }
584
585 VkResult res = goldfish_vk::ResourceTracker::get()->
586 on_vkImportSemaphoreZirconHandleFUCHSIA(
587 vkEnc, VK_SUCCESS, device, pInfo);
588
589 return res;
590 }
591
592 VKAPI_ATTR
CreateBufferCollectionFUCHSIA(VkDevice device,const VkBufferCollectionCreateInfoFUCHSIA * pInfo,const VkAllocationCallbacks * pAllocator,VkBufferCollectionFUCHSIA * pCollection)593 VkResult CreateBufferCollectionFUCHSIA(
594 VkDevice device,
595 const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
596 const VkAllocationCallbacks* pAllocator,
597 VkBufferCollectionFUCHSIA* pCollection) {
598 AEMU_SCOPED_TRACE("goldfish_vulkan::CreateBufferCollectionFUCHSIA");
599
600 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
601
602 if (!hostSupportsVulkan) {
603 return vkstubhal::CreateBufferCollectionFUCHSIA(
604 device, pInfo, pAllocator, pCollection);
605 }
606
607 VkResult res =
608 goldfish_vk::ResourceTracker::get()->on_vkCreateBufferCollectionFUCHSIA(
609 vkEnc, VK_SUCCESS, device, pInfo, pAllocator, pCollection);
610
611 return res;
612 }
613
614 VKAPI_ATTR
DestroyBufferCollectionFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkAllocationCallbacks * pAllocator)615 void DestroyBufferCollectionFUCHSIA(VkDevice device,
616 VkBufferCollectionFUCHSIA collection,
617 const VkAllocationCallbacks* pAllocator) {
618 AEMU_SCOPED_TRACE("goldfish_vulkan::DestroyBufferCollectionFUCHSIA");
619
620 VK_HOST_CONNECTION()
621
622 if (!hostSupportsVulkan) {
623 vkstubhal::DestroyBufferCollectionFUCHSIA(device, collection,
624 pAllocator);
625 return;
626 }
627
628 goldfish_vk::ResourceTracker::get()->on_vkDestroyBufferCollectionFUCHSIA(
629 vkEnc, VK_SUCCESS, device, collection, pAllocator);
630 }
631
632 VKAPI_ATTR
SetBufferCollectionBufferConstraintsFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkBufferConstraintsInfoFUCHSIA * pBufferConstraintsInfo)633 VkResult SetBufferCollectionBufferConstraintsFUCHSIA(
634 VkDevice device,
635 VkBufferCollectionFUCHSIA collection,
636 const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
637 AEMU_SCOPED_TRACE(
638 "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIA");
639
640 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
641
642 if (!hostSupportsVulkan) {
643 return vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIA(
644 device, collection, pBufferConstraintsInfo);
645 }
646
647 VkResult res =
648 goldfish_vk::ResourceTracker::get()
649 ->on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
650 vkEnc, VK_SUCCESS, device, collection, pBufferConstraintsInfo);
651
652 return res;
653 }
654
655 VKAPI_ATTR
SetBufferCollectionImageConstraintsFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkImageConstraintsInfoFUCHSIA * pImageConstraintsInfo)656 VkResult SetBufferCollectionImageConstraintsFUCHSIA(
657 VkDevice device,
658 VkBufferCollectionFUCHSIA collection,
659 const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
660 AEMU_SCOPED_TRACE(
661 "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIA");
662
663 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
664
665 if (!hostSupportsVulkan) {
666 return vkstubhal::SetBufferCollectionImageConstraintsFUCHSIA(
667 device, collection, pImageConstraintsInfo);
668 }
669
670 VkResult res =
671 goldfish_vk::ResourceTracker::get()
672 ->on_vkSetBufferCollectionImageConstraintsFUCHSIA(
673 vkEnc, VK_SUCCESS, device, collection, pImageConstraintsInfo);
674
675 return res;
676 }
677
678 VKAPI_ATTR
GetBufferCollectionPropertiesFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,VkBufferCollectionPropertiesFUCHSIA * pProperties)679 VkResult GetBufferCollectionPropertiesFUCHSIA(
680 VkDevice device,
681 VkBufferCollectionFUCHSIA collection,
682 VkBufferCollectionPropertiesFUCHSIA* pProperties) {
683 AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIA");
684
685 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
686
687 if (!hostSupportsVulkan) {
688 return vkstubhal::GetBufferCollectionPropertiesFUCHSIA(
689 device, collection, pProperties);
690 }
691
692 VkResult res = goldfish_vk::ResourceTracker::get()
693 ->on_vkGetBufferCollectionPropertiesFUCHSIA(
694 vkEnc, VK_SUCCESS, device, collection, pProperties);
695
696 return res;
697 }
698
699 VKAPI_ATTR
CreateBufferCollectionFUCHSIAX(VkDevice device,const VkBufferCollectionCreateInfoFUCHSIAX * pInfo,const VkAllocationCallbacks * pAllocator,VkBufferCollectionFUCHSIAX * pCollection)700 VkResult CreateBufferCollectionFUCHSIAX(
701 VkDevice device,
702 const VkBufferCollectionCreateInfoFUCHSIAX* pInfo,
703 const VkAllocationCallbacks* pAllocator,
704 VkBufferCollectionFUCHSIAX* pCollection) {
705 AEMU_SCOPED_TRACE("goldfish_vulkan::CreateBufferCollectionFUCHSIAX");
706
707 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
708
709 if (!hostSupportsVulkan) {
710 return vkstubhal::CreateBufferCollectionFUCHSIAX(
711 device, pInfo, pAllocator, pCollection);
712 }
713
714 VkResult res =
715 goldfish_vk::ResourceTracker::get()
716 ->on_vkCreateBufferCollectionFUCHSIAX(
717 vkEnc, VK_SUCCESS, device, pInfo, pAllocator, pCollection);
718
719 return res;
720 }
721
722 VKAPI_ATTR
DestroyBufferCollectionFUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,const VkAllocationCallbacks * pAllocator)723 void DestroyBufferCollectionFUCHSIAX(VkDevice device,
724 VkBufferCollectionFUCHSIAX collection,
725 const VkAllocationCallbacks* pAllocator) {
726 AEMU_SCOPED_TRACE("goldfish_vulkan::DestroyBufferCollectionFUCHSIAX");
727
728 VK_HOST_CONNECTION()
729
730 if (!hostSupportsVulkan) {
731 vkstubhal::DestroyBufferCollectionFUCHSIAX(device, collection,
732 pAllocator);
733 return;
734 }
735
736 goldfish_vk::ResourceTracker::get()->on_vkDestroyBufferCollectionFUCHSIAX(
737 vkEnc, VK_SUCCESS, device, collection, pAllocator);
738 }
739
740 VKAPI_ATTR
SetBufferCollectionConstraintsFUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,const VkImageCreateInfo * pImageInfo)741 VkResult SetBufferCollectionConstraintsFUCHSIAX(
742 VkDevice device,
743 VkBufferCollectionFUCHSIAX collection,
744 const VkImageCreateInfo* pImageInfo) {
745 AEMU_SCOPED_TRACE(
746 "goldfish_vulkan::SetBufferCollectionConstraintsFUCHSIAX");
747
748 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
749
750 if (!hostSupportsVulkan) {
751 return vkstubhal::SetBufferCollectionConstraintsFUCHSIAX(
752 device, collection, pImageInfo);
753 }
754
755 VkResult res = goldfish_vk::ResourceTracker::get()
756 ->on_vkSetBufferCollectionConstraintsFUCHSIAX(
757 vkEnc, VK_SUCCESS, device, collection, pImageInfo);
758
759 return res;
760 }
761
762 VKAPI_ATTR
SetBufferCollectionBufferConstraintsFUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,const VkBufferConstraintsInfoFUCHSIAX * pBufferConstraintsInfo)763 VkResult SetBufferCollectionBufferConstraintsFUCHSIAX(
764 VkDevice device,
765 VkBufferCollectionFUCHSIAX collection,
766 const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
767 AEMU_SCOPED_TRACE(
768 "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIAX");
769
770 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
771
772 if (!hostSupportsVulkan) {
773 return vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIAX(
774 device, collection, pBufferConstraintsInfo);
775 }
776
777 VkResult res =
778 goldfish_vk::ResourceTracker::get()
779 ->on_vkSetBufferCollectionBufferConstraintsFUCHSIAX(
780 vkEnc, VK_SUCCESS, device, collection, pBufferConstraintsInfo);
781
782 return res;
783 }
784
785 VKAPI_ATTR
SetBufferCollectionImageConstraintsFUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,const VkImageConstraintsInfoFUCHSIAX * pImageConstraintsInfo)786 VkResult SetBufferCollectionImageConstraintsFUCHSIAX(
787 VkDevice device,
788 VkBufferCollectionFUCHSIAX collection,
789 const VkImageConstraintsInfoFUCHSIAX* pImageConstraintsInfo) {
790 AEMU_SCOPED_TRACE(
791 "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIAX");
792
793 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
794
795 if (!hostSupportsVulkan) {
796 return vkstubhal::SetBufferCollectionImageConstraintsFUCHSIAX(
797 device, collection, pImageConstraintsInfo);
798 }
799
800 VkResult res =
801 goldfish_vk::ResourceTracker::get()
802 ->on_vkSetBufferCollectionImageConstraintsFUCHSIAX(
803 vkEnc, VK_SUCCESS, device, collection, pImageConstraintsInfo);
804
805 return res;
806 }
807
808 VKAPI_ATTR
GetBufferCollectionPropertiesFUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,VkBufferCollectionPropertiesFUCHSIAX * pProperties)809 VkResult GetBufferCollectionPropertiesFUCHSIAX(
810 VkDevice device,
811 VkBufferCollectionFUCHSIAX collection,
812 VkBufferCollectionPropertiesFUCHSIAX* pProperties) {
813 AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIAX");
814
815 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
816
817 if (!hostSupportsVulkan) {
818 return vkstubhal::GetBufferCollectionPropertiesFUCHSIAX(
819 device, collection, pProperties);
820 }
821
822 VkResult res = goldfish_vk::ResourceTracker::get()
823 ->on_vkGetBufferCollectionPropertiesFUCHSIAX(
824 vkEnc, VK_SUCCESS, device, collection, pProperties);
825
826 return res;
827 }
828
829 VKAPI_ATTR
GetBufferCollectionProperties2FUCHSIAX(VkDevice device,VkBufferCollectionFUCHSIAX collection,VkBufferCollectionProperties2FUCHSIAX * pProperties)830 VkResult GetBufferCollectionProperties2FUCHSIAX(
831 VkDevice device,
832 VkBufferCollectionFUCHSIAX collection,
833 VkBufferCollectionProperties2FUCHSIAX* pProperties) {
834 AEMU_SCOPED_TRACE(
835 "goldfish_vulkan::GetBufferCollectionProperties2FUCHSIAX");
836
837 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
838
839 if (!hostSupportsVulkan) {
840 return vkstubhal::GetBufferCollectionProperties2FUCHSIAX(
841 device, collection, pProperties);
842 }
843
844 VkResult res = goldfish_vk::ResourceTracker::get()
845 ->on_vkGetBufferCollectionProperties2FUCHSIAX(
846 vkEnc, VK_SUCCESS, device, collection, pProperties);
847
848 return res;
849 }
850 #endif
851
currGuestTimeNs()852 uint64_t currGuestTimeNs() {
853 struct timespec ts;
854 #ifdef __APPLE__
855 clock_gettime(CLOCK_REALTIME, &ts);
856 #else
857 clock_gettime(CLOCK_BOOTTIME, &ts);
858 #endif
859 uint64_t res = (uint64_t)(ts.tv_sec * 1000000000ULL + ts.tv_nsec);
860 return res;
861 }
862
863 struct FrameTracingState {
864 uint32_t frameNumber = 0;
865 bool tracingEnabled = false;
onSwapBuffersSuccessful__anon446723ec0111::FrameTracingState866 void onSwapBuffersSuccessful(ExtendedRCEncoderContext* rcEnc) {
867 #ifdef GFXSTREAM
868 bool current = android::base::isTracingEnabled();
869 // edge trigger
870 if (current && !tracingEnabled) {
871 if (rcEnc->hasHostSideTracing()) {
872 rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 1, currGuestTimeNs());
873 }
874 }
875 if (!current && tracingEnabled) {
876 if (rcEnc->hasHostSideTracing()) {
877 rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 0, currGuestTimeNs());
878 }
879 }
880 tracingEnabled = current;
881 #endif
882 ++frameNumber;
883 }
884 };
885
886 static FrameTracingState sFrameTracingState;
887
888 static PFN_vkVoidFunction sQueueSignalReleaseImageAndroidImpl = 0;
889
890 static VkResult
QueueSignalReleaseImageANDROID(VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)891 QueueSignalReleaseImageANDROID(
892 VkQueue queue,
893 uint32_t waitSemaphoreCount,
894 const VkSemaphore* pWaitSemaphores,
895 VkImage image,
896 int* pNativeFenceFd)
897 {
898 sFrameTracingState.onSwapBuffersSuccessful(HostConnection::get()->rcEncoder());
899 ((PFN_vkQueueSignalReleaseImageANDROID)sQueueSignalReleaseImageAndroidImpl)(queue, waitSemaphoreCount, pWaitSemaphores, image, pNativeFenceFd);
900 return VK_SUCCESS;
901 }
902
GetDeviceProcAddr(VkDevice device,const char * name)903 static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
904 AEMU_SCOPED_TRACE("goldfish_vulkan::GetDeviceProcAddr");
905
906 VK_HOST_CONNECTION(nullptr)
907
908 if (!hostSupportsVulkan) {
909 return nullptr;
910 }
911
912 #ifdef VK_USE_PLATFORM_FUCHSIA
913 if (!strcmp(name, "vkGetMemoryZirconHandleFUCHSIA")) {
914 return (PFN_vkVoidFunction)GetMemoryZirconHandleFUCHSIA;
915 }
916 if (!strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA")) {
917 return (PFN_vkVoidFunction)GetMemoryZirconHandlePropertiesFUCHSIA;
918 }
919 if (!strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA")) {
920 return (PFN_vkVoidFunction)GetSemaphoreZirconHandleFUCHSIA;
921 }
922 if (!strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA")) {
923 return (PFN_vkVoidFunction)ImportSemaphoreZirconHandleFUCHSIA;
924 }
925 if (!strcmp(name, "vkCreateBufferCollectionFUCHSIA")) {
926 return (PFN_vkVoidFunction)CreateBufferCollectionFUCHSIA;
927 }
928 if (!strcmp(name, "vkDestroyBufferCollectionFUCHSIA")) {
929 return (PFN_vkVoidFunction)DestroyBufferCollectionFUCHSIA;
930 }
931 if (!strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIA")) {
932 return (PFN_vkVoidFunction)SetBufferCollectionImageConstraintsFUCHSIA;
933 }
934 if (!strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA")) {
935 return (PFN_vkVoidFunction)SetBufferCollectionBufferConstraintsFUCHSIA;
936 }
937 if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) {
938 return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA;
939 }
940 if (!strcmp(name, "vkCreateBufferCollectionFUCHSIAX")) {
941 return (PFN_vkVoidFunction)CreateBufferCollectionFUCHSIAX;
942 }
943 if (!strcmp(name, "vkDestroyBufferCollectionFUCHSIAX")) {
944 return (PFN_vkVoidFunction)DestroyBufferCollectionFUCHSIAX;
945 }
946 if (!strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIAX")) {
947 return (PFN_vkVoidFunction)SetBufferCollectionConstraintsFUCHSIAX;
948 }
949 if (!strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIAX")) {
950 return (PFN_vkVoidFunction)SetBufferCollectionImageConstraintsFUCHSIAX;
951 }
952 if (!strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIAX")) {
953 return (PFN_vkVoidFunction)SetBufferCollectionBufferConstraintsFUCHSIAX;
954 }
955 if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIAX")) {
956 return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIAX;
957 }
958 if (!strcmp(name, "vkGetBufferCollectionProperties2FUCHSIAX")) {
959 return (PFN_vkVoidFunction)GetBufferCollectionProperties2FUCHSIAX;
960 }
961 #endif
962 if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
963 if (!sQueueSignalReleaseImageAndroidImpl) {
964 sQueueSignalReleaseImageAndroidImpl =
965 (PFN_vkVoidFunction)(
966 goldfish_vk::goldfish_vulkan_get_device_proc_address(device, "vkQueueSignalReleaseImageANDROID"));
967 }
968 return (PFN_vkVoidFunction)QueueSignalReleaseImageANDROID;
969 }
970 if (!strcmp(name, "vkGetDeviceProcAddr")) {
971 return (PFN_vkVoidFunction)(GetDeviceProcAddr);
972 }
973 return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_device_proc_address(device, name));
974 }
975
976 VKAPI_ATTR
GetInstanceProcAddr(VkInstance instance,const char * name)977 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
978 AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
979
980 VK_HOST_CONNECTION(nullptr)
981
982 if (!hostSupportsVulkan) {
983 return vkstubhal::GetInstanceProcAddr(instance, name);
984 }
985
986 if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
987 return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
988 }
989 if (!strcmp(name, "vkCreateInstance")) {
990 return (PFN_vkVoidFunction)CreateInstance;
991 }
992 if (!strcmp(name, "vkGetDeviceProcAddr")) {
993 return (PFN_vkVoidFunction)(GetDeviceProcAddr);
994 }
995 if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
996 if (!sQueueSignalReleaseImageAndroidImpl) {
997 sQueueSignalReleaseImageAndroidImpl =
998 (PFN_vkVoidFunction)(
999 goldfish_vk::goldfish_vulkan_get_instance_proc_address(instance, "vkQueueSignalReleaseImageANDROID"));
1000 }
1001 return (PFN_vkVoidFunction)QueueSignalReleaseImageANDROID;
1002 }
1003 return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_instance_proc_address(instance, name));
1004 }
1005
1006 #ifdef VK_USE_PLATFORM_ANDROID_KHR
1007
1008 hwvulkan_device_t goldfish_vulkan_device = {
1009 .common = {
1010 .tag = HARDWARE_DEVICE_TAG,
1011 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
1012 .module = &HAL_MODULE_INFO_SYM.common,
1013 .close = CloseDevice,
1014 },
1015 .EnumerateInstanceExtensionProperties = EnumerateInstanceExtensionProperties,
1016 .CreateInstance = CreateInstance,
1017 .GetInstanceProcAddr = GetInstanceProcAddr,
1018 };
1019
OpenDevice(const hw_module_t *,const char * id,hw_device_t ** device)1020 int OpenDevice(const hw_module_t* /*module*/,
1021 const char* id,
1022 hw_device_t** device) {
1023 AEMU_SCOPED_TRACE("goldfish_vulkan::OpenDevice");
1024
1025 if (strcmp(id, HWVULKAN_DEVICE_0) == 0) {
1026 *device = &goldfish_vulkan_device.common;
1027 goldfish_vk::ResourceTracker::get();
1028 return 0;
1029 }
1030 return -ENOENT;
1031 }
1032
1033 #elif VK_USE_PLATFORM_FUCHSIA
1034
1035 class VulkanDevice {
1036 public:
VulkanDevice()1037 VulkanDevice() : mHostSupportsGoldfish(IsAccessible(QEMU_PIPE_PATH)) {
1038 InitLogger();
1039 InitTraceProvider();
1040 goldfish_vk::ResourceTracker::get();
1041 }
1042
1043 static void InitLogger();
1044
IsAccessible(const char * name)1045 static bool IsAccessible(const char* name) {
1046 zx_handle_t handle = GetConnectToServiceFunction()(name);
1047 if (handle == ZX_HANDLE_INVALID)
1048 return false;
1049
1050 zxio_storage_t io_storage;
1051 zx_status_t status = zxio_create(handle, &io_storage);
1052 if (status != ZX_OK)
1053 return false;
1054
1055 status = zxio_close(&io_storage.io);
1056 if (status != ZX_OK)
1057 return false;
1058
1059 return true;
1060 }
1061
GetInstance()1062 static VulkanDevice& GetInstance() {
1063 static VulkanDevice g_instance;
1064 return g_instance;
1065 }
1066
GetInstanceProcAddr(VkInstance instance,const char * name)1067 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
1068 if (!mHostSupportsGoldfish) {
1069 return vkstubhal::GetInstanceProcAddr(instance, name);
1070 }
1071 return ::GetInstanceProcAddr(instance, name);
1072 }
1073
1074 private:
1075 void InitTraceProvider();
1076
1077 TraceProviderFuchsia mTraceProvider;
1078 const bool mHostSupportsGoldfish;
1079 };
1080
InitLogger()1081 void VulkanDevice::InitLogger() {
1082 auto log_service = ([] () -> std::optional<zx::socket> {
1083 fidl::ClientEnd<fuchsia_logger::LogSink> channel{zx::channel{
1084 GetConnectToServiceFunction()("/svc/fuchsia.logger.LogSink")}};
1085 if (!channel.is_valid())
1086 return std::nullopt;
1087
1088 zx::socket local_socket, remote_socket;
1089 zx_status_t status = zx::socket::create(ZX_SOCKET_DATAGRAM, &local_socket, &remote_socket);
1090 if (status != ZX_OK)
1091 return std::nullopt;
1092
1093 auto result = fidl::WireCall(channel)->Connect(std::move(remote_socket));
1094
1095 if (!result.ok())
1096 return std::nullopt;
1097
1098 return local_socket;
1099 })();
1100 if (!log_service)
1101 return;
1102
1103 fx_logger_config_t config = {.min_severity = FX_LOG_INFO,
1104 .console_fd = -1,
1105 .log_service_channel = log_service->release(),
1106 .tags = nullptr,
1107 .num_tags = 0};
1108
1109 fx_log_reconfigure(&config);
1110 }
1111
InitTraceProvider()1112 void VulkanDevice::InitTraceProvider() {
1113 if (!mTraceProvider.Initialize()) {
1114 ALOGE("Trace provider failed to initialize");
1115 }
1116 }
1117
1118 extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance,const char * name)1119 vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
1120 return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
1121 }
1122
1123 extern "C" __attribute__((visibility("default"))) VkResult
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)1124 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1125 *pSupportedVersion = std::min(*pSupportedVersion, 3u);
1126 return VK_SUCCESS;
1127 }
1128
1129 typedef VkResult(VKAPI_PTR *PFN_vkOpenInNamespaceAddr)(const char *pName, uint32_t handle);
1130
1131 namespace {
1132
1133 PFN_vkOpenInNamespaceAddr g_vulkan_connector;
1134
LocalConnectToServiceFunction(const char * pName)1135 zx_handle_t LocalConnectToServiceFunction(const char* pName) {
1136 zx::channel remote_endpoint, local_endpoint;
1137 zx_status_t status;
1138 if ((status = zx::channel::create(0, &remote_endpoint, &local_endpoint)) != ZX_OK) {
1139 ALOGE("zx::channel::create failed: %d", status);
1140 return ZX_HANDLE_INVALID;
1141 }
1142 if ((status = g_vulkan_connector(pName, remote_endpoint.release())) != ZX_OK) {
1143 ALOGE("vulkan_connector failed: %d", status);
1144 return ZX_HANDLE_INVALID;
1145 }
1146 return local_endpoint.release();
1147 }
1148
1149 }
1150
1151 extern "C" __attribute__((visibility("default"))) void
vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr callback)1152 vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr callback) {
1153 g_vulkan_connector = callback;
1154 SetConnectToServiceFunction(&LocalConnectToServiceFunction);
1155 }
1156
1157 #else
1158 class VulkanDevice {
1159 public:
VulkanDevice()1160 VulkanDevice() {
1161 goldfish_vk::ResourceTracker::get();
1162 }
1163
GetInstance()1164 static VulkanDevice& GetInstance() {
1165 static VulkanDevice g_instance;
1166 return g_instance;
1167 }
1168
GetInstanceProcAddr(VkInstance instance,const char * name)1169 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
1170 return ::GetInstanceProcAddr(instance, name);
1171 }
1172 };
1173
1174 extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance,const char * name)1175 vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
1176 return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
1177 }
1178
1179 extern "C" __attribute__((visibility("default"))) VkResult
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)1180 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1181 *pSupportedVersion = std::min(*pSupportedVersion, 3u);
1182 return VK_SUCCESS;
1183 }
1184
1185 #endif
1186
1187 } // namespace
1188