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