xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_android.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Intel Corporation
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 "vk_android.h"
25 
26 #include "vk_alloc.h"
27 #include "vk_common_entrypoints.h"
28 #include "vk_device.h"
29 #include "vk_physical_device.h"
30 #include "vk_image.h"
31 #include "vk_log.h"
32 #include "vk_queue.h"
33 #include "vk_util.h"
34 
35 #include "vk_enum_defines.h"
36 
37 #include "drm-uapi/drm_fourcc.h"
38 #include "util/libsync.h"
39 #include "util/os_file.h"
40 #include "util/u_gralloc/u_gralloc.h"
41 #include "util/log.h"
42 
43 #include <hardware/gralloc.h>
44 
45 #if ANDROID_API_LEVEL >= 26
46 #include <hardware/gralloc1.h>
47 #endif
48 
49 #include <unistd.h>
50 
51 static struct u_gralloc *u_gralloc;
52 
53 struct u_gralloc *
vk_android_get_ugralloc(void)54 vk_android_get_ugralloc(void)
55 {
56    return u_gralloc;
57 }
58 
59 struct u_gralloc *
vk_android_init_ugralloc(void)60 vk_android_init_ugralloc(void)
61 {
62    u_gralloc = u_gralloc_create(U_GRALLOC_TYPE_AUTO);
63 
64    return u_gralloc;
65 }
66 
67 void
vk_android_destroy_ugralloc(void)68 vk_android_destroy_ugralloc(void)
69 {
70    u_gralloc_destroy(&u_gralloc);
71 }
72 
73 /* If any bits in test_mask are set, then unset them and return true. */
74 static inline bool
unmask32(uint32_t * inout_mask,uint32_t test_mask)75 unmask32(uint32_t *inout_mask, uint32_t test_mask)
76 {
77    uint32_t orig_mask = *inout_mask;
78    *inout_mask &= ~test_mask;
79    return *inout_mask != orig_mask;
80 }
81 
82 static VkResult
format_supported_with_usage(struct vk_device * device,VkFormat format,VkImageUsageFlags imageUsage)83 format_supported_with_usage(struct vk_device *device, VkFormat format,
84                             VkImageUsageFlags imageUsage)
85 {
86    struct vk_physical_device *physical = device->physical;
87    VkResult result;
88 
89    const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
90       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
91       .format = format,
92       .type = VK_IMAGE_TYPE_2D,
93       .tiling = VK_IMAGE_TILING_OPTIMAL,
94       .usage = imageUsage,
95    };
96 
97    VkImageFormatProperties2 image_format_props = {
98       .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
99    };
100 
101    /* Check that requested format and usage are supported. */
102    result = physical->dispatch_table.GetPhysicalDeviceImageFormatProperties2(
103       (VkPhysicalDevice)physical, &image_format_info, &image_format_props);
104    if (result != VK_SUCCESS)
105       return result;
106 
107    return VK_SUCCESS;
108 }
109 
110 static VkResult
setup_gralloc0_usage(struct vk_device * device,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)111 setup_gralloc0_usage(struct vk_device *device, VkFormat format,
112                      VkImageUsageFlags imageUsage, int *grallocUsage)
113 {
114    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT |
115                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
116       *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
117 
118    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
119                                 VK_IMAGE_USAGE_SAMPLED_BIT |
120                                 VK_IMAGE_USAGE_STORAGE_BIT |
121                                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
122       *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
123 
124    /* All VkImageUsageFlags not explicitly checked here are unsupported for
125     * gralloc swapchains.
126     */
127    if (imageUsage != 0) {
128       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
129                        "unsupported VkImageUsageFlags(0x%x) for gralloc "
130                        "swapchain",
131                        imageUsage);
132    }
133 
134    *grallocUsage |= GRALLOC_USAGE_HW_COMPOSER;
135 
136    if (*grallocUsage == 0)
137       return VK_ERROR_FORMAT_NOT_SUPPORTED;
138 
139    return VK_SUCCESS;
140 }
141 
142 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)143 vk_common_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
144                                           VkImageUsageFlags imageUsage,
145                                           int *grallocUsage)
146 {
147    VK_FROM_HANDLE(vk_device, device, device_h);
148    VkResult result;
149 
150    result = format_supported_with_usage(device, format, imageUsage);
151    if (result != VK_SUCCESS)
152       return result;
153 
154    *grallocUsage = 0;
155    return setup_gralloc0_usage(device, format, imageUsage, grallocUsage);
156 }
157 
158 #if ANDROID_API_LEVEL >= 26
159 #include <vndk/hardware_buffer.h>
160 
161 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)162 vk_common_GetSwapchainGrallocUsage2ANDROID(
163    VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
164    VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
165    uint64_t *grallocConsumerUsage, uint64_t *grallocProducerUsage)
166 {
167    VK_FROM_HANDLE(vk_device, device, device_h);
168    VkResult result;
169 
170    *grallocConsumerUsage = 0;
171    *grallocProducerUsage = 0;
172 
173    result = format_supported_with_usage(device, format, imageUsage);
174    if (result != VK_SUCCESS)
175       return result;
176 
177    int32_t grallocUsage = 0;
178    result = setup_gralloc0_usage(device, format, imageUsage, &grallocUsage);
179    if (result != VK_SUCCESS)
180       return result;
181 
182    /* Setup gralloc1 usage flags from gralloc0 flags. */
183 
184    if (grallocUsage & GRALLOC_USAGE_HW_RENDER)
185       *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
186 
187    if (grallocUsage & GRALLOC_USAGE_HW_TEXTURE)
188       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
189 
190    if (grallocUsage & GRALLOC_USAGE_HW_COMPOSER) {
191       /* GPU composing case */
192       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
193       /* Hardware composing case */
194       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
195    }
196 
197    if ((swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID) &&
198        vk_android_get_ugralloc() != NULL) {
199       uint64_t front_rendering_usage = 0;
200       u_gralloc_get_front_rendering_usage(vk_android_get_ugralloc(),
201                                           &front_rendering_usage);
202       *grallocProducerUsage |= front_rendering_usage;
203    }
204 
205    return VK_SUCCESS;
206 }
207 
208 static VkResult
vk_gralloc_to_drm_explicit_layout(struct u_gralloc_buffer_handle * in_hnd,VkImageDrmFormatModifierExplicitCreateInfoEXT * out,VkSubresourceLayout * out_layouts,int max_planes)209 vk_gralloc_to_drm_explicit_layout(
210    struct u_gralloc_buffer_handle *in_hnd,
211    VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
212    VkSubresourceLayout *out_layouts, int max_planes)
213 {
214    struct u_gralloc_buffer_basic_info info;
215    struct u_gralloc *u_gralloc = vk_android_get_ugralloc();
216    assert(u_gralloc);
217 
218    if (u_gralloc_get_buffer_basic_info(u_gralloc, in_hnd, &info) != 0)
219       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
220 
221    if (info.num_planes > max_planes)
222       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
223 
224    bool is_disjoint = false;
225    for (size_t i = 1; i < info.num_planes; i++) {
226       if (info.offsets[i] == 0) {
227          is_disjoint = true;
228          break;
229       }
230    }
231 
232    if (is_disjoint) {
233       /* We don't support disjoint planes yet */
234       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
235    }
236 
237    memset(out, 0, sizeof(*out));
238    memset(out_layouts, 0, sizeof(*out_layouts) * max_planes);
239 
240    out->sType =
241       VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
242    out->pPlaneLayouts = out_layouts;
243 
244    out->drmFormatModifier = info.modifier;
245    out->drmFormatModifierPlaneCount = info.num_planes;
246    for (size_t i = 0; i < info.num_planes; i++) {
247       out_layouts[i].offset = info.offsets[i];
248       out_layouts[i].rowPitch = info.strides[i];
249    }
250 
251    if (info.drm_fourcc == DRM_FORMAT_YVU420) {
252       /* Swap the U and V planes to match the
253        * VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM */
254       VkSubresourceLayout tmp = out_layouts[1];
255       out_layouts[1] = out_layouts[2];
256       out_layouts[2] = tmp;
257    }
258 
259    return VK_SUCCESS;
260 }
261 
262 VkResult
vk_android_import_anb(struct vk_device * device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc,struct vk_image * image)263 vk_android_import_anb(struct vk_device *device,
264                       const VkImageCreateInfo *pCreateInfo,
265                       const VkAllocationCallbacks *alloc,
266                       struct vk_image *image)
267 {
268    VkResult result;
269 
270    const VkNativeBufferANDROID *native_buffer =
271       vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
272 
273    assert(native_buffer);
274    assert(native_buffer->handle);
275    assert(native_buffer->handle->numFds > 0);
276 
277    const VkMemoryDedicatedAllocateInfo ded_alloc = {
278       .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
279       .pNext = NULL,
280       .buffer = VK_NULL_HANDLE,
281       .image = (VkImage)image};
282 
283    const VkImportMemoryFdInfoKHR import_info = {
284       .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
285       .pNext = &ded_alloc,
286       .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
287       .fd = os_dupfd_cloexec(native_buffer->handle->data[0]),
288    };
289 
290    result = device->dispatch_table.AllocateMemory(
291       (VkDevice)device,
292       &(VkMemoryAllocateInfo){
293          .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
294          .pNext = &import_info,
295          .allocationSize = lseek(import_info.fd, 0, SEEK_END),
296          .memoryTypeIndex = 0, /* Should we be smarter here? */
297       },
298       alloc, &image->anb_memory);
299 
300    if (result != VK_SUCCESS) {
301       close(import_info.fd);
302       return result;
303    }
304 
305    VkBindImageMemoryInfo bind_info = {
306       .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
307       .image = (VkImage)image,
308       .memory = image->anb_memory,
309       .memoryOffset = 0,
310    };
311 
312    return device->dispatch_table.BindImageMemory2((VkDevice)device, 1, &bind_info);
313 }
314 
315 VkResult
vk_android_get_anb_layout(const VkImageCreateInfo * pCreateInfo,VkImageDrmFormatModifierExplicitCreateInfoEXT * out,VkSubresourceLayout * out_layouts,int max_planes)316 vk_android_get_anb_layout(
317    const VkImageCreateInfo *pCreateInfo,
318    VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
319    VkSubresourceLayout *out_layouts, int max_planes)
320 {
321    const VkNativeBufferANDROID *native_buffer =
322       vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
323 
324    struct u_gralloc_buffer_handle gr_handle = {
325       .handle = native_buffer->handle,
326       .hal_format = native_buffer->format,
327       .pixel_stride = native_buffer->stride,
328    };
329 
330    return vk_gralloc_to_drm_explicit_layout(&gr_handle, out,
331                                             out_layouts, max_planes);
332 }
333 
334 VkResult
vk_android_get_ahb_layout(struct AHardwareBuffer * ahardware_buffer,VkImageDrmFormatModifierExplicitCreateInfoEXT * out,VkSubresourceLayout * out_layouts,int max_planes)335 vk_android_get_ahb_layout(
336    struct AHardwareBuffer *ahardware_buffer,
337    VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
338    VkSubresourceLayout *out_layouts, int max_planes)
339 {
340    AHardwareBuffer_Desc description;
341    const native_handle_t *handle =
342       AHardwareBuffer_getNativeHandle(ahardware_buffer);
343 
344    AHardwareBuffer_describe(ahardware_buffer, &description);
345 
346    struct u_gralloc_buffer_handle gr_handle = {
347       .handle = handle,
348       .pixel_stride = description.stride,
349       .hal_format = description.format,
350    };
351 
352    return vk_gralloc_to_drm_explicit_layout(&gr_handle, out,
353                                             out_layouts, max_planes);
354 }
355 
356 /* From the Android hardware_buffer.h header:
357  *
358  *    "The buffer will be written to by the GPU as a framebuffer attachment.
359  *
360  *    Note that the name of this flag is somewhat misleading: it does not
361  *    imply that the buffer contains a color format. A buffer with depth or
362  *    stencil format that will be used as a framebuffer attachment should
363  *    also have this flag. Use the equivalent flag
364  *    AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER to avoid this confusion."
365  *
366  * The flag was renamed from COLOR_OUTPUT to FRAMEBUFFER at Android API
367  * version 29.
368  */
369 #if ANDROID_API_LEVEL < 29
370 #define AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT
371 #endif
372 
373 /* Convert an AHB format to a VkFormat, based on the "AHardwareBuffer Format
374  * Equivalence" table in Vulkan spec.
375  *
376  * Note that this only covers a subset of AHB formats defined in NDK.  Drivers
377  * can support more AHB formats, including private ones.
378  */
379 VkFormat
vk_ahb_format_to_image_format(uint32_t ahb_format)380 vk_ahb_format_to_image_format(uint32_t ahb_format)
381 {
382    switch (ahb_format) {
383    case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
384    case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
385       return VK_FORMAT_R8G8B8A8_UNORM;
386    case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
387       return VK_FORMAT_R8G8B8_UNORM;
388    case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
389       return VK_FORMAT_R5G6B5_UNORM_PACK16;
390    case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
391       return VK_FORMAT_R16G16B16A16_SFLOAT;
392    case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
393       return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
394    case AHARDWAREBUFFER_FORMAT_D16_UNORM:
395       return VK_FORMAT_D16_UNORM;
396    case AHARDWAREBUFFER_FORMAT_D24_UNORM:
397       return VK_FORMAT_X8_D24_UNORM_PACK32;
398    case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
399       return VK_FORMAT_D24_UNORM_S8_UINT;
400    case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
401       return VK_FORMAT_D32_SFLOAT;
402    case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
403       return VK_FORMAT_D32_SFLOAT_S8_UINT;
404    case AHARDWAREBUFFER_FORMAT_S8_UINT:
405       return VK_FORMAT_S8_UINT;
406 #if ANDROID_API_LEVEL >= 33
407    case AHARDWAREBUFFER_FORMAT_R8_UNORM:
408       return VK_FORMAT_R8_UNORM;
409 #endif
410    default:
411       return VK_FORMAT_UNDEFINED;
412    }
413 }
414 
415 /* Convert a VkFormat to an AHB format, based on the "AHardwareBuffer Format
416  * Equivalence" table in Vulkan spec.
417  *
418  * Note that this only covers a subset of AHB formats defined in NDK.  Drivers
419  * can support more AHB formats, including private ones.
420  */
421 uint32_t
vk_image_format_to_ahb_format(VkFormat vk_format)422 vk_image_format_to_ahb_format(VkFormat vk_format)
423 {
424    switch (vk_format) {
425    case VK_FORMAT_R8G8B8A8_UNORM:
426       return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
427    case VK_FORMAT_R8G8B8_UNORM:
428       return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
429    case VK_FORMAT_R5G6B5_UNORM_PACK16:
430       return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
431    case VK_FORMAT_R16G16B16A16_SFLOAT:
432       return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
433    case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
434       return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
435    case VK_FORMAT_D16_UNORM:
436       return AHARDWAREBUFFER_FORMAT_D16_UNORM;
437    case VK_FORMAT_X8_D24_UNORM_PACK32:
438       return AHARDWAREBUFFER_FORMAT_D24_UNORM;
439    case VK_FORMAT_D24_UNORM_S8_UINT:
440       return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
441    case VK_FORMAT_D32_SFLOAT:
442       return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
443    case VK_FORMAT_D32_SFLOAT_S8_UINT:
444       return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
445    case VK_FORMAT_S8_UINT:
446       return AHARDWAREBUFFER_FORMAT_S8_UINT;
447 #if ANDROID_API_LEVEL >= 33
448    case VK_FORMAT_R8_UNORM:
449       return AHARDWAREBUFFER_FORMAT_R8_UNORM;
450 #endif
451    default:
452       return 0;
453    }
454 }
455 
456 /* Construct ahw usage mask from image usage bits, see
457  * 'AHardwareBuffer Usage Equivalence' in Vulkan spec.
458  */
459 uint64_t
vk_image_usage_to_ahb_usage(const VkImageCreateFlags vk_create,const VkImageUsageFlags vk_usage)460 vk_image_usage_to_ahb_usage(const VkImageCreateFlags vk_create,
461                             const VkImageUsageFlags vk_usage)
462 {
463    uint64_t ahb_usage = 0;
464    if (vk_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
465                    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
466       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
467 
468    if (vk_usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
469                    VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
470       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
471 
472    if (vk_usage & VK_IMAGE_USAGE_STORAGE_BIT)
473       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
474 
475    if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
476       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
477 
478    if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
479       ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
480 
481    /* No usage bits set - set at least one GPU usage. */
482    if (ahb_usage == 0)
483       ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
484 
485    return ahb_usage;
486 }
487 
488 /* Probe gralloc implementation to test whether it can allocate a buffer
489  * for the given format and usage.  Vk drivers must not advertise support
490  * for AHB backed VkImage's if the gralloc implementation is not able to
491  * perform the allocation.
492  */
493 bool
vk_ahb_probe_format(VkFormat vk_format,VkImageCreateFlags vk_create,VkImageUsageFlags vk_usage)494 vk_ahb_probe_format(VkFormat vk_format,
495                     VkImageCreateFlags vk_create,
496                     VkImageUsageFlags vk_usage)
497 {
498    AHardwareBuffer_Desc desc = {
499       .width = 16,
500       .height = 16,
501       .layers = 1,
502       .format = vk_image_format_to_ahb_format(vk_format),
503       .usage = vk_image_usage_to_ahb_usage(vk_create, vk_usage),
504    };
505 #if ANDROID_API_LEVEL >= 29
506    return AHardwareBuffer_isSupported(&desc);
507 #else
508    AHardwareBuffer *ahb = NULL;
509    int ret = 0;
510 
511    ret = AHardwareBuffer_allocate(&desc, &ahb);
512    if (ret)
513       return false;
514 
515    AHardwareBuffer_release(ahb);
516 
517    return true;
518 #endif
519 }
520 
521 struct AHardwareBuffer *
vk_alloc_ahardware_buffer(const VkMemoryAllocateInfo * pAllocateInfo)522 vk_alloc_ahardware_buffer(const VkMemoryAllocateInfo *pAllocateInfo)
523 {
524    const VkMemoryDedicatedAllocateInfo *dedicated_info =
525       vk_find_struct_const(pAllocateInfo->pNext,
526                            MEMORY_DEDICATED_ALLOCATE_INFO);
527 
528    uint32_t w = 0;
529    uint32_t h = 1;
530    uint32_t layers = 1;
531    uint32_t format = 0;
532    uint64_t usage = 0;
533 
534    /* If caller passed dedicated information. */
535    if (dedicated_info && dedicated_info->image) {
536       VK_FROM_HANDLE(vk_image, image, dedicated_info->image);
537 
538       if (!image->ahb_format)
539          return NULL;
540 
541       w = image->extent.width;
542       h = image->extent.height;
543       layers = image->array_layers;
544       format = image->ahb_format;
545       usage = vk_image_usage_to_ahb_usage(image->create_flags,
546                                           image->usage);
547    } else {
548       /* AHB export allocation for VkBuffer requires a valid allocationSize */
549       assert(pAllocateInfo->allocationSize);
550       w = pAllocateInfo->allocationSize;
551       format = AHARDWAREBUFFER_FORMAT_BLOB;
552       usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER |
553               AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
554               AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
555    }
556 
557    struct AHardwareBuffer_Desc desc = {
558       .width = w,
559       .height = h,
560       .layers = layers,
561       .format = format,
562       .usage = usage,
563     };
564 
565    struct AHardwareBuffer *ahb;
566    if (AHardwareBuffer_allocate(&desc, &ahb) != 0)
567       return NULL;
568 
569    return ahb;
570 }
571 
572 static VkResult
get_ahb_buffer_format_properties2(struct vk_device * device,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatProperties2ANDROID * pProperties)573 get_ahb_buffer_format_properties2(
574    struct vk_device *device, const struct AHardwareBuffer *buffer,
575    VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
576 {
577    /* Get a description of buffer contents . */
578    AHardwareBuffer_Desc desc;
579    AHardwareBuffer_describe(buffer, &desc);
580 
581    /* Verify description. */
582    bool gpu_usage = desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
583                                   AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
584                                   AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER);
585 
586    /* "Buffer must be a valid Android hardware buffer object with at least
587     * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
588     */
589    if (!gpu_usage)
590       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
591 
592    /* Fill properties fields based on description. */
593    VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
594 
595    p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
596    p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
597    p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
598    p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
599 
600    p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
601    p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
602 
603    p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
604    p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
605 
606    VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
607 
608    p->format = vk_ahb_format_to_image_format(desc.format);
609 
610    VkFormat external_format = p->format;
611 
612    if (p->format != VK_FORMAT_UNDEFINED)
613       goto finish;
614 
615    /* External format only case
616     *
617     * From vkGetAndroidHardwareBufferPropertiesANDROID spec:
618     * "If the Android hardware buffer has one of the formats listed in the Format
619     * Equivalence table (see spec.), then format must have the equivalent Vulkan
620     * format listed in the table. Otherwise, format may be VK_FORMAT_UNDEFINED,
621     * indicating the Android hardware buffer can only be used with an external format."
622     *
623     * From SKIA source code analysis: p->format MUST be VK_FORMAT_UNDEFINED, if the
624     * format is not in the Equivalence table.
625     */
626 
627    struct u_gralloc_buffer_handle gr_handle = {
628       .handle = AHardwareBuffer_getNativeHandle(buffer),
629       .pixel_stride = desc.stride,
630       .hal_format = desc.format,
631    };
632 
633    struct u_gralloc_buffer_basic_info info;
634 
635    if (u_gralloc_get_buffer_basic_info(vk_android_get_ugralloc(), &gr_handle, &info) != 0)
636       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
637 
638    switch (info.drm_fourcc) {
639    case DRM_FORMAT_YVU420:
640       /* Assuming that U and V planes are swapped earlier */
641       external_format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
642       break;
643    case DRM_FORMAT_NV12:
644       external_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
645       break;
646    default:;
647       mesa_loge("Unsupported external DRM format: %d", info.drm_fourcc);
648       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
649    }
650 
651    struct u_gralloc_buffer_color_info color_info;
652    if (u_gralloc_get_buffer_color_info(vk_android_get_ugralloc(), &gr_handle, &color_info) == 0) {
653       switch (color_info.yuv_color_space) {
654       case __DRI_YUV_COLOR_SPACE_ITU_REC601:
655          p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
656          break;
657       case __DRI_YUV_COLOR_SPACE_ITU_REC709:
658          p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709;
659          break;
660       case __DRI_YUV_COLOR_SPACE_ITU_REC2020:
661          p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020;
662          break;
663       default:
664          break;
665       }
666 
667       p->suggestedYcbcrRange = (color_info.sample_range == __DRI_YUV_NARROW_RANGE) ?
668          VK_SAMPLER_YCBCR_RANGE_ITU_NARROW : VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
669       p->suggestedXChromaOffset = (color_info.horizontal_siting == __DRI_YUV_CHROMA_SITING_0_5) ?
670          VK_CHROMA_LOCATION_MIDPOINT : VK_CHROMA_LOCATION_COSITED_EVEN;
671       p->suggestedYChromaOffset = (color_info.vertical_siting == __DRI_YUV_CHROMA_SITING_0_5) ?
672          VK_CHROMA_LOCATION_MIDPOINT : VK_CHROMA_LOCATION_COSITED_EVEN;
673    } else {
674       p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
675       p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW;
676    }
677 
678 finish:
679 
680    device->physical->dispatch_table.GetPhysicalDeviceFormatProperties2(
681       (VkPhysicalDevice)device->physical, external_format, &format_properties);
682 
683    p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
684    p->externalFormat = external_format;
685 
686    /* From vkGetAndroidHardwareBufferPropertiesANDROID spec:
687     * "The formatFeatures member *must* include
688     *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT and at least one of
689     *  VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT or
690     *  VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT"
691     */
692    p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
693 
694    return VK_SUCCESS;
695 }
696 
697 VkResult
vk_common_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)698 vk_common_GetAndroidHardwareBufferPropertiesANDROID(
699    VkDevice device_h, const struct AHardwareBuffer *buffer,
700    VkAndroidHardwareBufferPropertiesANDROID *pProperties)
701 {
702    VK_FROM_HANDLE(vk_device, device, device_h);
703    struct vk_physical_device *pdevice = device->physical;
704 
705    VkResult result;
706 
707    VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
708       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
709 
710    /* Fill format properties of an Android hardware buffer. */
711    if (format_prop) {
712       VkAndroidHardwareBufferFormatProperties2ANDROID format_prop2 = {
713          .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID,
714       };
715       result = get_ahb_buffer_format_properties2(device, buffer, &format_prop2);
716       if (result != VK_SUCCESS)
717          return result;
718 
719       format_prop->format                 = format_prop2.format;
720       format_prop->externalFormat         = format_prop2.externalFormat;
721       format_prop->formatFeatures         =
722          vk_format_features2_to_features(format_prop2.formatFeatures);
723       format_prop->samplerYcbcrConversionComponents =
724          format_prop2.samplerYcbcrConversionComponents;
725       format_prop->suggestedYcbcrModel    = format_prop2.suggestedYcbcrModel;
726       format_prop->suggestedYcbcrRange    = format_prop2.suggestedYcbcrRange;
727       format_prop->suggestedXChromaOffset = format_prop2.suggestedXChromaOffset;
728       format_prop->suggestedYChromaOffset = format_prop2.suggestedYChromaOffset;
729    }
730 
731    VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
732       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
733    if (format_prop2) {
734       result = get_ahb_buffer_format_properties2(device, buffer, format_prop2);
735       if (result != VK_SUCCESS)
736          return result;
737    }
738 
739    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
740    assert(handle && handle->numFds > 0);
741    pProperties->allocationSize = lseek(handle->data[0], 0, SEEK_END);
742 
743    VkPhysicalDeviceMemoryProperties mem_props;
744 
745    device->physical->dispatch_table.GetPhysicalDeviceMemoryProperties(
746       (VkPhysicalDevice)pdevice, &mem_props);
747 
748    /* All memory types. (Should we be smarter than this?) */
749    pProperties->memoryTypeBits = (1u << mem_props.memoryTypeCount) - 1;
750 
751    return VK_SUCCESS;
752 }
753 #endif /* ANDROID_API_LEVEL >= 26 */
754 
755 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_AcquireImageANDROID(VkDevice _device,VkImage image,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)756 vk_common_AcquireImageANDROID(VkDevice _device,
757                               VkImage image,
758                               int nativeFenceFd,
759                               VkSemaphore semaphore,
760                               VkFence fence)
761 {
762    VK_FROM_HANDLE(vk_device, device, _device);
763    VkResult result = VK_SUCCESS;
764 
765    /* From https://source.android.com/devices/graphics/implement-vulkan :
766     *
767     *    "The driver takes ownership of the fence file descriptor and closes
768     *    the fence file descriptor when no longer needed. The driver must do
769     *    so even if neither a semaphore or fence object is provided, or even
770     *    if vkAcquireImageANDROID fails and returns an error."
771     *
772     * The Vulkan spec for VkImportFence/SemaphoreFdKHR(), however, requires
773     * the file descriptor to be left alone on failure.
774     */
775    int semaphore_fd = -1, fence_fd = -1;
776    if (nativeFenceFd >= 0) {
777       if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) {
778          /* We have both so we have to import the sync file twice. One of
779           * them needs to be a dup.
780           */
781          semaphore_fd = nativeFenceFd;
782          fence_fd = dup(nativeFenceFd);
783          if (fence_fd < 0) {
784             VkResult err = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS :
785                                                VK_ERROR_OUT_OF_HOST_MEMORY;
786             close(nativeFenceFd);
787             return vk_error(device, err);
788          }
789       } else if (semaphore != VK_NULL_HANDLE) {
790          semaphore_fd = nativeFenceFd;
791       } else if (fence != VK_NULL_HANDLE) {
792          fence_fd = nativeFenceFd;
793       } else {
794          /* Nothing to import into so we have to close the file */
795          close(nativeFenceFd);
796       }
797    }
798 
799    if (semaphore != VK_NULL_HANDLE) {
800       const VkImportSemaphoreFdInfoKHR info = {
801          .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
802          .semaphore = semaphore,
803          .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
804          .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
805          .fd = semaphore_fd,
806       };
807       result = device->dispatch_table.ImportSemaphoreFdKHR(_device, &info);
808       if (result == VK_SUCCESS)
809          semaphore_fd = -1; /* The driver took ownership */
810    }
811 
812    if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) {
813       const VkImportFenceFdInfoKHR info = {
814          .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
815          .fence = fence,
816          .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
817          .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
818          .fd = fence_fd,
819       };
820       result = device->dispatch_table.ImportFenceFdKHR(_device, &info);
821       if (result == VK_SUCCESS)
822          fence_fd = -1; /* The driver took ownership */
823    }
824 
825    if (semaphore_fd >= 0)
826       close(semaphore_fd);
827    if (fence_fd >= 0)
828       close(fence_fd);
829 
830    return result;
831 }
832 
833 static VkResult
vk_anb_semaphore_init_once(struct vk_queue * queue,struct vk_device * device)834 vk_anb_semaphore_init_once(struct vk_queue *queue, struct vk_device *device)
835 {
836    if (queue->anb_semaphore != VK_NULL_HANDLE)
837       return VK_SUCCESS;
838 
839    const VkExportSemaphoreCreateInfo export_info = {
840       .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
841       .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
842    };
843    const VkSemaphoreCreateInfo create_info = {
844       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
845       .pNext = &export_info,
846    };
847    return device->dispatch_table.CreateSemaphore(vk_device_to_handle(device),
848                                                  &create_info, NULL,
849                                                  &queue->anb_semaphore);
850 }
851 
852 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)853 vk_common_QueueSignalReleaseImageANDROID(VkQueue _queue,
854                                          uint32_t waitSemaphoreCount,
855                                          const VkSemaphore *pWaitSemaphores,
856                                          VkImage image,
857                                          int *pNativeFenceFd)
858 {
859    VK_FROM_HANDLE(vk_queue, queue, _queue);
860    struct vk_device *device = queue->base.device;
861    VkResult result = VK_SUCCESS;
862 
863    STACK_ARRAY(VkPipelineStageFlags, stage_flags, MAX2(1, waitSemaphoreCount));
864    for (uint32_t i = 0; i < MAX2(1, waitSemaphoreCount); i++)
865       stage_flags[i] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
866 
867    result = vk_anb_semaphore_init_once(queue, device);
868    if (result != VK_SUCCESS) {
869       STACK_ARRAY_FINISH(stage_flags);
870       return result;
871    }
872 
873    const VkSubmitInfo submit_info = {
874       .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
875       .waitSemaphoreCount = waitSemaphoreCount,
876       .pWaitSemaphores = pWaitSemaphores,
877       .pWaitDstStageMask = stage_flags,
878       .signalSemaphoreCount = 1,
879       .pSignalSemaphores = &queue->anb_semaphore,
880    };
881    result = device->dispatch_table.QueueSubmit(_queue, 1, &submit_info,
882                                                VK_NULL_HANDLE);
883    STACK_ARRAY_FINISH(stage_flags);
884    if (result != VK_SUCCESS)
885       return result;
886 
887    const VkSemaphoreGetFdInfoKHR get_fd = {
888       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
889       .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
890       .semaphore = queue->anb_semaphore,
891    };
892    return device->dispatch_table.GetSemaphoreFdKHR(vk_device_to_handle(device),
893                                                    &get_fd, pNativeFenceFd);
894 }
895