xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/radv_android.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2017, Google Inc.
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "radv_android.h"
8 #include "radv_buffer.h"
9 #include "radv_device.h"
10 #include "radv_device_memory.h"
11 #include "radv_entrypoints.h"
12 #include "radv_image.h"
13 #include "radv_physical_device.h"
14 
15 #if DETECT_OS_ANDROID
16 #include <libsync.h>
17 #include <hardware/gralloc.h>
18 #include <hardware/hardware.h>
19 #include <hardware/hwvulkan.h>
20 #include <vulkan/vk_android_native_buffer.h>
21 #include <vulkan/vk_icd.h>
22 
23 #if ANDROID_API_LEVEL >= 26
24 #include <hardware/gralloc1.h>
25 #endif
26 #endif /* DETECT_OS_ANDROID */
27 
28 #include "util/os_file.h"
29 
30 #include "vk_android.h"
31 #include "vk_log.h"
32 #include "vk_util.h"
33 
34 #if DETECT_OS_ANDROID
35 
36 static int radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev);
37 static int radv_hal_close(struct hw_device_t *dev);
38 
39 static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
40 
41 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
42    .common =
43       {
44          .tag = HARDWARE_MODULE_TAG,
45          .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
46          .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
47          .id = HWVULKAN_HARDWARE_MODULE_ID,
48          .name = "AMD Vulkan HAL",
49          .author = "Google",
50          .methods =
51             &(hw_module_methods_t){
52                .open = radv_hal_open,
53             },
54       },
55 };
56 
57 /* If any bits in test_mask are set, then unset them and return true. */
58 static inline bool
unmask32(uint32_t * inout_mask,uint32_t test_mask)59 unmask32(uint32_t *inout_mask, uint32_t test_mask)
60 {
61    uint32_t orig_mask = *inout_mask;
62    *inout_mask &= ~test_mask;
63    return *inout_mask != orig_mask;
64 }
65 
66 static int
radv_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)67 radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev)
68 {
69    assert(mod == &HAL_MODULE_INFO_SYM.common);
70    assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
71 
72    hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
73    if (!hal_dev)
74       return -1;
75 
76    *hal_dev = (hwvulkan_device_t){
77       .common =
78          {
79             .tag = HARDWARE_DEVICE_TAG,
80             .version = HWVULKAN_DEVICE_API_VERSION_0_1,
81             .module = &HAL_MODULE_INFO_SYM.common,
82             .close = radv_hal_close,
83          },
84       .EnumerateInstanceExtensionProperties = radv_EnumerateInstanceExtensionProperties,
85       .CreateInstance = radv_CreateInstance,
86       .GetInstanceProcAddr = radv_GetInstanceProcAddr,
87    };
88 
89    *dev = &hal_dev->common;
90    return 0;
91 }
92 
93 static int
radv_hal_close(struct hw_device_t * dev)94 radv_hal_close(struct hw_device_t *dev)
95 {
96    /* hwvulkan.h claims that hw_device_t::close() is never called. */
97    return -1;
98 }
99 
100 VkResult
radv_image_from_gralloc(VkDevice device_h,const VkImageCreateInfo * base_info,const VkNativeBufferANDROID * gralloc_info,const VkAllocationCallbacks * alloc,VkImage * out_image_h)101 radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
102                         const VkNativeBufferANDROID *gralloc_info, const VkAllocationCallbacks *alloc,
103                         VkImage *out_image_h)
104 
105 {
106    VK_FROM_HANDLE(radv_device, device, device_h);
107    const struct radv_physical_device *pdev = radv_device_physical(device);
108    VkImage image_h = VK_NULL_HANDLE;
109    struct radv_image *image = NULL;
110    VkResult result;
111 
112    if (gralloc_info->handle->numFds != 1) {
113       return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
114                        "VkNativeBufferANDROID::handle::numFds is %d, "
115                        "expected 1",
116                        gralloc_info->handle->numFds);
117    }
118 
119    /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
120     * must exceed that of the gralloc handle, and we do not own the gralloc
121     * handle.
122     */
123    int dma_buf = gralloc_info->handle->data[0];
124 
125    VkDeviceMemory memory_h;
126 
127    const VkImportMemoryFdInfoKHR import_info = {
128       .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
129       .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
130       .fd = os_dupfd_cloexec(dma_buf),
131    };
132 
133    /* Find the first VRAM memory type, or GART for PRIME images. */
134    int memory_type_index = -1;
135    for (int i = 0; i < pdev->memory_properties.memoryTypeCount; ++i) {
136       bool is_local = !!(pdev->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
137       bool is_32bit = !!(pdev->memory_types_32bit & (1u << i));
138       if (is_local && !is_32bit) {
139          memory_type_index = i;
140          break;
141       }
142    }
143 
144    /* fallback */
145    if (memory_type_index == -1)
146       memory_type_index = 0;
147 
148    result = radv_AllocateMemory(device_h,
149                                 &(VkMemoryAllocateInfo){
150                                    .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
151                                    .pNext = &import_info,
152                                    /* Max buffer size, unused for imports */
153                                    .allocationSize = 0x7FFFFFFF,
154                                    .memoryTypeIndex = memory_type_index,
155                                 },
156                                 alloc, &memory_h);
157    if (result != VK_SUCCESS)
158       return result;
159 
160    struct radeon_bo_metadata md;
161    device->ws->buffer_get_metadata(device->ws, radv_device_memory_from_handle(memory_h)->bo, &md);
162 
163    VkImageCreateInfo updated_base_info = *base_info;
164 
165    VkExternalMemoryImageCreateInfo external_memory_info = {
166       .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
167       .pNext = updated_base_info.pNext,
168       .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
169    };
170 
171    updated_base_info.pNext = &external_memory_info;
172 
173    result = radv_image_create(device_h,
174                               &(struct radv_image_create_info){
175                                  .vk_info = &updated_base_info,
176                                  .no_metadata_planes = true,
177                                  .bo_metadata = &md,
178                               },
179                               alloc, &image_h, false);
180 
181    if (result != VK_SUCCESS)
182       goto fail_create_image;
183 
184    image = radv_image_from_handle(image_h);
185 
186    radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
187 
188    VkBindImageMemoryInfo bind_info = {.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
189                                       .image = image_h,
190                                       .memory = memory_h,
191                                       .memoryOffset = 0};
192    radv_BindImageMemory2(device_h, 1, &bind_info);
193 
194    image->owned_memory = memory_h;
195    /* Don't clobber the out-parameter until success is certain. */
196    *out_image_h = image_h;
197 
198    return VK_SUCCESS;
199 
200 fail_create_image:
201    radv_FreeMemory(device_h, memory_h, alloc);
202    return result;
203 }
204 
205 VkResult
radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)206 radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
207                                      int *grallocUsage)
208 {
209    VK_FROM_HANDLE(radv_device, device, device_h);
210    struct radv_physical_device *pdev = radv_device_physical(device);
211    VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
212    VkResult result;
213 
214    *grallocUsage = 0;
215 
216    /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
217     * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
218     * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
219     *
220     *     TODO(jessehall): I think these are right, but haven't thought hard
221     *     about it. Do we need to query the driver for support of any of
222     *     these?
223     *
224     * Any disagreement between this function and the hardcoded
225     * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
226     * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
227     */
228 
229    const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
230       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
231       .format = format,
232       .type = VK_IMAGE_TYPE_2D,
233       .tiling = VK_IMAGE_TILING_OPTIMAL,
234       .usage = imageUsage,
235    };
236 
237    VkImageFormatProperties2 image_format_props = {
238       .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
239    };
240 
241    /* Check that requested format and usage are supported. */
242    result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
243    if (result != VK_SUCCESS) {
244       return vk_errorf(device, result,
245                        "radv_GetPhysicalDeviceImageFormatProperties2 failed "
246                        "inside %s",
247                        __func__);
248    }
249 
250    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
251       *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
252 
253    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
254                                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
255       *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
256 
257    /* All VkImageUsageFlags not explicitly checked here are unsupported for
258     * gralloc swapchains.
259     */
260    if (imageUsage != 0) {
261       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
262                        "unsupported VkImageUsageFlags(0x%x) for gralloc "
263                        "swapchain",
264                        imageUsage);
265    }
266 
267    /*
268     * FINISHME: Advertise all display-supported formats. Mostly
269     * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
270     * what we need for 30-bit colors.
271     */
272    if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
273       *grallocUsage |= GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
274    }
275 
276    if (*grallocUsage == 0)
277       return VK_ERROR_FORMAT_NOT_SUPPORTED;
278 
279    return VK_SUCCESS;
280 }
281 
282 VkResult
radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)283 radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
284                                       VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
285                                       uint64_t *grallocConsumerUsage, uint64_t *grallocProducerUsage)
286 {
287    /* Before level 26 (Android 8.0/Oreo) the loader uses
288     * vkGetSwapchainGrallocUsageANDROID. */
289 #if ANDROID_API_LEVEL >= 26
290    VK_FROM_HANDLE(radv_device, device, device_h);
291    struct radv_physical_device *pdev = radv_device_physical(device);
292    VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
293    VkResult result;
294 
295    *grallocConsumerUsage = 0;
296    *grallocProducerUsage = 0;
297 
298    if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
299       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
300                        "The Vulkan loader tried to query shared presentable image support");
301 
302    const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
303       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
304       .format = format,
305       .type = VK_IMAGE_TYPE_2D,
306       .tiling = VK_IMAGE_TILING_OPTIMAL,
307       .usage = imageUsage,
308    };
309 
310    VkImageFormatProperties2 image_format_props = {
311       .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
312    };
313 
314    /* Check that requested format and usage are supported. */
315    result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
316    if (result != VK_SUCCESS) {
317       return vk_errorf(device, result,
318                        "radv_GetPhysicalDeviceImageFormatProperties2 failed "
319                        "inside %s",
320                        __func__);
321    }
322 
323    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
324       *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
325       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
326    }
327 
328    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
329                                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
330       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
331    }
332 
333    if (imageUsage != 0) {
334       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
335                        "unsupported VkImageUsageFlags(0x%x) for gralloc "
336                        "swapchain",
337                        imageUsage);
338    }
339 
340    /*
341     * FINISHME: Advertise all display-supported formats. Mostly
342     * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
343     * what we need for 30-bit colors.
344     */
345    if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
346       *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
347       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
348    }
349 
350    if (!*grallocProducerUsage && !*grallocConsumerUsage)
351       return VK_ERROR_FORMAT_NOT_SUPPORTED;
352 
353    return VK_SUCCESS;
354 #else
355    *grallocConsumerUsage = 0;
356    *grallocProducerUsage = 0;
357    return VK_ERROR_FORMAT_NOT_SUPPORTED;
358 #endif
359 }
360 #endif /* DETECT_OS_ANDROID */
361 
362 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
363 
364 enum {
365    /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
366    BUFFER_USAGE_CAMERA_MASK = 0x00060000U,
367 };
368 
369 static inline VkFormat
vk_format_from_android(unsigned android_format,unsigned android_usage)370 vk_format_from_android(unsigned android_format, unsigned android_usage)
371 {
372    switch (android_format) {
373    case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
374       return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
375    case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
376       if (android_usage & BUFFER_USAGE_CAMERA_MASK)
377          return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
378       else
379          return VK_FORMAT_R8G8B8_UNORM;
380    default:
381       return vk_ahb_format_to_image_format(android_format);
382    }
383 }
384 
385 unsigned
radv_ahb_format_for_vk_format(VkFormat vk_format)386 radv_ahb_format_for_vk_format(VkFormat vk_format)
387 {
388    switch (vk_format) {
389    case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
390       return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
391    default:
392       return vk_image_format_to_ahb_format(vk_format);
393    }
394 }
395 
396 static VkResult
get_ahb_buffer_format_properties(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatPropertiesANDROID * pProperties)397 get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer *buffer,
398                                  VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
399 {
400    VK_FROM_HANDLE(radv_device, device, device_h);
401    struct radv_physical_device *pdev = radv_device_physical(device);
402 
403    /* Get a description of buffer contents . */
404    AHardwareBuffer_Desc desc;
405    AHardwareBuffer_describe(buffer, &desc);
406 
407    /* Verify description. */
408    const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
409                               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
410 
411    /* "Buffer must be a valid Android hardware buffer object with at least
412     * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
413     */
414    if (!(desc.usage & (gpu_usage)))
415       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
416 
417    /* Fill properties fields based on description. */
418    VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
419 
420    p->format = vk_format_from_android(desc.format, desc.usage);
421    p->externalFormat = (uint64_t)(uintptr_t)p->format;
422 
423    VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
424 
425    radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
426 
427    if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
428       p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
429    else
430       p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
431 
432    /* "Images can be created with an external format even if the Android hardware
433     *  buffer has a format which has an equivalent Vulkan format to enable
434     *  consistent handling of images from sources that might use either category
435     *  of format. However, all images created with an external format are subject
436     *  to the valid usage requirements associated with external formats, even if
437     *  the Android hardware buffer’s format has a Vulkan equivalent."
438     *
439     * "The formatFeatures member *must* include
440     *  VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
441     *  VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
442     *  VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
443     */
444    assert(p->formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
445 
446    p->formatFeatures |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
447 
448    /* "Implementations may not always be able to determine the color model,
449     *  numerical range, or chroma offsets of the image contents, so the values
450     *  in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
451     *  Applications should treat these values as sensible defaults to use in
452     *  the absence of more reliable information obtained through some other
453     *  means."
454     */
455    p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
456    p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
457    p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
458    p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
459 
460    p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
461    p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
462 
463    p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
464    p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
465 
466    return VK_SUCCESS;
467 }
468 
469 static VkResult
get_ahb_buffer_format_properties2(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatProperties2ANDROID * pProperties)470 get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
471                                   VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
472 {
473    VK_FROM_HANDLE(radv_device, device, device_h);
474    struct radv_physical_device *pdev = radv_device_physical(device);
475 
476    /* Get a description of buffer contents . */
477    AHardwareBuffer_Desc desc;
478    AHardwareBuffer_describe(buffer, &desc);
479 
480    /* Verify description. */
481    const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
482                               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
483 
484    /* "Buffer must be a valid Android hardware buffer object with at least
485     * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
486     */
487    if (!(desc.usage & (gpu_usage)))
488       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
489 
490    /* Fill properties fields based on description. */
491    VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
492 
493    p->format = vk_format_from_android(desc.format, desc.usage);
494    p->externalFormat = (uint64_t)(uintptr_t)p->format;
495 
496    VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
497 
498    radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
499 
500    if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
501       p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
502    else
503       p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
504 
505    /* "Images can be created with an external format even if the Android hardware
506     *  buffer has a format which has an equivalent Vulkan format to enable
507     *  consistent handling of images from sources that might use either category
508     *  of format. However, all images created with an external format are subject
509     *  to the valid usage requirements associated with external formats, even if
510     *  the Android hardware buffer’s format has a Vulkan equivalent."
511     *
512     * "The formatFeatures member *must* include
513     *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT and at least one of
514     *  VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT or
515     *  VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT"
516     */
517    assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT);
518 
519    p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
520 
521    /* "Implementations may not always be able to determine the color model,
522     *  numerical range, or chroma offsets of the image contents, so the values
523     *  in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
524     *  Applications should treat these values as sensible defaults to use in
525     *  the absence of more reliable information obtained through some other
526     *  means."
527     */
528    p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
529    p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
530    p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
531    p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
532 
533    p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
534    p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
535 
536    p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
537    p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
538 
539    return VK_SUCCESS;
540 }
541 
542 VkResult
radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)543 radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h, const struct AHardwareBuffer *buffer,
544                                                VkAndroidHardwareBufferPropertiesANDROID *pProperties)
545 {
546    VK_FROM_HANDLE(radv_device, dev, device_h);
547    struct radv_physical_device *pdev = radv_device_physical(dev);
548 
549    VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
550       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
551 
552    /* Fill format properties of an Android hardware buffer. */
553    if (format_prop)
554       get_ahb_buffer_format_properties(device_h, buffer, format_prop);
555 
556    VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
557       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
558    if (format_prop2)
559       get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
560 
561    /* NOTE - We support buffers with only one handle but do not error on
562     * multiple handle case. Reason is that we want to support YUV formats
563     * where we have many logical planes but they all point to the same
564     * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
565     */
566    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
567    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
568    if (dma_buf < 0)
569       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
570 
571    /* All memory types. */
572    uint32_t memory_types = (1u << pdev->memory_properties.memoryTypeCount) - 1;
573 
574    pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
575    pProperties->memoryTypeBits = memory_types & ~pdev->memory_types_32bit;
576 
577    return VK_SUCCESS;
578 }
579 
580 VkResult
radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,const VkMemoryGetAndroidHardwareBufferInfoANDROID * pInfo,struct AHardwareBuffer ** pBuffer)581 radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h, const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
582                                            struct AHardwareBuffer **pBuffer)
583 {
584    VK_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
585 
586    /* This should always be set due to the export handle types being set on
587     * allocation. */
588    assert(mem->android_hardware_buffer);
589 
590    /* Some quotes from Vulkan spec:
591     *
592     * "If the device memory was created by importing an Android hardware
593     * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
594     * Android hardware buffer object."
595     *
596     * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
597     * have been included in VkExportMemoryAllocateInfo::handleTypes when
598     * memory was created."
599     */
600    *pBuffer = mem->android_hardware_buffer;
601    /* Increase refcount. */
602    AHardwareBuffer_acquire(mem->android_hardware_buffer);
603    return VK_SUCCESS;
604 }
605 
606 #endif
607 
608 VkFormat
radv_select_android_external_format(const void * next,VkFormat default_format)609 radv_select_android_external_format(const void *next, VkFormat default_format)
610 {
611 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
612    const VkExternalFormatANDROID *android_format = vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
613 
614    if (android_format && android_format->externalFormat) {
615       return (VkFormat)android_format->externalFormat;
616    }
617 #endif
618 
619    return default_format;
620 }
621 
622 VkResult
radv_import_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkImportAndroidHardwareBufferInfoANDROID * info)623 radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
624                        const VkImportAndroidHardwareBufferInfoANDROID *info)
625 {
626 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
627    /* Import from AHardwareBuffer to radv_device_memory. */
628    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
629 
630    /* NOTE - We support buffers with only one handle but do not error on
631     * multiple handle case. Reason is that we want to support YUV formats
632     * where we have many logical planes but they all point to the same
633     * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
634     */
635    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
636    if (dma_buf < 0)
637       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
638 
639    uint64_t alloc_size = 0;
640    VkResult result = device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
641    if (result != VK_SUCCESS)
642       return result;
643 
644    if (mem->image) {
645       struct radeon_bo_metadata metadata;
646       device->ws->buffer_get_metadata(device->ws, mem->bo, &metadata);
647 
648       struct radv_image_create_info create_info = {.no_metadata_planes = true, .bo_metadata = &metadata};
649 
650       result = radv_image_create_layout(device, create_info, NULL, NULL, mem->image);
651       if (result != VK_SUCCESS) {
652          radv_bo_destroy(device, NULL, mem->bo);
653          mem->bo = NULL;
654          return result;
655       }
656 
657       if (alloc_size < mem->image->size) {
658          radv_bo_destroy(device, NULL, mem->bo);
659          mem->bo = NULL;
660          return VK_ERROR_INVALID_EXTERNAL_HANDLE;
661       }
662    } else if (mem->buffer) {
663       if (alloc_size < mem->buffer->vk.size) {
664          radv_bo_destroy(device, NULL, mem->bo);
665          mem->bo = NULL;
666          return VK_ERROR_INVALID_EXTERNAL_HANDLE;
667       }
668    }
669 
670    /* "If the vkAllocateMemory command succeeds, the implementation must
671     * acquire a reference to the imported hardware buffer, which it must
672     * release when the device memory object is freed. If the command fails,
673     * the implementation must not retain a reference."
674     */
675    AHardwareBuffer_acquire(info->buffer);
676    mem->android_hardware_buffer = info->buffer;
677 
678    return VK_SUCCESS;
679 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
680    return VK_ERROR_EXTENSION_NOT_PRESENT;
681 #endif
682 }
683 
684 VkResult
radv_create_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkMemoryAllocateInfo * pAllocateInfo)685 radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
686                        const VkMemoryAllocateInfo *pAllocateInfo)
687 {
688 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
689    mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
690    if (mem->android_hardware_buffer == NULL)
691       return VK_ERROR_OUT_OF_HOST_MEMORY;
692 
693    const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
694       .buffer = mem->android_hardware_buffer,
695    };
696 
697    VkResult result = radv_import_ahb_memory(device, mem, priority, &import_info);
698 
699    /* Release a reference to avoid leak for AHB allocation. */
700    AHardwareBuffer_release(mem->android_hardware_buffer);
701 
702    return result;
703 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
704    return VK_ERROR_EXTENSION_NOT_PRESENT;
705 #endif
706 }
707 
708 bool
radv_android_gralloc_supports_format(VkFormat format,VkImageUsageFlagBits usage)709 radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage)
710 {
711 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
712    /* Ideally we check AHardwareBuffer_isSupported.  But that test-allocates on most platforms and
713     * seems a bit on the expensive side.  Return true as long as it is a format we understand.
714     */
715    (void)usage;
716    return radv_ahb_format_for_vk_format(format);
717 #else
718    (void)format;
719    (void)usage;
720    return false;
721 #endif
722 }
723