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
21 #include "HostConnection.h"
22 #include "ResourceTracker.h"
23 #include "VkEncoder.h"
24
25 #include "func_table.h"
26
27 #include <array>
28 #include <bitset>
29 #include <mutex>
30
31 // Used when there is no Vulkan support on the host.
32 // Copied from frameworks/native/vulkan/libvulkan/stubhal.cpp
33 namespace vkstubhal {
34
35 const size_t kMaxInstances = 32;
36 static std::mutex g_instance_mutex;
37 static std::bitset<kMaxInstances> g_instance_used(false);
38 static std::array<hwvulkan_dispatch_t, kMaxInstances> g_instances;
39
NoOp()40 [[noreturn]] VKAPI_ATTR void NoOp() {
41 LOG_ALWAYS_FATAL("invalid stub function called");
42 }
43
44 VkResult
EnumerateInstanceExtensionProperties(const char *,uint32_t * count,VkExtensionProperties *)45 EnumerateInstanceExtensionProperties(const char* /*layer_name*/,
46 uint32_t* count,
47 VkExtensionProperties* /*properties*/) {
48 AEMU_SCOPED_TRACE("vkstubhal::EnumerateInstanceExtensionProperties");
49 *count = 0;
50 return VK_SUCCESS;
51 }
52
53 VkResult
EnumerateInstanceLayerProperties(uint32_t * count,VkLayerProperties *)54 EnumerateInstanceLayerProperties(uint32_t* count,
55 VkLayerProperties* /*properties*/) {
56 AEMU_SCOPED_TRACE("vkstubhal::EnumerateInstanceLayerProperties");
57 *count = 0;
58 return VK_SUCCESS;
59 }
60
CreateInstance(const VkInstanceCreateInfo *,const VkAllocationCallbacks *,VkInstance * instance)61 VkResult CreateInstance(const VkInstanceCreateInfo* /*create_info*/,
62 const VkAllocationCallbacks* /*allocator*/,
63 VkInstance* instance) {
64 AEMU_SCOPED_TRACE("vkstubhal::CreateInstance");
65 std::lock_guard<std::mutex> lock(g_instance_mutex);
66 for (size_t i = 0; i < kMaxInstances; i++) {
67 if (!g_instance_used[i]) {
68 g_instance_used[i] = true;
69 g_instances[i].magic = HWVULKAN_DISPATCH_MAGIC;
70 *instance = reinterpret_cast<VkInstance>(&g_instances[i]);
71 return VK_SUCCESS;
72 }
73 }
74 ALOGE("no more instances available (max=%zu)", kMaxInstances);
75 return VK_ERROR_INITIALIZATION_FAILED;
76 }
77
DestroyInstance(VkInstance instance,const VkAllocationCallbacks *)78 void DestroyInstance(VkInstance instance,
79 const VkAllocationCallbacks* /*allocator*/) {
80 AEMU_SCOPED_TRACE("vkstubhal::DestroyInstance");
81 std::lock_guard<std::mutex> lock(g_instance_mutex);
82 ssize_t idx =
83 reinterpret_cast<hwvulkan_dispatch_t*>(instance) - &g_instances[0];
84 ALOG_ASSERT(idx >= 0 && static_cast<size_t>(idx) < g_instance_used.size(),
85 "DestroyInstance: invalid instance handle");
86 g_instance_used[static_cast<size_t>(idx)] = false;
87 }
88
EnumeratePhysicalDevices(VkInstance,uint32_t * count,VkPhysicalDevice *)89 VkResult EnumeratePhysicalDevices(VkInstance /*instance*/,
90 uint32_t* count,
91 VkPhysicalDevice* /*gpus*/) {
92 AEMU_SCOPED_TRACE("vkstubhal::EnumeratePhysicalDevices");
93 *count = 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 #ifdef VK_USE_PLATFORM_FUCHSIA
107 VkResult
GetMemoryZirconHandleFUCHSIA(VkDevice,const VkMemoryGetZirconHandleInfoFUCHSIA *,uint32_t * pHandle)108 GetMemoryZirconHandleFUCHSIA(VkDevice /*device*/,
109 const VkMemoryGetZirconHandleInfoFUCHSIA* /*pInfo*/,
110 uint32_t* pHandle) {
111 AEMU_SCOPED_TRACE("vkstubhal::GetMemoryZirconHandleFUCHSIA");
112 *pHandle = 0;
113 return VK_SUCCESS;
114 }
115
116 VkResult
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice,VkExternalMemoryHandleTypeFlagBits,uint32_t,VkMemoryZirconHandlePropertiesFUCHSIA *)117 GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice /*device*/,
118 VkExternalMemoryHandleTypeFlagBits /*handleType*/,
119 uint32_t /*handle*/,
120 VkMemoryZirconHandlePropertiesFUCHSIA* /*pProperties*/) {
121 AEMU_SCOPED_TRACE("vkstubhal::GetMemoryZirconHandlePropertiesFUCHSIA");
122 return VK_SUCCESS;
123 }
124
125 VkResult
GetSemaphoreZirconHandleFUCHSIA(VkDevice,const VkSemaphoreGetZirconHandleInfoFUCHSIA *,uint32_t * pHandle)126 GetSemaphoreZirconHandleFUCHSIA(VkDevice /*device*/,
127 const VkSemaphoreGetZirconHandleInfoFUCHSIA* /*pInfo*/,
128 uint32_t* pHandle) {
129 AEMU_SCOPED_TRACE("vkstubhal::GetSemaphoreZirconHandleFUCHSIA");
130 *pHandle = 0;
131 return VK_SUCCESS;
132 }
133
134 VkResult
ImportSemaphoreZirconHandleFUCHSIA(VkDevice,const VkImportSemaphoreZirconHandleInfoFUCHSIA *)135 ImportSemaphoreZirconHandleFUCHSIA(VkDevice /*device*/,
136 const VkImportSemaphoreZirconHandleInfoFUCHSIA* /*pInfo*/) {
137 AEMU_SCOPED_TRACE("vkstubhal::ImportSemaphoreZirconHandleFUCHSIA");
138 return VK_SUCCESS;
139 }
140
141 VkResult
CreateBufferCollectionFUCHSIA(VkDevice,const VkBufferCollectionCreateInfoFUCHSIA *,const VkAllocationCallbacks *,VkBufferCollectionFUCHSIA *)142 CreateBufferCollectionFUCHSIA(VkDevice /*device*/,
143 const VkBufferCollectionCreateInfoFUCHSIA* /*pInfo*/,
144 const VkAllocationCallbacks* /*pAllocator*/,
145 VkBufferCollectionFUCHSIA* /*pCollection*/) {
146 AEMU_SCOPED_TRACE("vkstubhal::CreateBufferCollectionFUCHSIA");
147 return VK_SUCCESS;
148 }
149
150 void
DestroyBufferCollectionFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,const VkAllocationCallbacks *)151 DestroyBufferCollectionFUCHSIA(VkDevice /*device*/,
152 VkBufferCollectionFUCHSIA /*collection*/,
153 const VkAllocationCallbacks* /*pAllocator*/) {
154 AEMU_SCOPED_TRACE("vkstubhal::DestroyBufferCollectionFUCHSIA");
155 }
156
157 VkResult
SetBufferCollectionConstraintsFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,const VkImageCreateInfo *)158 SetBufferCollectionConstraintsFUCHSIA(VkDevice /*device*/,
159 VkBufferCollectionFUCHSIA /*collection*/,
160 const VkImageCreateInfo* /*pImageInfo*/) {
161 AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionConstraintsFUCHSIA");
162 return VK_SUCCESS;
163 }
164
165 VkResult
GetBufferCollectionPropertiesFUCHSIA(VkDevice,VkBufferCollectionFUCHSIA,VkBufferCollectionPropertiesFUCHSIA *)166 GetBufferCollectionPropertiesFUCHSIA(VkDevice /*device*/,
167 VkBufferCollectionFUCHSIA /*collection*/,
168 VkBufferCollectionPropertiesFUCHSIA* /*pProperties*/) {
169 AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionPropertiesFUCHSIA");
170 return VK_SUCCESS;
171 }
172 #endif
173
GetInstanceProcAddr(VkInstance instance,const char * name)174 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
175 const char* name) {
176 AEMU_SCOPED_TRACE("vkstubhal::GetInstanceProcAddr");
177 if (strcmp(name, "vkCreateInstance") == 0)
178 return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
179 if (strcmp(name, "vkDestroyInstance") == 0)
180 return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
181 if (strcmp(name, "vkEnumerateInstanceExtensionProperties") == 0)
182 return reinterpret_cast<PFN_vkVoidFunction>(
183 EnumerateInstanceExtensionProperties);
184 if (strcmp(name, "vkEnumeratePhysicalDevices") == 0)
185 return reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices);
186 if (strcmp(name, "vkEnumeratePhysicalDeviceGroups") == 0)
187 return reinterpret_cast<PFN_vkVoidFunction>(
188 EnumeratePhysicalDeviceGroups);
189 if (strcmp(name, "vkGetInstanceProcAddr") == 0)
190 return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
191 #ifdef VK_USE_PLATFORM_FUCHSIA
192 if (strcmp(name, "vkGetMemoryZirconHandleFUCHSIA") == 0)
193 return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandleFUCHSIA);
194 if (strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA") == 0)
195 return reinterpret_cast<PFN_vkVoidFunction>(GetMemoryZirconHandlePropertiesFUCHSIA);
196 if (strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA") == 0)
197 return reinterpret_cast<PFN_vkVoidFunction>(GetSemaphoreZirconHandleFUCHSIA);
198 if (strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA") == 0)
199 return reinterpret_cast<PFN_vkVoidFunction>(ImportSemaphoreZirconHandleFUCHSIA);
200 if (strcmp(name, "vkCreateBufferCollectionFUCHSIA") == 0)
201 return reinterpret_cast<PFN_vkVoidFunction>(CreateBufferCollectionFUCHSIA);
202 if (strcmp(name, "vkDestroyBufferCollectionFUCHSIA") == 0)
203 return reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferCollectionFUCHSIA);
204 if (strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA") == 0)
205 return reinterpret_cast<PFN_vkVoidFunction>(SetBufferCollectionConstraintsFUCHSIA);
206 if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0)
207 return reinterpret_cast<PFN_vkVoidFunction>(GetBufferCollectionPropertiesFUCHSIA);
208 #endif
209 // Per the spec, return NULL if instance is NULL.
210 if (!instance)
211 return nullptr;
212 // None of the other Vulkan functions should ever be called, as they all
213 // take a VkPhysicalDevice or other object obtained from a physical device.
214 return reinterpret_cast<PFN_vkVoidFunction>(NoOp);
215 }
216
217 } // namespace vkstubhal
218
219 namespace {
220
221 #ifdef VK_USE_PLATFORM_ANDROID_KHR
222
223 int OpenDevice(const hw_module_t* module, const char* id, hw_device_t** device);
224
225 hw_module_methods_t goldfish_vulkan_module_methods = {
226 .open = OpenDevice
227 };
228
229 extern "C" __attribute__((visibility("default"))) hwvulkan_module_t HAL_MODULE_INFO_SYM = {
230 .common = {
231 .tag = HARDWARE_MODULE_TAG,
232 .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
233 .hal_api_version = HARDWARE_HAL_API_VERSION,
234 .id = HWVULKAN_HARDWARE_MODULE_ID,
235 .name = "Goldfish Vulkan Driver",
236 .author = "The Android Open Source Project",
237 .methods = &goldfish_vulkan_module_methods,
238 },
239 };
240
CloseDevice(struct hw_device_t *)241 int CloseDevice(struct hw_device_t* /*device*/) {
242 AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
243 // nothing to do - opening a device doesn't allocate any resources
244 return 0;
245 }
246
247 #endif
248
249 #define VK_HOST_CONNECTION(ret) \
250 HostConnection *hostCon = HostConnection::get(); \
251 if (!hostCon) { \
252 ALOGE("vulkan: Failed to get host connection\n"); \
253 return ret; \
254 } \
255 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
256 if (!rcEnc) { \
257 ALOGE("vulkan: Failed to get renderControl encoder context\n"); \
258 return ret; \
259 } \
260 goldfish_vk::VkEncoder *vkEnc = hostCon->vkEncoder(); \
261 if (!vkEnc) { \
262 ALOGE("vulkan: Failed to get Vulkan encoder\n"); \
263 return ret; \
264 } \
265 goldfish_vk::ResourceTracker::get()->setupFeatures(rcEnc->featureInfo_const()); \
266 auto hostSupportsVulkan = goldfish_vk::ResourceTracker::get()->hostSupportsVulkan(); \
267
268 VKAPI_ATTR
EnumerateInstanceExtensionProperties(const char * layer_name,uint32_t * count,VkExtensionProperties * properties)269 VkResult EnumerateInstanceExtensionProperties(
270 const char* layer_name,
271 uint32_t* count,
272 VkExtensionProperties* properties) {
273 AEMU_SCOPED_TRACE("goldfish_vulkan::EnumerateInstanceExtensionProperties");
274
275 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
276
277 if (!hostSupportsVulkan) {
278 return vkstubhal::EnumerateInstanceExtensionProperties(layer_name, count, properties);
279 }
280
281 if (layer_name) {
282 ALOGW(
283 "Driver vkEnumerateInstanceExtensionProperties shouldn't be called "
284 "with a layer name ('%s')",
285 layer_name);
286 }
287
288 VkResult res = goldfish_vk::ResourceTracker::get()->on_vkEnumerateInstanceExtensionProperties(
289 vkEnc, VK_SUCCESS, layer_name, count, properties);
290
291 return res;
292 }
293
294 VKAPI_ATTR
CreateInstance(const VkInstanceCreateInfo * create_info,const VkAllocationCallbacks * allocator,VkInstance * out_instance)295 VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
296 const VkAllocationCallbacks* allocator,
297 VkInstance* out_instance) {
298 AEMU_SCOPED_TRACE("goldfish_vulkan::CreateInstance");
299
300 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
301
302 if (!hostSupportsVulkan) {
303 return vkstubhal::CreateInstance(create_info, allocator, out_instance);
304 }
305
306 VkResult res = vkEnc->vkCreateInstance(create_info, nullptr, out_instance);
307
308 return res;
309 }
310
311 #ifdef VK_USE_PLATFORM_FUCHSIA
312 VKAPI_ATTR
GetMemoryZirconHandleFUCHSIA(VkDevice device,const VkMemoryGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)313 VkResult GetMemoryZirconHandleFUCHSIA(
314 VkDevice device,
315 const VkMemoryGetZirconHandleInfoFUCHSIA* pInfo,
316 uint32_t* pHandle) {
317 AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandleFUCHSIA");
318
319 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
320
321 if (!hostSupportsVulkan) {
322 return vkstubhal::GetMemoryZirconHandleFUCHSIA(device, pInfo, pHandle);
323 }
324
325 VkResult res = goldfish_vk::ResourceTracker::get()->
326 on_vkGetMemoryZirconHandleFUCHSIA(
327 vkEnc, VK_SUCCESS,
328 device, pInfo, pHandle);
329
330 return res;
331 }
332
333 VKAPI_ATTR
GetMemoryZirconHandlePropertiesFUCHSIA(VkDevice device,VkExternalMemoryHandleTypeFlagBits handleType,uint32_t handle,VkMemoryZirconHandlePropertiesFUCHSIA * pProperties)334 VkResult GetMemoryZirconHandlePropertiesFUCHSIA(
335 VkDevice device,
336 VkExternalMemoryHandleTypeFlagBits handleType,
337 uint32_t handle,
338 VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
339 AEMU_SCOPED_TRACE("goldfish_vulkan::GetMemoryZirconHandlePropertiesFUCHSIA");
340
341 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
342
343 if (!hostSupportsVulkan) {
344 return vkstubhal::GetMemoryZirconHandlePropertiesFUCHSIA(
345 device, handleType, handle, pProperties);
346 }
347
348 VkResult res = goldfish_vk::ResourceTracker::get()->
349 on_vkGetMemoryZirconHandlePropertiesFUCHSIA(
350 vkEnc, VK_SUCCESS, device, handleType, handle, pProperties);
351
352 return res;
353 }
354
355 VKAPI_ATTR
GetSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkSemaphoreGetZirconHandleInfoFUCHSIA * pInfo,uint32_t * pHandle)356 VkResult GetSemaphoreZirconHandleFUCHSIA(
357 VkDevice device,
358 const VkSemaphoreGetZirconHandleInfoFUCHSIA* pInfo,
359 uint32_t* pHandle) {
360 AEMU_SCOPED_TRACE("goldfish_vulkan::GetSemaphoreZirconHandleFUCHSIA");
361
362 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
363
364 if (!hostSupportsVulkan) {
365 return vkstubhal::GetSemaphoreZirconHandleFUCHSIA(device, pInfo, pHandle);
366 }
367
368 VkResult res = goldfish_vk::ResourceTracker::get()->
369 on_vkGetSemaphoreZirconHandleFUCHSIA(
370 vkEnc, VK_SUCCESS, device, pInfo, pHandle);
371
372 return res;
373 }
374
375 VKAPI_ATTR
ImportSemaphoreZirconHandleFUCHSIA(VkDevice device,const VkImportSemaphoreZirconHandleInfoFUCHSIA * pInfo)376 VkResult ImportSemaphoreZirconHandleFUCHSIA(
377 VkDevice device,
378 const VkImportSemaphoreZirconHandleInfoFUCHSIA* pInfo) {
379 AEMU_SCOPED_TRACE("goldfish_vulkan::ImportSemaphoreZirconHandleFUCHSIA");
380
381 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
382
383 if (!hostSupportsVulkan) {
384 return vkstubhal::ImportSemaphoreZirconHandleFUCHSIA(device, pInfo);
385 }
386
387 VkResult res = goldfish_vk::ResourceTracker::get()->
388 on_vkImportSemaphoreZirconHandleFUCHSIA(
389 vkEnc, VK_SUCCESS, device, pInfo);
390
391 return res;
392 }
393
394 VKAPI_ATTR
CreateBufferCollectionFUCHSIA(VkDevice device,const VkBufferCollectionCreateInfoFUCHSIA * pInfo,const VkAllocationCallbacks * pAllocator,VkBufferCollectionFUCHSIA * pCollection)395 VkResult CreateBufferCollectionFUCHSIA(
396 VkDevice device,
397 const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
398 const VkAllocationCallbacks* pAllocator,
399 VkBufferCollectionFUCHSIA* pCollection) {
400 AEMU_SCOPED_TRACE("goldfish_vulkan::CreateBufferCollectionFUCHSIA");
401
402 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
403
404 if (!hostSupportsVulkan) {
405 return vkstubhal::CreateBufferCollectionFUCHSIA(device, pInfo, pAllocator, pCollection);
406 }
407
408 VkResult res = goldfish_vk::ResourceTracker::get()->
409 on_vkCreateBufferCollectionFUCHSIA(
410 vkEnc, VK_SUCCESS, device, pInfo, pAllocator, pCollection);
411
412 return res;
413 }
414
415 VKAPI_ATTR
DestroyBufferCollectionFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkAllocationCallbacks * pAllocator)416 void DestroyBufferCollectionFUCHSIA(
417 VkDevice device,
418 VkBufferCollectionFUCHSIA collection,
419 const VkAllocationCallbacks* pAllocator) {
420 AEMU_SCOPED_TRACE("goldfish_vulkan::DestroyBufferCollectionFUCHSIA");
421
422 VK_HOST_CONNECTION()
423
424 if (!hostSupportsVulkan) {
425 vkstubhal::DestroyBufferCollectionFUCHSIA(device, collection, pAllocator);
426 return;
427 }
428
429 goldfish_vk::ResourceTracker::get()->
430 on_vkDestroyBufferCollectionFUCHSIA(
431 vkEnc, VK_SUCCESS, device, collection, pAllocator);
432 }
433
434 VKAPI_ATTR
SetBufferCollectionConstraintsFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,const VkImageCreateInfo * pImageInfo)435 VkResult SetBufferCollectionConstraintsFUCHSIA(
436 VkDevice device,
437 VkBufferCollectionFUCHSIA collection,
438 const VkImageCreateInfo* pImageInfo) {
439 AEMU_SCOPED_TRACE("goldfish_vulkan::SetBufferCollectionConstraintsFUCHSIA");
440
441 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
442
443 if (!hostSupportsVulkan) {
444 return vkstubhal::SetBufferCollectionConstraintsFUCHSIA(device, collection, pImageInfo);
445 }
446
447 VkResult res = goldfish_vk::ResourceTracker::get()->
448 on_vkSetBufferCollectionConstraintsFUCHSIA(
449 vkEnc, VK_SUCCESS, device, collection, pImageInfo);
450
451 return res;
452 }
453
454 VKAPI_ATTR
GetBufferCollectionPropertiesFUCHSIA(VkDevice device,VkBufferCollectionFUCHSIA collection,VkBufferCollectionPropertiesFUCHSIA * pProperties)455 VkResult GetBufferCollectionPropertiesFUCHSIA(
456 VkDevice device,
457 VkBufferCollectionFUCHSIA collection,
458 VkBufferCollectionPropertiesFUCHSIA* pProperties) {
459 AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIA");
460
461 VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
462
463 if (!hostSupportsVulkan) {
464 return vkstubhal::GetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties);
465 }
466
467 VkResult res = goldfish_vk::ResourceTracker::get()->
468 on_vkGetBufferCollectionPropertiesFUCHSIA(
469 vkEnc, VK_SUCCESS, device, collection, pProperties);
470
471 return res;
472 }
473 #endif
474
GetDeviceProcAddr(VkDevice device,const char * name)475 static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
476 AEMU_SCOPED_TRACE("goldfish_vulkan::GetDeviceProcAddr");
477
478 VK_HOST_CONNECTION(nullptr)
479
480 if (!hostSupportsVulkan) {
481 return nullptr;
482 }
483
484 #ifdef VK_USE_PLATFORM_FUCHSIA
485 if (!strcmp(name, "vkGetMemoryZirconHandleFUCHSIA")) {
486 return (PFN_vkVoidFunction)GetMemoryZirconHandleFUCHSIA;
487 }
488 if (!strcmp(name, "vkGetMemoryZirconHandlePropertiesFUCHSIA")) {
489 return (PFN_vkVoidFunction)GetMemoryZirconHandlePropertiesFUCHSIA;
490 }
491 if (!strcmp(name, "vkGetSemaphoreZirconHandleFUCHSIA")) {
492 return (PFN_vkVoidFunction)GetSemaphoreZirconHandleFUCHSIA;
493 }
494 if (!strcmp(name, "vkImportSemaphoreZirconHandleFUCHSIA")) {
495 return (PFN_vkVoidFunction)ImportSemaphoreZirconHandleFUCHSIA;
496 }
497 if (!strcmp(name, "vkCreateBufferCollectionFUCHSIA")) {
498 return (PFN_vkVoidFunction)CreateBufferCollectionFUCHSIA;
499 }
500 if (!strcmp(name, "vkDestroyBufferCollectionFUCHSIA")) {
501 return (PFN_vkVoidFunction)DestroyBufferCollectionFUCHSIA;
502 }
503 if (!strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA")) {
504 return (PFN_vkVoidFunction)SetBufferCollectionConstraintsFUCHSIA;
505 }
506 if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) {
507 return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA;
508 }
509 #endif
510 if (!strcmp(name, "vkGetDeviceProcAddr")) {
511 return (PFN_vkVoidFunction)(GetDeviceProcAddr);
512 }
513 return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_device_proc_address(device, name));
514 }
515
516 VKAPI_ATTR
GetInstanceProcAddr(VkInstance instance,const char * name)517 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
518 AEMU_SCOPED_TRACE("goldfish_vulkan::GetInstanceProcAddr");
519
520 VK_HOST_CONNECTION(nullptr)
521
522 if (!hostSupportsVulkan) {
523 return vkstubhal::GetInstanceProcAddr(instance, name);
524 }
525
526 if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
527 return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
528 }
529 if (!strcmp(name, "vkCreateInstance")) {
530 return (PFN_vkVoidFunction)CreateInstance;
531 }
532 if (!strcmp(name, "vkGetDeviceProcAddr")) {
533 return (PFN_vkVoidFunction)(GetDeviceProcAddr);
534 }
535 return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_instance_proc_address(instance, name));
536 }
537
538 #ifdef VK_USE_PLATFORM_ANDROID_KHR
539
540 hwvulkan_device_t goldfish_vulkan_device = {
541 .common = {
542 .tag = HARDWARE_DEVICE_TAG,
543 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
544 .module = &HAL_MODULE_INFO_SYM.common,
545 .close = CloseDevice,
546 },
547 .EnumerateInstanceExtensionProperties = EnumerateInstanceExtensionProperties,
548 .CreateInstance = CreateInstance,
549 .GetInstanceProcAddr = GetInstanceProcAddr,
550 };
551
OpenDevice(const hw_module_t *,const char * id,hw_device_t ** device)552 int OpenDevice(const hw_module_t* /*module*/,
553 const char* id,
554 hw_device_t** device) {
555 AEMU_SCOPED_TRACE("goldfish_vulkan::OpenDevice");
556
557 if (strcmp(id, HWVULKAN_DEVICE_0) == 0) {
558 *device = &goldfish_vulkan_device.common;
559 goldfish_vk::ResourceTracker::get();
560 return 0;
561 }
562 return -ENOENT;
563 }
564
565 #endif
566
567 #ifdef VK_USE_PLATFORM_FUCHSIA
568
569 class VulkanDevice {
570 public:
VulkanDevice()571 VulkanDevice() {
572 goldfish_vk::ResourceTracker::get();
573 }
574
GetInstance()575 static VulkanDevice& GetInstance() {
576 static VulkanDevice g_instance;
577 return g_instance;
578 }
579
GetInstanceProcAddr(VkInstance instance,const char * name)580 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
581 return ::GetInstanceProcAddr(instance, name);
582 }
583 };
584
585 extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance,const char * name)586 vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
587 return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
588 }
589
590 extern "C" __attribute__((visibility("default"))) VkResult
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)591 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
592 *pSupportedVersion = std::min(*pSupportedVersion, 3u);
593 return VK_SUCCESS;
594 }
595
596 #endif
597
598 } // namespace
599