• 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       if (is_local) {
150          memory_type_index = i;
151          break;
152       }
153    }
154 
155    /* fallback */
156    if (memory_type_index == -1)
157       memory_type_index = 0;
158 
159    result = radv_AllocateMemory(device_h,
160                                 &(VkMemoryAllocateInfo){
161                                    .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
162                                    .pNext = &import_info,
163                                    /* Max buffer size, unused for imports */
164                                    .allocationSize = 0x7FFFFFFF,
165                                    .memoryTypeIndex = memory_type_index,
166                                 },
167                                 alloc, &memory_h);
168    if (result != VK_SUCCESS)
169       return result;
170 
171    struct radeon_bo_metadata md;
172    device->ws->buffer_get_metadata(device->ws, radv_device_memory_from_handle(memory_h)->bo, &md);
173 
174    VkImageCreateInfo updated_base_info = *base_info;
175 
176    VkExternalMemoryImageCreateInfo external_memory_info = {
177       .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
178       .pNext = updated_base_info.pNext,
179       .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
180    };
181 
182    updated_base_info.pNext = &external_memory_info;
183 
184    result = radv_image_create(device_h,
185                               &(struct radv_image_create_info){
186                                  .vk_info = &updated_base_info,
187                                  .no_metadata_planes = true,
188                                  .bo_metadata = &md,
189                               },
190                               alloc, &image_h);
191 
192    if (result != VK_SUCCESS)
193       goto fail_create_image;
194 
195    image = radv_image_from_handle(image_h);
196 
197    radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
198 
199    VkBindImageMemoryInfo bind_info = {
200       .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
201       .image = image_h,
202       .memory = memory_h,
203       .memoryOffset = 0
204    };
205    radv_BindImageMemory2(device_h, 1, &bind_info);
206 
207    image->owned_memory = memory_h;
208    /* Don't clobber the out-parameter until success is certain. */
209    *out_image_h = image_h;
210 
211    return VK_SUCCESS;
212 
213 fail_create_image:
214    radv_FreeMemory(device_h, memory_h, alloc);
215    return result;
216 }
217 
218 VkResult
radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)219 radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
220                                      VkImageUsageFlags imageUsage, int *grallocUsage)
221 {
222    RADV_FROM_HANDLE(radv_device, device, device_h);
223    struct radv_physical_device *phys_dev = device->physical_device;
224    VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
225    VkResult result;
226 
227    *grallocUsage = 0;
228 
229    /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
230     * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
231     * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
232     *
233     *     TODO(jessehall): I think these are right, but haven't thought hard
234     *     about it. Do we need to query the driver for support of any of
235     *     these?
236     *
237     * Any disagreement between this function and the hardcoded
238     * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
239     * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
240     */
241 
242    const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
243       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
244       .format = format,
245       .type = VK_IMAGE_TYPE_2D,
246       .tiling = VK_IMAGE_TILING_OPTIMAL,
247       .usage = imageUsage,
248    };
249 
250    VkImageFormatProperties2 image_format_props = {
251       .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
252    };
253 
254    /* Check that requested format and usage are supported. */
255    result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
256                                                          &image_format_props);
257    if (result != VK_SUCCESS) {
258       return vk_errorf(device, result,
259                        "radv_GetPhysicalDeviceImageFormatProperties2 failed "
260                        "inside %s",
261                        __func__);
262    }
263 
264    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
265       *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
266 
267    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
268                                 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
269       *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
270 
271    /* All VkImageUsageFlags not explicitly checked here are unsupported for
272     * gralloc swapchains.
273     */
274    if (imageUsage != 0) {
275       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
276                        "unsupported VkImageUsageFlags(0x%x) for gralloc "
277                        "swapchain",
278                        imageUsage);
279    }
280 
281    /*
282     * FINISHME: Advertise all display-supported formats. Mostly
283     * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
284     * what we need for 30-bit colors.
285     */
286    if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
287       *grallocUsage |=
288          GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
289    }
290 
291    if (*grallocUsage == 0)
292       return VK_ERROR_FORMAT_NOT_SUPPORTED;
293 
294    return VK_SUCCESS;
295 }
296 
297 VkResult
radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)298 radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format,
299                                       VkImageUsageFlags imageUsage,
300                                       VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
301                                       uint64_t *grallocConsumerUsage,
302                                       uint64_t *grallocProducerUsage)
303 {
304    /* Before level 26 (Android 8.0/Oreo) the loader uses
305     * vkGetSwapchainGrallocUsageANDROID. */
306 #if ANDROID_API_LEVEL >= 26
307    RADV_FROM_HANDLE(radv_device, device, device_h);
308    struct radv_physical_device *phys_dev = device->physical_device;
309    VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
310    VkResult result;
311 
312    *grallocConsumerUsage = 0;
313    *grallocProducerUsage = 0;
314 
315    if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
316       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
317                        "The Vulkan loader tried to query shared presentable image support");
318 
319    const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
320       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
321       .format = format,
322       .type = VK_IMAGE_TYPE_2D,
323       .tiling = VK_IMAGE_TILING_OPTIMAL,
324       .usage = imageUsage,
325    };
326 
327    VkImageFormatProperties2 image_format_props = {
328       .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
329    };
330 
331    /* Check that requested format and usage are supported. */
332    result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
333                                                          &image_format_props);
334    if (result != VK_SUCCESS) {
335       return vk_errorf(device, result,
336                        "radv_GetPhysicalDeviceImageFormatProperties2 failed "
337                        "inside %s",
338                        __func__);
339    }
340 
341    if (unmask32(&imageUsage,
342                 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
343       *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
344       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
345    }
346 
347    if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
348                                 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
349       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
350    }
351 
352    if (imageUsage != 0) {
353       return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
354                        "unsupported VkImageUsageFlags(0x%x) for gralloc "
355                        "swapchain",
356                        imageUsage);
357    }
358 
359    /*
360     * FINISHME: Advertise all display-supported formats. Mostly
361     * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
362     * what we need for 30-bit colors.
363     */
364    if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
365       *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
366       *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
367    }
368 
369    if (!*grallocProducerUsage && !*grallocConsumerUsage)
370       return VK_ERROR_FORMAT_NOT_SUPPORTED;
371 
372    return VK_SUCCESS;
373 #else
374    *grallocConsumerUsage = 0;
375    *grallocProducerUsage = 0;
376    return VK_ERROR_FORMAT_NOT_SUPPORTED;
377 #endif
378 }
379 
380 VkResult
radv_AcquireImageANDROID(VkDevice device_h,VkImage image_h,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)381 radv_AcquireImageANDROID(VkDevice device_h, VkImage image_h, int nativeFenceFd, VkSemaphore semaphore,
382                          VkFence fence)
383 {
384    RADV_FROM_HANDLE(radv_device, device, device_h);
385    VkResult result = VK_SUCCESS;
386 
387    /* From https://source.android.com/devices/graphics/implement-vulkan :
388     *
389     *    "The driver takes ownership of the fence file descriptor and closes
390     *    the fence file descriptor when no longer needed. The driver must do
391     *    so even if neither a semaphore or fence object is provided, or even
392     *    if vkAcquireImageANDROID fails and returns an error."
393     *
394     * The Vulkan spec for VkImportFence/SemaphoreFdKHR(), however, requires
395     * the file descriptor to be left alone on failure.
396     */
397    int semaphore_fd = -1, fence_fd = -1;
398    if (nativeFenceFd >= 0) {
399       if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) {
400          /* We have both so we have to import the sync file twice. One of
401           * them needs to be a dup.
402           */
403          semaphore_fd = nativeFenceFd;
404          fence_fd = dup(nativeFenceFd);
405          if (fence_fd < 0) {
406             VkResult err = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS :
407                                                VK_ERROR_OUT_OF_HOST_MEMORY;
408             close(nativeFenceFd);
409             return vk_error(device, err);
410          }
411       } else if (semaphore != VK_NULL_HANDLE) {
412          semaphore_fd = nativeFenceFd;
413       } else if (fence != VK_NULL_HANDLE) {
414          fence_fd = nativeFenceFd;
415       } else {
416          /* Nothing to import into so we have to close the file */
417          close(nativeFenceFd);
418       }
419    }
420 
421    if (semaphore != VK_NULL_HANDLE) {
422       const VkImportSemaphoreFdInfoKHR info = {
423          .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
424          .semaphore = semaphore,
425          .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
426          .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
427          .fd = semaphore_fd,
428       };
429       result = radv_ImportSemaphoreFdKHR(device_h, &info);
430       if (result == VK_SUCCESS)
431          semaphore_fd = -1; /* RADV took ownership */
432    }
433 
434    if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) {
435       const VkImportFenceFdInfoKHR info = {
436          .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
437          .fence = fence,
438          .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
439          .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
440          .fd = fence_fd,
441       };
442       result = radv_ImportFenceFdKHR(device_h, &info);
443       if (result == VK_SUCCESS)
444          fence_fd = -1; /* RADV took ownership */
445    }
446 
447    if (semaphore_fd >= 0)
448       close(semaphore_fd);
449    if (fence_fd >= 0)
450       close(fence_fd);
451 
452    return result;
453 }
454 
455 VkResult
radv_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)456 radv_QueueSignalReleaseImageANDROID(VkQueue _queue, uint32_t waitSemaphoreCount,
457                                     const VkSemaphore *pWaitSemaphores, VkImage image,
458                                     int *pNativeFenceFd)
459 {
460    RADV_FROM_HANDLE(radv_queue, queue, _queue);
461    VkResult result = VK_SUCCESS;
462 
463    if (waitSemaphoreCount == 0) {
464       if (pNativeFenceFd)
465          *pNativeFenceFd = -1;
466       return VK_SUCCESS;
467    }
468 
469    int fd = -1;
470 
471    for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
472       int tmp_fd;
473       result =
474          radv_GetSemaphoreFdKHR(radv_device_to_handle(queue->device),
475                                 &(VkSemaphoreGetFdInfoKHR){
476                                    .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
477                                    .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
478                                    .semaphore = pWaitSemaphores[i],
479                                 },
480                                 &tmp_fd);
481       if (result != VK_SUCCESS) {
482          if (fd >= 0)
483             close(fd);
484          return result;
485       }
486 
487       if (fd < 0)
488          fd = tmp_fd;
489       else if (tmp_fd >= 0) {
490          sync_accumulate("radv", &fd, tmp_fd);
491          close(tmp_fd);
492       }
493    }
494 
495    if (pNativeFenceFd) {
496       *pNativeFenceFd = fd;
497    } else if (fd >= 0) {
498       close(fd);
499       /* We still need to do the exports, to reset the semaphores, but
500        * otherwise we don't wait on them. */
501    }
502    return VK_SUCCESS;
503 }
504 #endif
505 
506 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
507 
508 enum {
509    /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
510    BUFFER_USAGE_CAMERA_MASK = 0x00060000U,
511 };
512 
513 static inline VkFormat
vk_format_from_android(unsigned android_format,unsigned android_usage)514 vk_format_from_android(unsigned android_format, unsigned android_usage)
515 {
516    switch (android_format) {
517    case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
518    case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
519       return VK_FORMAT_R8G8B8A8_UNORM;
520    case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
521       return VK_FORMAT_R8G8B8_UNORM;
522    case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
523       return VK_FORMAT_R5G6B5_UNORM_PACK16;
524    case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
525       return VK_FORMAT_R16G16B16A16_SFLOAT;
526    case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
527       return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
528    case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
529       return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
530    case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
531       if (android_usage & BUFFER_USAGE_CAMERA_MASK)
532          return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
533       else
534          return VK_FORMAT_R8G8B8_UNORM;
535    case AHARDWAREBUFFER_FORMAT_BLOB:
536    default:
537       return VK_FORMAT_UNDEFINED;
538    }
539 }
540 
541 static inline unsigned
android_format_from_vk(unsigned vk_format)542 android_format_from_vk(unsigned vk_format)
543 {
544    switch (vk_format) {
545    case VK_FORMAT_R8G8B8A8_UNORM:
546       return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
547    case VK_FORMAT_R8G8B8_UNORM:
548       return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
549    case VK_FORMAT_R5G6B5_UNORM_PACK16:
550       return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
551    case VK_FORMAT_R16G16B16A16_SFLOAT:
552       return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
553    case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
554       return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
555    case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
556       return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
557    default:
558       return AHARDWAREBUFFER_FORMAT_BLOB;
559    }
560 }
561 
562 uint64_t
radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create,const VkImageUsageFlags vk_usage)563 radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage)
564 {
565    uint64_t ahb_usage = 0;
566    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
567       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
568 
569    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
570       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
571 
572    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
573       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
574 
575    if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
576       ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
577 
578    if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
579       ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
580 
581    /* No usage bits set - set at least one GPU usage. */
582    if (ahb_usage == 0)
583       ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
584    return ahb_usage;
585 }
586 
587 static VkResult
get_ahb_buffer_format_properties(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatPropertiesANDROID * pProperties)588 get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer *buffer,
589                                  VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
590 {
591    RADV_FROM_HANDLE(radv_device, device, device_h);
592 
593    /* Get a description of buffer contents . */
594    AHardwareBuffer_Desc desc;
595    AHardwareBuffer_describe(buffer, &desc);
596 
597    /* Verify description. */
598    const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
599                               AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
600                               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
601 
602    /* "Buffer must be a valid Android hardware buffer object with at least
603     * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
604     */
605    if (!(desc.usage & (gpu_usage)))
606       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
607 
608    /* Fill properties fields based on description. */
609    VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
610 
611    p->format = vk_format_from_android(desc.format, desc.usage);
612    p->externalFormat = (uint64_t)(uintptr_t)p->format;
613 
614    VkFormatProperties2 format_properties = {
615       .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
616    };
617 
618    radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
619                                                p->format, &format_properties);
620 
621    if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
622       p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
623    else
624       p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
625 
626    /* "Images can be created with an external format even if the Android hardware
627     *  buffer has a format which has an equivalent Vulkan format to enable
628     *  consistent handling of images from sources that might use either category
629     *  of format. However, all images created with an external format are subject
630     *  to the valid usage requirements associated with external formats, even if
631     *  the Android hardware buffer’s format has a Vulkan equivalent."
632     *
633     * "The formatFeatures member *must* include
634     *  VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
635     *  VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
636     *  VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
637     */
638    assert(p->formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
639 
640    p->formatFeatures |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
641 
642    /* "Implementations may not always be able to determine the color model,
643     *  numerical range, or chroma offsets of the image contents, so the values
644     *  in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
645     *  Applications should treat these values as sensible defaults to use in
646     *  the absence of more reliable information obtained through some other
647     *  means."
648     */
649    p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
650    p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
651    p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
652    p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
653 
654    p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
655    p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
656 
657    p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
658    p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
659 
660    return VK_SUCCESS;
661 }
662 
663 static VkResult
get_ahb_buffer_format_properties2(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatProperties2ANDROID * pProperties)664 get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
665                                   VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
666 {
667    RADV_FROM_HANDLE(radv_device, device, device_h);
668 
669    /* Get a description of buffer contents . */
670    AHardwareBuffer_Desc desc;
671    AHardwareBuffer_describe(buffer, &desc);
672 
673    /* Verify description. */
674    const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
675                               AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
676                               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
677 
678    /* "Buffer must be a valid Android hardware buffer object with at least
679     * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
680     */
681    if (!(desc.usage & (gpu_usage)))
682       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
683 
684    /* Fill properties fields based on description. */
685    VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
686 
687    p->format = vk_format_from_android(desc.format, desc.usage);
688    p->externalFormat = (uint64_t)(uintptr_t)p->format;
689 
690    VkFormatProperties2 format_properties = {
691       .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
692    };
693 
694    radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
695                                                p->format, &format_properties);
696 
697    if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
698       p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
699    else
700       p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
701 
702    /* "Images can be created with an external format even if the Android hardware
703     *  buffer has a format which has an equivalent Vulkan format to enable
704     *  consistent handling of images from sources that might use either category
705     *  of format. However, all images created with an external format are subject
706     *  to the valid usage requirements associated with external formats, even if
707     *  the Android hardware buffer’s format has a Vulkan equivalent."
708     *
709     * "The formatFeatures member *must* include
710     *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR and at least one of
711     *  VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR or
712     *  VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR"
713     */
714    assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR);
715 
716    p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
717 
718    /* "Implementations may not always be able to determine the color model,
719     *  numerical range, or chroma offsets of the image contents, so the values
720     *  in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
721     *  Applications should treat these values as sensible defaults to use in
722     *  the absence of more reliable information obtained through some other
723     *  means."
724     */
725    p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
726    p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
727    p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
728    p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
729 
730    p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
731    p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
732 
733    p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
734    p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
735 
736    return VK_SUCCESS;
737 }
738 
739 VkResult
radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)740 radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
741                                                const struct AHardwareBuffer *buffer,
742                                                VkAndroidHardwareBufferPropertiesANDROID *pProperties)
743 {
744    RADV_FROM_HANDLE(radv_device, dev, device_h);
745    struct radv_physical_device *pdevice = dev->physical_device;
746 
747    VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
748       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
749 
750    /* Fill format properties of an Android hardware buffer. */
751    if (format_prop)
752       get_ahb_buffer_format_properties(device_h, buffer, format_prop);
753 
754    VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
755       vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
756    if (format_prop2)
757       get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
758 
759    /* NOTE - We support buffers with only one handle but do not error on
760     * multiple handle case. Reason is that we want to support YUV formats
761     * where we have many logical planes but they all point to the same
762     * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
763     */
764    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
765    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
766    if (dma_buf < 0)
767       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
768 
769    /* All memory types. */
770    uint32_t memory_types = (1u << pdevice->memory_properties.memoryTypeCount) - 1;
771 
772    pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
773    pProperties->memoryTypeBits = memory_types;
774 
775    return VK_SUCCESS;
776 }
777 
778 VkResult
radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,const VkMemoryGetAndroidHardwareBufferInfoANDROID * pInfo,struct AHardwareBuffer ** pBuffer)779 radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,
780                                            const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
781                                            struct AHardwareBuffer **pBuffer)
782 {
783    RADV_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
784 
785    /* This should always be set due to the export handle types being set on
786     * allocation. */
787    assert(mem->android_hardware_buffer);
788 
789    /* Some quotes from Vulkan spec:
790     *
791     * "If the device memory was created by importing an Android hardware
792     * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
793     * Android hardware buffer object."
794     *
795     * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
796     * have been included in VkExportMemoryAllocateInfo::handleTypes when
797     * memory was created."
798     */
799    *pBuffer = mem->android_hardware_buffer;
800    /* Increase refcount. */
801    AHardwareBuffer_acquire(mem->android_hardware_buffer);
802    return VK_SUCCESS;
803 }
804 
805 #endif
806 
807 VkFormat
radv_select_android_external_format(const void * next,VkFormat default_format)808 radv_select_android_external_format(const void *next, VkFormat default_format)
809 {
810 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
811    const VkExternalFormatANDROID *android_format =
812       vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
813 
814    if (android_format && android_format->externalFormat) {
815       return (VkFormat)android_format->externalFormat;
816    }
817 #endif
818 
819    return default_format;
820 }
821 
822 VkResult
radv_import_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkImportAndroidHardwareBufferInfoANDROID * info)823 radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
824                        unsigned priority, const VkImportAndroidHardwareBufferInfoANDROID *info)
825 {
826 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
827    /* Import from AHardwareBuffer to radv_device_memory. */
828    const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
829 
830    /* NOTE - We support buffers with only one handle but do not error on
831     * multiple handle case. Reason is that we want to support YUV formats
832     * where we have many logical planes but they all point to the same
833     * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
834     */
835    int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
836    if (dma_buf < 0)
837       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
838 
839    uint64_t alloc_size = 0;
840    VkResult result =
841       device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
842    if (result != VK_SUCCESS)
843       return result;
844 
845    if (mem->image) {
846       struct radeon_bo_metadata metadata;
847       device->ws->buffer_get_metadata(device->ws, mem->bo, &metadata);
848 
849       struct radv_image_create_info create_info = {.no_metadata_planes = true,
850                                                    .bo_metadata = &metadata};
851 
852       VkResult result = radv_image_create_layout(device, create_info, NULL, mem->image);
853       if (result != VK_SUCCESS) {
854          device->ws->buffer_destroy(device->ws, mem->bo);
855          mem->bo = NULL;
856          return result;
857       }
858 
859       if (alloc_size < mem->image->size) {
860          device->ws->buffer_destroy(device->ws, mem->bo);
861          mem->bo = NULL;
862          return VK_ERROR_INVALID_EXTERNAL_HANDLE;
863       }
864    } else if (mem->buffer) {
865       if (alloc_size < mem->buffer->size) {
866          device->ws->buffer_destroy(device->ws, mem->bo);
867          mem->bo = NULL;
868          return VK_ERROR_INVALID_EXTERNAL_HANDLE;
869       }
870    }
871 
872    /* "If the vkAllocateMemory command succeeds, the implementation must
873     * acquire a reference to the imported hardware buffer, which it must
874     * release when the device memory object is freed. If the command fails,
875     * the implementation must not retain a reference."
876     */
877    AHardwareBuffer_acquire(info->buffer);
878    mem->android_hardware_buffer = info->buffer;
879 
880    return VK_SUCCESS;
881 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
882    return VK_ERROR_EXTENSION_NOT_PRESENT;
883 #endif
884 }
885 
886 VkResult
radv_create_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkMemoryAllocateInfo * pAllocateInfo)887 radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
888                        unsigned priority, const VkMemoryAllocateInfo *pAllocateInfo)
889 {
890 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
891    const VkMemoryDedicatedAllocateInfo *dedicated_info =
892       vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
893 
894    uint32_t w = 0;
895    uint32_t h = 1;
896    uint32_t layers = 1;
897    uint32_t format = 0;
898    uint64_t usage = 0;
899 
900    /* If caller passed dedicated information. */
901    if (dedicated_info && dedicated_info->image) {
902       RADV_FROM_HANDLE(radv_image, image, dedicated_info->image);
903       w = image->info.width;
904       h = image->info.height;
905       layers = image->info.array_size;
906       format = android_format_from_vk(image->vk_format);
907       usage = radv_ahb_usage_from_vk_usage(image->flags, image->usage);
908    } else if (dedicated_info && dedicated_info->buffer) {
909       RADV_FROM_HANDLE(radv_buffer, buffer, dedicated_info->buffer);
910       w = buffer->size;
911       format = AHARDWAREBUFFER_FORMAT_BLOB;
912       usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
913    } else {
914       w = pAllocateInfo->allocationSize;
915       format = AHARDWAREBUFFER_FORMAT_BLOB;
916       usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
917    }
918 
919    struct AHardwareBuffer *android_hardware_buffer = NULL;
920    struct AHardwareBuffer_Desc desc = {
921       .width = w,
922       .height = h,
923       .layers = layers,
924       .format = format,
925       .usage = usage,
926    };
927 
928    if (AHardwareBuffer_allocate(&desc, &android_hardware_buffer) != 0)
929       return VK_ERROR_OUT_OF_HOST_MEMORY;
930 
931    mem->android_hardware_buffer = android_hardware_buffer;
932 
933    const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
934       .buffer = mem->android_hardware_buffer,
935    };
936 
937    VkResult result = radv_import_ahb_memory(device, mem, priority, &import_info);
938 
939    /* Release a reference to avoid leak for AHB allocation. */
940    AHardwareBuffer_release(mem->android_hardware_buffer);
941 
942    return result;
943 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
944    return VK_ERROR_EXTENSION_NOT_PRESENT;
945 #endif
946 }
947 
948 bool
radv_android_gralloc_supports_format(VkFormat format,VkImageUsageFlagBits usage)949 radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage)
950 {
951 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
952    /* Ideally we check Gralloc for what it supports and then merge that with the radv
953       format support, but there is no easy gralloc query besides just creating an image.
954       That seems a bit on the expensive side, so just hardcode for now. */
955    /* TODO: Add multi-plane formats after confirming everything works between radeonsi
956       and radv. */
957    switch (format) {
958    case VK_FORMAT_R8G8B8A8_UNORM:
959    case VK_FORMAT_R5G6B5_UNORM_PACK16:
960       return true;
961    case VK_FORMAT_R8_UNORM:
962    case VK_FORMAT_R8G8_UNORM:
963       return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
964    default:
965       return false;
966    }
967 #else
968    (void)format;
969    (void)usage;
970    return false;
971 #endif
972 }
973