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