• 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 <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 #endif
240 
GetInstanceProcAddr(VkInstance instance,const char * name)241 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
242                                        const char* name) {
243     AEMU_SCOPED_TRACE("vkstubhal::GetInstanceProcAddr");
244     if (strcmp(name, "vkCreateInstance") == 0)
245         return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
246     if (strcmp(name, "vkDestroyInstance") == 0)
247         return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
248     if (strcmp(name, "vkEnumerateInstanceExtensionProperties") == 0)
249         return reinterpret_cast<PFN_vkVoidFunction>(
250             EnumerateInstanceExtensionProperties);
251     if (strcmp(name, "vkEnumeratePhysicalDevices") == 0)
252         return reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices);
253     if (strcmp(name, "vkEnumerateInstanceVersion") == 0)
254         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceVersion);
255     if (strcmp(name, "vkEnumeratePhysicalDeviceGroups") == 0)
256         return reinterpret_cast<PFN_vkVoidFunction>(
257             EnumeratePhysicalDeviceGroups);
258     if (strcmp(name, "vkEnumeratePhysicalDeviceGroupsKHR") == 0)
259         return reinterpret_cast<PFN_vkVoidFunction>(
260             EnumeratePhysicalDeviceGroups);
261     if (strcmp(name, "vkGetInstanceProcAddr") == 0)
262         return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
263     if (strcmp(name, "vkCreateDebugReportCallbackEXT") == 0)
264         return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT);
265     if (strcmp(name, "vkDestroyDebugReportCallbackEXT") == 0)
266         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT);
267     if (strcmp(name, "vkDebugReportMessageEXT") == 0)
268         return reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT);
269     if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0)
270         return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
271     if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0)
272         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
273     if (strcmp(name, "vkSubmitDebugUtilsMessageEXT") == 0)
274         return reinterpret_cast<PFN_vkVoidFunction>(SubmitDebugUtilsMessageEXT);
275 #ifdef VK_USE_PLATFORM_FUCHSIA
276     if (strcmp(name, "vkGetMemoryZirconHandleFUCHSIA") == 0)
277         return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandleFUCHSIA);
278     if (strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA") == 0)
279         return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandlePropertiesFUCHSIA);
280     if (strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA") == 0)
281         return reinterpret_cast<PFN_vkVoidFunction>(GetSemaphoreZirconHandleFUCHSIA);
282     if (strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA") == 0)
283         return reinterpret_cast<PFN_vkVoidFunction>(ImportSemaphoreZirconHandleFUCHSIA);
284     if (strcmp(name, "vkCreateBufferCollectionFUCHSIA") == 0)
285         return reinterpret_cast<PFN_vkVoidFunction>(
286             CreateBufferCollectionFUCHSIA);
287     if (strcmp(name, "vkDestroyBufferCollectionFUCHSIA") == 0)
288         return reinterpret_cast<PFN_vkVoidFunction>(
289             DestroyBufferCollectionFUCHSIA);
290     if (strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIA") == 0)
291         return reinterpret_cast<PFN_vkVoidFunction>(
292             SetBufferCollectionImageConstraintsFUCHSIA);
293     if (strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA") == 0)
294         return reinterpret_cast<PFN_vkVoidFunction>(
295             SetBufferCollectionBufferConstraintsFUCHSIA);
296     if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0)
297         return reinterpret_cast<PFN_vkVoidFunction>(
298             GetBufferCollectionPropertiesFUCHSIA);
299 #endif
300     // Return NoOp for entrypoints that should never be called.
301     if (strcmp(name, "vkGetPhysicalDeviceFeatures") == 0 ||
302         strcmp(name, "vkGetPhysicalDeviceProperties") == 0 ||
303         strcmp(name, "vkGetPhysicalDeviceFormatProperties") == 0 ||
304         strcmp(name, "vkGetPhysicalDeviceImageFormatProperties") == 0 ||
305         strcmp(name, "vkGetPhysicalDeviceMemoryProperties") == 0 ||
306         strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties") == 0 ||
307         strcmp(name, "vkGetDeviceProcAddr") == 0 ||
308         strcmp(name, "vkCreateDevice") == 0 ||
309         strcmp(name, "vkEnumerateDeviceExtensionProperties") == 0 ||
310         strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties") == 0 ||
311         strcmp(name, "vkGetPhysicalDeviceFeatures2") == 0 ||
312         strcmp(name, "vkGetPhysicalDeviceProperties2") == 0 ||
313         strcmp(name, "vkGetPhysicalDeviceFormatProperties2") == 0 ||
314         strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2") == 0 ||
315         strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2") == 0 ||
316         strcmp(name, "vkGetPhysicalDeviceMemoryProperties2") == 0 ||
317         strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2") == 0 ||
318         strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties") == 0 ||
319         strcmp(name, "vkGetPhysicalDeviceExternalFenceProperties") == 0 ||
320         strcmp(name, "vkGetPhysicalDeviceExternalSemaphoreProperties") == 0)
321         return reinterpret_cast<PFN_vkVoidFunction>(NoOp);
322 
323     // Per the spec, return NULL for nonexistent entrypoints.
324     return nullptr;
325 }
326 
327 } // namespace vkstubhal
328 
329 namespace {
330 
331 #ifdef VK_USE_PLATFORM_ANDROID_KHR
332 
333 int OpenDevice(const hw_module_t* module, const char* id, hw_device_t** device);
334 
335 hw_module_methods_t goldfish_vulkan_module_methods = {
336     .open = OpenDevice
337 };
338 
339 extern "C" __attribute__((visibility("default"))) hwvulkan_module_t HAL_MODULE_INFO_SYM = {
340     .common = {
341         .tag = HARDWARE_MODULE_TAG,
342         .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
343         .hal_api_version = HARDWARE_HAL_API_VERSION,
344         .id = HWVULKAN_HARDWARE_MODULE_ID,
345         .name = "Goldfish Vulkan Driver",
346         .author = "The Android Open Source Project",
347         .methods = &goldfish_vulkan_module_methods,
348     },
349 };
350 
CloseDevice(struct hw_device_t *)351 int CloseDevice(struct hw_device_t* /*device*/) {
352     AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
353     // nothing to do - opening a device doesn't allocate any resources
354     return 0;
355 }
356 
357 #endif
358 
359 #define VK_HOST_CONNECTION(ret) \
360     HostConnection *hostCon = HostConnection::getOrCreate(VIRTIO_GPU_CAPSET_GFXSTREAM); \
361     if (!hostCon) { \
362         ALOGE("vulkan: Failed to get host connection\n"); \
363         return ret; \
364     } \
365     ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
366     if (!rcEnc) { \
367         ALOGE("vulkan: Failed to get renderControl encoder context\n"); \
368         return ret; \
369     } \
370     gfxstream::vk::ResourceTracker::ThreadingCallbacks threadingCallbacks = { \
371         [] { \
372           auto hostCon = HostConnection::get(); \
373           hostCon->rcEncoder(); \
374           return hostCon; \
375         }, \
376         [](HostConnection* hostCon) { return hostCon->vkEncoder(); }, \
377     }; \
378     gfxstream::vk::ResourceTracker::get()->setThreadingCallbacks(threadingCallbacks); \
379     gfxstream::vk::ResourceTracker::get()->setupFeatures(rcEnc->featureInfo_const()); \
380     gfxstream::vk::ResourceTracker::get()->setupCaps();                                    \
381     gfxstream::vk::ResourceTracker::get()->setSeqnoPtr(getSeqnoPtrForProcess()); \
382     auto hostSupportsVulkan = gfxstream::vk::ResourceTracker::get()->hostSupportsVulkan(); \
383     gfxstream::vk::VkEncoder *vkEnc = hostCon->vkEncoder(); \
384     if (!vkEnc) { \
385         ALOGE("vulkan: Failed to get Vulkan encoder\n"); \
386         return ret; \
387     } \
388 
389 VKAPI_ATTR
EnumerateInstanceExtensionProperties(const char * layer_name,uint32_t * count,VkExtensionProperties * properties)390 VkResult EnumerateInstanceExtensionProperties(
391     const char* layer_name,
392     uint32_t* count,
393     VkExtensionProperties* properties) {
394     AEMU_SCOPED_TRACE("goldfish_vulkan::EnumerateInstanceExtensionProperties");
395 
396     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
397 
398     if (!hostSupportsVulkan) {
399         return vkstubhal::EnumerateInstanceExtensionProperties(layer_name, count, properties);
400     }
401 
402     if (layer_name) {
403         ALOGW(
404             "Driver vkEnumerateInstanceExtensionProperties shouldn't be called "
405             "with a layer name ('%s')",
406             layer_name);
407     }
408 
409     VkResult res = gfxstream::vk::ResourceTracker::get()->on_vkEnumerateInstanceExtensionProperties(
410         vkEnc, VK_SUCCESS, layer_name, count, properties);
411 
412     return res;
413 }
414 
415 VKAPI_ATTR
CreateInstance(const VkInstanceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkInstance * out_instance)416 VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
417                         const VkAllocationCallbacks* allocator,
418                         VkInstance* out_instance) {
419     AEMU_SCOPED_TRACE("goldfish_vulkan::CreateInstance");
420 
421     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
422 
423     if (!hostSupportsVulkan) {
424         return vkstubhal::CreateInstance(create_info, allocator, out_instance);
425     }
426 
427     VkResult res = vkEnc->vkCreateInstance(create_info, nullptr, out_instance, true /* do lock */);
428 
429     return res;
430 }
431 
432 #ifdef VK_USE_PLATFORM_FUCHSIA
433 VKAPI_ATTR
GetMemoryZirconHandleFUCHSIA(VkDevice device,const VkMemoryGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)434 VkResult GetMemoryZirconHandleFUCHSIA(
435     VkDevice device,
436     const VkMemoryGetZirconHandleInfoFUCHSIA* pInfo,
437     uint32_t* pHandle) {
438     AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandleFUCHSIA");
439 
440     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
441 
442     if (!hostSupportsVulkan) {
443         return vkstubhal::GetMemoryZirconHandleFUCHSIA(device, pInfo, pHandle);
444     }
445 
446     VkResult res = gfxstream::vk::ResourceTracker::get()->
447         on_vkGetMemoryZirconHandleFUCHSIA(
448             vkEnc, VK_SUCCESS,
449             device, pInfo, pHandle);
450 
451     return res;
452 }
453 
454 VKAPI_ATTR
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice device,VkExternalMemoryHandleTypeFlagBits handleType,uint32_t handle,VkMemoryZirconHandlePropertiesFUCHSIA * pProperties)455 VkResult GetMemoryZirconHandlePropertiesFUCHSIA(
456     VkDevice device,
457     VkExternalMemoryHandleTypeFlagBits handleType,
458     uint32_t handle,
459     VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
460     AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandlePropertiesFUCHSIA");
461 
462     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
463 
464     if (!hostSupportsVulkan) {
465         return vkstubhal::GetMemoryZirconHandlePropertiesFUCHSIA(
466             device, handleType, handle, pProperties);
467     }
468 
469     VkResult res = gfxstream::vk::ResourceTracker::get()->
470         on_vkGetMemoryZirconHandlePropertiesFUCHSIA(
471             vkEnc, VK_SUCCESS, device, handleType, handle, pProperties);
472 
473     return res;
474 }
475 
476 VKAPI_ATTR
GetSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkSemaphoreGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)477 VkResult GetSemaphoreZirconHandleFUCHSIA(
478     VkDevice device,
479     const VkSemaphoreGetZirconHandleInfoFUCHSIA* pInfo,
480     uint32_t* pHandle) {
481     AEMU_SCOPED_TRACE("goldfish_vulkan::GetSemaphoreZirconHandleFUCHSIA");
482 
483     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
484 
485     if (!hostSupportsVulkan) {
486         return vkstubhal::GetSemaphoreZirconHandleFUCHSIA(device, pInfo, pHandle);
487     }
488 
489     VkResult res = gfxstream::vk::ResourceTracker::get()->
490         on_vkGetSemaphoreZirconHandleFUCHSIA(
491             vkEnc, VK_SUCCESS, device, pInfo, pHandle);
492 
493     return res;
494 }
495 
496 VKAPI_ATTR
ImportSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkImportSemaphoreZirconHandleInfoFUCHSIA * pInfo)497 VkResult ImportSemaphoreZirconHandleFUCHSIA(
498     VkDevice device,
499     const VkImportSemaphoreZirconHandleInfoFUCHSIA* pInfo) {
500     AEMU_SCOPED_TRACE("goldfish_vulkan::ImportSemaphoreZirconHandleFUCHSIA");
501 
502     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
503 
504     if (!hostSupportsVulkan) {
505         return vkstubhal::ImportSemaphoreZirconHandleFUCHSIA(device, pInfo);
506     }
507 
508     VkResult res = gfxstream::vk::ResourceTracker::get()->
509         on_vkImportSemaphoreZirconHandleFUCHSIA(
510             vkEnc, VK_SUCCESS, device, pInfo);
511 
512     return res;
513 }
514 
515 VKAPI_ATTR
CreateBufferCollectionFUCHSIA(VkDevice device,const VkBufferCollectionCreateInfoFUCHSIA * pInfo,const VkAllocationCallbacks * pAllocator,VkBufferCollectionFUCHSIA * pCollection)516 VkResult CreateBufferCollectionFUCHSIA(
517     VkDevice device,
518     const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
519     const VkAllocationCallbacks* pAllocator,
520     VkBufferCollectionFUCHSIA* pCollection) {
521     AEMU_SCOPED_TRACE("goldfish_vulkan::CreateBufferCollectionFUCHSIA");
522 
523     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
524 
525     if (!hostSupportsVulkan) {
526         return vkstubhal::CreateBufferCollectionFUCHSIA(
527             device, pInfo, pAllocator, pCollection);
528     }
529 
530     VkResult res =
531         gfxstream::vk::ResourceTracker::get()->on_vkCreateBufferCollectionFUCHSIA(
532             vkEnc, VK_SUCCESS, device, pInfo, pAllocator, pCollection);
533 
534     return res;
535 }
536 
537 VKAPI_ATTR
DestroyBufferCollectionFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkAllocationCallbacks * pAllocator)538 void DestroyBufferCollectionFUCHSIA(VkDevice device,
539                                     VkBufferCollectionFUCHSIA collection,
540                                     const VkAllocationCallbacks* pAllocator) {
541     AEMU_SCOPED_TRACE("goldfish_vulkan::DestroyBufferCollectionFUCHSIA");
542 
543     VK_HOST_CONNECTION()
544 
545     if (!hostSupportsVulkan) {
546         vkstubhal::DestroyBufferCollectionFUCHSIA(device, collection,
547                                                   pAllocator);
548         return;
549     }
550 
551     gfxstream::vk::ResourceTracker::get()->on_vkDestroyBufferCollectionFUCHSIA(
552         vkEnc, VK_SUCCESS, device, collection, pAllocator);
553 }
554 
555 VKAPI_ATTR
SetBufferCollectionBufferConstraintsFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkBufferConstraintsInfoFUCHSIA * pBufferConstraintsInfo)556 VkResult SetBufferCollectionBufferConstraintsFUCHSIA(
557     VkDevice device,
558     VkBufferCollectionFUCHSIA collection,
559     const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
560     AEMU_SCOPED_TRACE(
561         "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIA");
562 
563     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
564 
565     if (!hostSupportsVulkan) {
566         return vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIA(
567             device, collection, pBufferConstraintsInfo);
568     }
569 
570     VkResult res =
571         gfxstream::vk::ResourceTracker::get()
572             ->on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
573                 vkEnc, VK_SUCCESS, device, collection, pBufferConstraintsInfo);
574 
575     return res;
576 }
577 
578 VKAPI_ATTR
SetBufferCollectionImageConstraintsFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkImageConstraintsInfoFUCHSIA * pImageConstraintsInfo)579 VkResult SetBufferCollectionImageConstraintsFUCHSIA(
580     VkDevice device,
581     VkBufferCollectionFUCHSIA collection,
582     const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
583     AEMU_SCOPED_TRACE(
584         "goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIA");
585 
586     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
587 
588     if (!hostSupportsVulkan) {
589         return vkstubhal::SetBufferCollectionImageConstraintsFUCHSIA(
590             device, collection, pImageConstraintsInfo);
591     }
592 
593     VkResult res =
594         gfxstream::vk::ResourceTracker::get()
595             ->on_vkSetBufferCollectionImageConstraintsFUCHSIA(
596                 vkEnc, VK_SUCCESS, device, collection, pImageConstraintsInfo);
597 
598     return res;
599 }
600 
601 VKAPI_ATTR
GetBufferCollectionPropertiesFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,VkBufferCollectionPropertiesFUCHSIA * pProperties)602 VkResult GetBufferCollectionPropertiesFUCHSIA(
603     VkDevice device,
604     VkBufferCollectionFUCHSIA collection,
605     VkBufferCollectionPropertiesFUCHSIA* pProperties) {
606     AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIA");
607 
608     VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
609 
610     if (!hostSupportsVulkan) {
611         return vkstubhal::GetBufferCollectionPropertiesFUCHSIA(
612             device, collection, pProperties);
613     }
614 
615     VkResult res = gfxstream::vk::ResourceTracker::get()
616                        ->on_vkGetBufferCollectionPropertiesFUCHSIA(
617                            vkEnc, VK_SUCCESS, device, collection, pProperties);
618 
619     return res;
620 }
621 
622 #endif
623 
currGuestTimeNs()624 uint64_t currGuestTimeNs() {
625     struct timespec ts;
626 #ifdef __APPLE__
627     clock_gettime(CLOCK_REALTIME, &ts);
628 #else
629     clock_gettime(CLOCK_BOOTTIME, &ts);
630 #endif
631     uint64_t res = (uint64_t)(ts.tv_sec * 1000000000ULL + ts.tv_nsec);
632     return res;
633 }
634 
635 struct FrameTracingState {
636     uint32_t frameNumber = 0;
637     bool tracingEnabled = false;
onSwapBuffersSuccessful__anon7cffe3450111::FrameTracingState638     void onSwapBuffersSuccessful(ExtendedRCEncoderContext* rcEnc) {
639 #ifdef GFXSTREAM
640         bool current = android::base::isTracingEnabled();
641         // edge trigger
642         if (current && !tracingEnabled) {
643             if (rcEnc->hasHostSideTracing()) {
644                 rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 1, currGuestTimeNs());
645             }
646         }
647         if (!current && tracingEnabled) {
648             if (rcEnc->hasHostSideTracing()) {
649                 rcEnc->rcSetTracingForPuid(rcEnc, getPuid(), 0, currGuestTimeNs());
650             }
651         }
652         tracingEnabled = current;
653 #endif
654         ++frameNumber;
655     }
656 };
657 
658 static FrameTracingState sFrameTracingState;
659 
660 static PFN_vkVoidFunction sQueueSignalReleaseImageAndroidImpl = 0;
661 
662 #ifdef VK_USE_PLATFORM_ANDROID_KHR
663 static VkResult
QueueSignalReleaseImageANDROID(VkQueue queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)664 QueueSignalReleaseImageANDROID(
665     VkQueue queue,
666     uint32_t waitSemaphoreCount,
667     const VkSemaphore* pWaitSemaphores,
668     VkImage image,
669     int* pNativeFenceFd)
670 {
671     sFrameTracingState.onSwapBuffersSuccessful(HostConnection::get()->rcEncoder());
672     ((PFN_vkQueueSignalReleaseImageANDROID)sQueueSignalReleaseImageAndroidImpl)(queue, waitSemaphoreCount, pWaitSemaphores, image, pNativeFenceFd);
673     return VK_SUCCESS;
674 }
675 #endif
676 
GetDeviceProcAddr(VkDevice device,const char * name)677 static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
678     AEMU_SCOPED_TRACE("goldfish_vulkan::GetDeviceProcAddr");
679 
680     VK_HOST_CONNECTION(nullptr)
681 
682     if (!hostSupportsVulkan) {
683         return nullptr;
684     }
685 
686 #ifdef VK_USE_PLATFORM_FUCHSIA
687     if (!strcmp(name, "vkGetMemoryZirconHandleFUCHSIA")) {
688         return (PFN_vkVoidFunction)GetMemoryZirconHandleFUCHSIA;
689     }
690     if (!strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA")) {
691         return (PFN_vkVoidFunction)GetMemoryZirconHandlePropertiesFUCHSIA;
692     }
693     if (!strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA")) {
694         return (PFN_vkVoidFunction)GetSemaphoreZirconHandleFUCHSIA;
695     }
696     if (!strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA")) {
697         return (PFN_vkVoidFunction)ImportSemaphoreZirconHandleFUCHSIA;
698     }
699     if (!strcmp(name, "vkCreateBufferCollectionFUCHSIA")) {
700         return (PFN_vkVoidFunction)CreateBufferCollectionFUCHSIA;
701     }
702     if (!strcmp(name, "vkDestroyBufferCollectionFUCHSIA")) {
703         return (PFN_vkVoidFunction)DestroyBufferCollectionFUCHSIA;
704     }
705     if (!strcmp(name, "vkSetBufferCollectionImageConstraintsFUCHSIA")) {
706         return (PFN_vkVoidFunction)SetBufferCollectionImageConstraintsFUCHSIA;
707     }
708     if (!strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA")) {
709         return (PFN_vkVoidFunction)SetBufferCollectionBufferConstraintsFUCHSIA;
710     }
711     if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) {
712         return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA;
713     }
714 #endif
715 #ifdef VK_USE_PLATFORM_ANDROID_KHR
716     if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
717         if (!sQueueSignalReleaseImageAndroidImpl) {
718             sQueueSignalReleaseImageAndroidImpl =
719                 (PFN_vkVoidFunction)(
720                     gfxstream::vk::goldfish_vulkan_get_device_proc_address(device, "vkQueueSignalReleaseImageANDROID"));
721         }
722         return (PFN_vkVoidFunction)QueueSignalReleaseImageANDROID;
723     }
724 #endif
725     if (!strcmp(name, "vkGetDeviceProcAddr")) {
726         return (PFN_vkVoidFunction)(GetDeviceProcAddr);
727     }
728     return (PFN_vkVoidFunction)(gfxstream::vk::goldfish_vulkan_get_device_proc_address(device, name));
729 }
730 
731 VKAPI_ATTR
GetInstanceProcAddr(VkInstance instance,const char * name)732 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
733     AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
734 
735     VK_HOST_CONNECTION(nullptr)
736 
737     if (!hostSupportsVulkan) {
738         return vkstubhal::GetInstanceProcAddr(instance, name);
739     }
740 
741     if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
742         return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
743     }
744     if (!strcmp(name, "vkCreateInstance")) {
745         return (PFN_vkVoidFunction)CreateInstance;
746     }
747     if (!strcmp(name, "vkGetDeviceProcAddr")) {
748         return (PFN_vkVoidFunction)(GetDeviceProcAddr);
749     }
750 #ifdef VK_USE_PLATFORM_ANDROID_KHR
751     if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
752         if (!sQueueSignalReleaseImageAndroidImpl) {
753             sQueueSignalReleaseImageAndroidImpl =
754                 (PFN_vkVoidFunction)(
755                     gfxstream::vk::goldfish_vulkan_get_instance_proc_address(instance, "vkQueueSignalReleaseImageANDROID"));
756         }
757         return (PFN_vkVoidFunction)QueueSignalReleaseImageANDROID;
758     }
759 #endif
760     return (PFN_vkVoidFunction)(gfxstream::vk::goldfish_vulkan_get_instance_proc_address(instance, name));
761 }
762 
763 #ifdef VK_USE_PLATFORM_ANDROID_KHR
764 
765 hwvulkan_device_t goldfish_vulkan_device = {
766     .common = {
767         .tag = HARDWARE_DEVICE_TAG,
768         .version = HWVULKAN_DEVICE_API_VERSION_0_1,
769         .module = &HAL_MODULE_INFO_SYM.common,
770         .close = CloseDevice,
771     },
772     .EnumerateInstanceExtensionProperties = EnumerateInstanceExtensionProperties,
773     .CreateInstance = CreateInstance,
774     .GetInstanceProcAddr = GetInstanceProcAddr,
775 };
776 
OpenDevice(const hw_module_t *,const char * id,hw_device_t ** device)777 int OpenDevice(const hw_module_t* /*module*/,
778                const char* id,
779                hw_device_t** device) {
780     AEMU_SCOPED_TRACE("goldfish_vulkan::OpenDevice");
781 
782     if (strcmp(id, HWVULKAN_DEVICE_0) == 0) {
783         *device = &goldfish_vulkan_device.common;
784         gfxstream::vk::ResourceTracker::get();
785         return 0;
786     }
787     return -ENOENT;
788 }
789 
790 #elif VK_USE_PLATFORM_FUCHSIA
791 
792 class VulkanDevice {
793 public:
VulkanDevice()794     VulkanDevice() : mHostSupportsGoldfish(IsAccessible(QEMU_PIPE_PATH)) {
795         InitLogger();
796         InitTraceProvider();
797         gfxstream::vk::ResourceTracker::get();
798     }
799 
800     static void InitLogger();
801 
IsAccessible(const char * name)802     static bool IsAccessible(const char* name) {
803         zx_handle_t handle = GetConnectToServiceFunction()(name);
804         if (handle == ZX_HANDLE_INVALID)
805             return false;
806 
807         zxio_storage_t io_storage;
808         zx_status_t status = zxio_create(handle, &io_storage);
809         if (status != ZX_OK)
810             return false;
811 
812         status = zxio_close(&io_storage.io, /*should_wait=*/true);
813         if (status != ZX_OK)
814             return false;
815 
816         return true;
817     }
818 
GetInstance()819     static VulkanDevice& GetInstance() {
820         static VulkanDevice g_instance;
821         return g_instance;
822     }
823 
GetInstanceProcAddr(VkInstance instance,const char * name)824     PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
825         if (!mHostSupportsGoldfish) {
826             return vkstubhal::GetInstanceProcAddr(instance, name);
827         }
828         return ::GetInstanceProcAddr(instance, name);
829     }
830 
831 private:
832     void InitTraceProvider();
833 
834     TraceProviderFuchsia mTraceProvider;
835     const bool mHostSupportsGoldfish;
836 };
837 
InitLogger()838 void VulkanDevice::InitLogger() {
839   auto log_socket = ([] () -> std::optional<zx::socket> {
840     fidl::ClientEnd<fuchsia_logger::LogSink> channel{zx::channel{
841       GetConnectToServiceFunction()("/svc/fuchsia.logger.LogSink")}};
842     if (!channel.is_valid())
843       return std::nullopt;
844 
845     zx::socket local_socket, remote_socket;
846     zx_status_t status = zx::socket::create(ZX_SOCKET_DATAGRAM, &local_socket, &remote_socket);
847     if (status != ZX_OK)
848       return std::nullopt;
849 
850     auto result = fidl::WireCall(channel)->Connect(std::move(remote_socket));
851 
852     if (!result.ok())
853       return std::nullopt;
854 
855     return local_socket;
856   })();
857   if (!log_socket)
858     return;
859 
860   fx_logger_config_t config = {
861       .min_severity = FX_LOG_INFO,
862       .log_sink_socket = log_socket->release(),
863       .tags = nullptr,
864       .num_tags = 0,
865   };
866 
867   fx_log_reconfigure(&config);
868 }
869 
InitTraceProvider()870 void VulkanDevice::InitTraceProvider() {
871     if (!mTraceProvider.Initialize()) {
872         ALOGE("Trace provider failed to initialize");
873     }
874 }
875 
876 extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance,const char * name)877 vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
878     return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
879 }
880 
881 extern "C" __attribute__((visibility("default"))) VkResult
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)882 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
883     *pSupportedVersion = std::min(*pSupportedVersion, 3u);
884     return VK_SUCCESS;
885 }
886 
887 typedef VkResult(VKAPI_PTR *PFN_vkOpenInNamespaceAddr)(const char *pName, uint32_t handle);
888 
889 namespace {
890 
891 PFN_vkOpenInNamespaceAddr g_vulkan_connector;
892 
LocalConnectToServiceFunction(const char * pName)893 zx_handle_t LocalConnectToServiceFunction(const char* pName) {
894     zx::channel remote_endpoint, local_endpoint;
895     zx_status_t status;
896     if ((status = zx::channel::create(0, &remote_endpoint, &local_endpoint)) != ZX_OK) {
897         ALOGE("zx::channel::create failed: %d", status);
898         return ZX_HANDLE_INVALID;
899     }
900     if ((status = g_vulkan_connector(pName, remote_endpoint.release())) != ZX_OK) {
901         ALOGE("vulkan_connector failed: %d", status);
902         return ZX_HANDLE_INVALID;
903     }
904     return local_endpoint.release();
905 }
906 
907 }
908 
909 extern "C" __attribute__((visibility("default"))) void
vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr callback)910 vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr callback) {
911     g_vulkan_connector = callback;
912     SetConnectToServiceFunction(&LocalConnectToServiceFunction);
913 }
914 
915 #else
916 class VulkanDevice {
917 public:
VulkanDevice()918     VulkanDevice() {
919         gfxstream::vk::ResourceTracker::get();
920     }
921 
GetInstance()922     static VulkanDevice& GetInstance() {
923         static VulkanDevice g_instance;
924         return g_instance;
925     }
926 
GetInstanceProcAddr(VkInstance instance,const char * name)927     PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
928         return ::GetInstanceProcAddr(instance, name);
929     }
930 };
931 
932 extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance,const char * name)933 vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
934     return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
935 }
936 
937 extern "C" __attribute__((visibility("default"))) VkResult
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)938 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
939     *pSupportedVersion = std::min(*pSupportedVersion, 3u);
940     return VK_SUCCESS;
941 }
942 
943 #endif
944 
945 } // namespace
946