• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <hardware/gralloc.h>
25 
26 #if ANDROID_API_LEVEL >= 26
27 #include <hardware/gralloc1.h>
28 #endif
29 
30 #include <hardware/hardware.h>
31 #include <hardware/hwvulkan.h>
32 #include <vulkan/vk_android_native_buffer.h>
33 #include <vulkan/vk_icd.h>
34 
35 #include "util/libsync.h"
36 #include "util/os_file.h"
37 #include "util/libsync.h"
38 
39 #include "vk_fence.h"
40 #include "vk_semaphore.h"
41 #include "vk_android.h"
42 
43 #include "lvp_private.h"
44 
45 static int
46 lvp_hal_open(const struct hw_module_t *mod,
47             const char *id,
48             struct hw_device_t **dev);
49 static int
50 lvp_hal_close(struct hw_device_t *dev);
51 
52 static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
53 
54 struct hw_module_methods_t HAL_MODULE_METHODS = {
55    .open = lvp_hal_open,
56 };
57 
58 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
59    .common =
60      {
61        .tag = HARDWARE_MODULE_TAG,
62        .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
63        .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
64        .id = HWVULKAN_HARDWARE_MODULE_ID,
65        .name = "Lavapipe Vulkan HAL",
66        .author = "Mesa3D",
67        .methods = &HAL_MODULE_METHODS,
68      },
69 };
70 
71 static int
lvp_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)72 lvp_hal_open(const struct hw_module_t *mod,
73             const char *id,
74             struct hw_device_t **dev)
75 {
76    assert(mod == &HAL_MODULE_INFO_SYM.common);
77    assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
78 
79    hwvulkan_device_t *hal_dev = (hwvulkan_device_t *) malloc(sizeof(*hal_dev));
80    if (!hal_dev)
81       return -1;
82 
83    *hal_dev = (hwvulkan_device_t){
84       .common =
85         {
86           .tag = HARDWARE_DEVICE_TAG,
87           .version = HWVULKAN_DEVICE_API_VERSION_0_1,
88           .module = &HAL_MODULE_INFO_SYM.common,
89           .close = lvp_hal_close,
90         },
91       .EnumerateInstanceExtensionProperties =
92         lvp_EnumerateInstanceExtensionProperties,
93       .CreateInstance = lvp_CreateInstance,
94       .GetInstanceProcAddr = lvp_GetInstanceProcAddr,
95    };
96 
97    *dev = &hal_dev->common;
98    return 0;
99 }
100 
101 static int
lvp_hal_close(struct hw_device_t * dev)102 lvp_hal_close(struct hw_device_t *dev)
103 {
104    /* hwvulkan.h claims that hw_device_t::close() is never called. */
105    return -1;
106 }
107 
108 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)109 lvp_GetSwapchainGrallocUsageANDROID(VkDevice device_h,
110                                    VkFormat format,
111                                    VkImageUsageFlags imageUsage,
112                                    int *grallocUsage)
113 {
114    *grallocUsage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
115 
116    return VK_SUCCESS;
117 }
118 
119 #if ANDROID_API_LEVEL >= 26
120 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)121 lvp_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,
122                                     VkFormat format,
123                                     VkImageUsageFlags imageUsage,
124                                     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
125                                     uint64_t *grallocConsumerUsage,
126                                     uint64_t *grallocProducerUsage)
127 {
128    *grallocConsumerUsage = 0;
129    *grallocProducerUsage = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
130 
131    return VK_SUCCESS;
132 }
133 #endif
134 
135 VKAPI_ATTR VkResult VKAPI_CALL
lvp_AcquireImageANDROID(VkDevice _device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)136 lvp_AcquireImageANDROID(VkDevice _device,
137                         VkImage image,
138                         int nativeFenceFd,
139                         VkSemaphore semaphore,
140                         VkFence fence)
141 {
142    VK_FROM_HANDLE(vk_device, vk_device, _device);
143    VkResult result = VK_SUCCESS;
144 
145    if(nativeFenceFd >= 0)
146    {
147       sync_wait(nativeFenceFd, -1);
148       close(nativeFenceFd);
149    }
150 
151    if(fence != VK_NULL_HANDLE)
152    {
153       VK_FROM_HANDLE(vk_fence, vk_fence, fence);
154       result = vk_sync_signal(vk_device, &vk_fence->permanent, 0);
155    }
156 
157    if(result == VK_SUCCESS && semaphore != VK_NULL_HANDLE)
158    {
159       VK_FROM_HANDLE(vk_semaphore, vk_semaphore, semaphore);
160       result = vk_sync_signal(vk_device, &vk_semaphore->permanent, 0);
161    }
162 
163    return result;
164 }
165 
166 VKAPI_ATTR VkResult VKAPI_CALL
lvp_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)167 lvp_QueueSignalReleaseImageANDROID(VkQueue _queue,
168                                    uint32_t waitSemaphoreCount,
169                                    const VkSemaphore *pWaitSemaphores,
170                                    VkImage image,
171                                    int *pNativeFenceFd)
172 {
173    VK_FROM_HANDLE(vk_queue, queue, _queue);
174    struct vk_device *device = queue->base.device;
175 
176    device->dispatch_table.QueueWaitIdle(_queue);
177 
178    *pNativeFenceFd = -1;
179 
180    return VK_SUCCESS;
181 }
182 
183 VkResult
lvp_import_ahb_memory(struct lvp_device * device,struct lvp_device_memory * mem,const VkImportAndroidHardwareBufferInfoANDROID * info)184 lvp_import_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
185                       const VkImportAndroidHardwareBufferInfoANDROID *info)
186 {
187    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
188    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
189    if (dma_buf < 0)
190       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
191 
192    uint64_t size;
193    int result = device->pscreen->import_memory_fd(device->pscreen, dma_buf, (struct pipe_memory_allocation**)&mem->pmem, &size, true);
194    if (!result)
195       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
196 
197    AHardwareBuffer_acquire(info->buffer);
198    mem->android_hardware_buffer = info->buffer;
199    mem->size = size;
200    mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
201 
202    return VK_SUCCESS;
203 }
204 
205 VkResult
lvp_create_ahb_memory(struct lvp_device * device,struct lvp_device_memory * mem,const VkMemoryAllocateInfo * pAllocateInfo)206 lvp_create_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
207                       const VkMemoryAllocateInfo *pAllocateInfo)
208 {
209    mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
210    if (mem->android_hardware_buffer == NULL)
211       return VK_ERROR_OUT_OF_HOST_MEMORY;
212 
213    const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
214       .buffer = mem->android_hardware_buffer,
215    };
216 
217    VkResult result = lvp_import_ahb_memory(device, mem, &import_info);
218 
219    /* Release a reference to avoid leak for AHB allocation. */
220    AHardwareBuffer_release(mem->android_hardware_buffer);
221 
222    return result;
223 }
224