1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright © 2017, Google Inc.
5 *
6 * SPDX-License-Identifier: MIT
7 */
8
9 #include "nvk_private.h"
10 #include <hardware/gralloc.h>
11
12 #if ANDROID_API_LEVEL >= 26
13 #include <hardware/gralloc1.h>
14 #endif
15
16 #include <hardware/hardware.h>
17 #include <hardware/hwvulkan.h>
18 #include <vulkan/vk_icd.h>
19
20 #include "util/log.h"
21 #include "util/u_gralloc/u_gralloc.h"
22 #include "nvk_android.h"
23 #include "nvk_entrypoints.h"
24 #include "vk_android.h"
25
26 #include "util/libsync.h"
27 #include "util/os_file.h"
28 #include "vk_device.h"
29 #include "vk_fence.h"
30 #include "vk_queue.h"
31 #include "vk_semaphore.h"
32
33 static int nvk_hal_open(const struct hw_module_t *mod, const char *id,
34 struct hw_device_t **dev);
35 static int nvk_hal_close(struct hw_device_t *dev);
36
37 static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
38
39 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
40 .common =
41 {
42 .tag = HARDWARE_MODULE_TAG,
43 .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
44 .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
45 .id = HWVULKAN_HARDWARE_MODULE_ID,
46 .name = "NVK Vulkan HAL",
47 .author = "Mesa3D",
48 .methods =
49 &(hw_module_methods_t){
50 .open = nvk_hal_open,
51 },
52 },
53 };
54
55 static int
nvk_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)56 nvk_hal_open(const struct hw_module_t *mod, const char *id,
57 struct hw_device_t **dev)
58 {
59 assert(mod == &HAL_MODULE_INFO_SYM.common);
60 assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
61
62 hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
63 if (!hal_dev)
64 return -1;
65
66 *hal_dev = (hwvulkan_device_t){
67 .common =
68 {
69 .tag = HARDWARE_DEVICE_TAG,
70 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
71 .module = &HAL_MODULE_INFO_SYM.common,
72 .close = nvk_hal_close,
73 },
74 .EnumerateInstanceExtensionProperties =
75 nvk_EnumerateInstanceExtensionProperties,
76 .CreateInstance = nvk_CreateInstance,
77 .GetInstanceProcAddr = nvk_GetInstanceProcAddr,
78 };
79
80 mesa_logi("nvk: Warning: Android Vulkan implementation is experimental");
81
82 *dev = &hal_dev->common;
83 return 0;
84 }
85
86 static int
nvk_hal_close(struct hw_device_t * dev)87 nvk_hal_close(struct hw_device_t *dev)
88 {
89 /* hwvulkan.h claims that hw_device_t::close() is never called. */
90 return -1;
91 }
92
93 VKAPI_ATTR VkResult VKAPI_CALL
nvk_AcquireImageANDROID(VkDevice _device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)94 nvk_AcquireImageANDROID(VkDevice _device,
95 VkImage image,
96 int nativeFenceFd,
97 VkSemaphore semaphore,
98 VkFence fence)
99 {
100 VK_FROM_HANDLE(vk_device, vk_device, _device);
101 VkResult result = VK_SUCCESS;
102
103 if(nativeFenceFd >= 0)
104 {
105 sync_wait(nativeFenceFd, -1);
106 close(nativeFenceFd);
107 }
108
109 if(fence != VK_NULL_HANDLE)
110 {
111 VK_FROM_HANDLE(vk_fence, vk_fence, fence);
112 result = vk_sync_signal(vk_device, &vk_fence->permanent, 0);
113 }
114
115 if(result == VK_SUCCESS && semaphore != VK_NULL_HANDLE)
116 {
117 VK_FROM_HANDLE(vk_semaphore, vk_semaphore, semaphore);
118 result = vk_sync_signal(vk_device, &vk_semaphore->permanent, 0);
119 }
120
121 return result;
122 }
123
124 VKAPI_ATTR VkResult VKAPI_CALL
nvk_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)125 nvk_QueueSignalReleaseImageANDROID(VkQueue _queue,
126 uint32_t waitSemaphoreCount,
127 const VkSemaphore *pWaitSemaphores,
128 VkImage image,
129 int *pNativeFenceFd)
130 {
131 VK_FROM_HANDLE(vk_queue, queue, _queue);
132 struct vk_device *device = queue->base.device;
133
134 device->dispatch_table.QueueWaitIdle(_queue);
135
136 *pNativeFenceFd = -1;
137
138 return VK_SUCCESS;
139 }
140