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