xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/lavapipe/lvp_android.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2024, Google Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <lvp_private.h>
25 #include <hardware/gralloc.h>
26 
27 #if ANDROID_API_LEVEL >= 26
28 #include <hardware/gralloc1.h>
29 #endif
30 
31 #include <hardware/hardware.h>
32 #include <hardware/hwvulkan.h>
33 #include <vulkan/vk_android_native_buffer.h>
34 #include <vulkan/vk_icd.h>
35 
36 #include "util/libsync.h"
37 #include "util/os_file.h"
38 #include "util/libsync.h"
39 
40 #include "vk_fence.h"
41 #include "vk_semaphore.h"
42 #include "vk_android.h"
43 
44 static int
45 lvp_hal_open(const struct hw_module_t *mod,
46             const char *id,
47             struct hw_device_t **dev);
48 static int
49 lvp_hal_close(struct hw_device_t *dev);
50 
51 static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
52 
53 struct hw_module_methods_t HAL_MODULE_METHODS = {
54    .open = lvp_hal_open,
55 };
56 
57 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
58    .common =
59      {
60        .tag = HARDWARE_MODULE_TAG,
61        .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
62        .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
63        .id = HWVULKAN_HARDWARE_MODULE_ID,
64        .name = "Lavapipe Vulkan HAL",
65        .author = "Mesa3D",
66        .methods = &HAL_MODULE_METHODS,
67      },
68 };
69 
70 static int
lvp_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)71 lvp_hal_open(const struct hw_module_t *mod,
72             const char *id,
73             struct hw_device_t **dev)
74 {
75    assert(mod == &HAL_MODULE_INFO_SYM.common);
76    assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
77 
78    hwvulkan_device_t *hal_dev = (hwvulkan_device_t *) malloc(sizeof(*hal_dev));
79    if (!hal_dev)
80       return -1;
81 
82    *hal_dev = (hwvulkan_device_t){
83       .common =
84         {
85           .tag = HARDWARE_DEVICE_TAG,
86           .version = HWVULKAN_DEVICE_API_VERSION_0_1,
87           .module = &HAL_MODULE_INFO_SYM.common,
88           .close = lvp_hal_close,
89         },
90       .EnumerateInstanceExtensionProperties =
91         lvp_EnumerateInstanceExtensionProperties,
92       .CreateInstance = lvp_CreateInstance,
93       .GetInstanceProcAddr = lvp_GetInstanceProcAddr,
94    };
95 
96    *dev = &hal_dev->common;
97    return 0;
98 }
99 
100 static int
lvp_hal_close(struct hw_device_t * dev)101 lvp_hal_close(struct hw_device_t *dev)
102 {
103    /* hwvulkan.h claims that hw_device_t::close() is never called. */
104    return -1;
105 }
106 
107 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)108 lvp_GetSwapchainGrallocUsageANDROID(VkDevice device_h,
109                                    VkFormat format,
110                                    VkImageUsageFlags imageUsage,
111                                    int *grallocUsage)
112 {
113    *grallocUsage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
114 
115    return VK_SUCCESS;
116 }
117 
118 #if ANDROID_API_LEVEL >= 26
119 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)120 lvp_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,
121                                     VkFormat format,
122                                     VkImageUsageFlags imageUsage,
123                                     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
124                                     uint64_t *grallocConsumerUsage,
125                                     uint64_t *grallocProducerUsage)
126 {
127    *grallocConsumerUsage = 0;
128    *grallocProducerUsage = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
129 
130    return VK_SUCCESS;
131 }
132 #endif
133 
134 VKAPI_ATTR VkResult VKAPI_CALL
lvp_AcquireImageANDROID(VkDevice _device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)135 lvp_AcquireImageANDROID(VkDevice _device,
136                         VkImage image,
137                         int nativeFenceFd,
138                         VkSemaphore semaphore,
139                         VkFence fence)
140 {
141    VK_FROM_HANDLE(vk_device, vk_device, _device);
142    VkResult result = VK_SUCCESS;
143 
144    if(nativeFenceFd >= 0)
145    {
146       sync_wait(nativeFenceFd, -1);
147       close(nativeFenceFd);
148    }
149 
150    if(fence != VK_NULL_HANDLE)
151    {
152       VK_FROM_HANDLE(vk_fence, vk_fence, fence);
153       result = vk_sync_signal(vk_device, &vk_fence->permanent, 0);
154    }
155 
156    if(result == VK_SUCCESS && semaphore != VK_NULL_HANDLE)
157    {
158       VK_FROM_HANDLE(vk_semaphore, vk_semaphore, semaphore);
159       result = vk_sync_signal(vk_device, &vk_semaphore->permanent, 0);
160    }
161 
162    return result;
163 }
164 
165 VKAPI_ATTR VkResult VKAPI_CALL
lvp_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)166 lvp_QueueSignalReleaseImageANDROID(VkQueue _queue,
167                                    uint32_t waitSemaphoreCount,
168                                    const VkSemaphore *pWaitSemaphores,
169                                    VkImage image,
170                                    int *pNativeFenceFd)
171 {
172    VK_FROM_HANDLE(vk_queue, queue, _queue);
173    struct vk_device *device = queue->base.device;
174 
175    device->dispatch_table.QueueWaitIdle(_queue);
176 
177    *pNativeFenceFd = -1;
178 
179    return VK_SUCCESS;
180 }
181 
182 VkResult
lvp_import_ahb_memory(struct lvp_device * device,struct lvp_device_memory * mem,const VkImportAndroidHardwareBufferInfoANDROID * info)183 lvp_import_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
184                       const VkImportAndroidHardwareBufferInfoANDROID *info)
185 {
186    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
187    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
188    if (dma_buf < 0)
189       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
190 
191    uint64_t size;
192    int result = device->pscreen->import_memory_fd(device->pscreen, dma_buf, (struct pipe_memory_allocation**)&mem->pmem, &size, true);
193    if (!result)
194       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
195 
196    AHardwareBuffer_acquire(info->buffer);
197    mem->android_hardware_buffer = info->buffer;
198    mem->size = size;
199    mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
200 
201    return VK_SUCCESS;
202 }
203 
204 VkResult
lvp_create_ahb_memory(struct lvp_device * device,struct lvp_device_memory * mem,const VkMemoryAllocateInfo * pAllocateInfo)205 lvp_create_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
206                       const VkMemoryAllocateInfo *pAllocateInfo)
207 {
208    mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
209    if (mem->android_hardware_buffer == NULL)
210       return VK_ERROR_OUT_OF_HOST_MEMORY;
211 
212    const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
213       .buffer = mem->android_hardware_buffer,
214    };
215 
216    VkResult result = lvp_import_ahb_memory(device, mem, &import_info);
217 
218    /* Release a reference to avoid leak for AHB allocation. */
219    AHardwareBuffer_release(mem->android_hardware_buffer);
220 
221    return result;
222 }
223