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