2 * Copyright © 2017, Google Inc.
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:
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
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
25 #include <hardware/gralloc.h>
26 #include <hardware/hardware.h>
27 #include <hardware/hwvulkan.h>
28 #include <vndk/hardware_buffer.h>
29 #include <vulkan/vk_android_native_buffer.h>
30 #include <vulkan/vk_icd.h>
33 #if ANDROID_API_LEVEL >= 26
34 #include <hardware/gralloc1.h>
38 #include "util/os_file.h"
40 #include "radv_private.h"
45 static int radv_hal_open(const struct hw_module_t
* mod
, const char* id
, struct hw_device_t
** dev
);
46 static int radv_hal_close(struct hw_device_t
*dev
);
51 STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC
== ICD_LOADER_MAGIC
);
54 PUBLIC
struct hwvulkan_module_t HAL_MODULE_INFO_SYM
= {
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",
62 .methods
= &(hw_module_methods_t
) {
63 .open
= radv_hal_open
,
68 /* If any bits in test_mask are set, then unset them and return true. */
70 unmask32(uint32_t *inout_mask
, uint32_t test_mask
)
72 uint32_t orig_mask
= *inout_mask
;
73 *inout_mask
&= ~test_mask
;
74 return *inout_mask
!= orig_mask
;
78 radv_hal_open(const struct hw_module_t
* mod
, const char* id
,
79 struct hw_device_t
** dev
)
81 assert(mod
== &HAL_MODULE_INFO_SYM
.common
);
82 assert(strcmp(id
, HWVULKAN_DEVICE_0
) == 0);
84 hwvulkan_device_t
*hal_dev
= malloc(sizeof(*hal_dev
));
88 *hal_dev
= (hwvulkan_device_t
) {
90 .tag
= HARDWARE_DEVICE_TAG
,
91 .version
= HWVULKAN_DEVICE_API_VERSION_0_1
,
92 .module
= &HAL_MODULE_INFO_SYM
.common
,
93 .close
= radv_hal_close
,
95 .EnumerateInstanceExtensionProperties
= radv_EnumerateInstanceExtensionProperties
,
96 .CreateInstance
= radv_CreateInstance
,
97 .GetInstanceProcAddr
= radv_GetInstanceProcAddr
,
100 *dev
= &hal_dev
->common
;
105 radv_hal_close(struct hw_device_t
*dev
)
107 /* hwvulkan.h claims that hw_device_t::close() is never called. */
112 radv_image_from_gralloc(VkDevice device_h
,
113 const VkImageCreateInfo
*base_info
,
114 const VkNativeBufferANDROID
*gralloc_info
,
115 const VkAllocationCallbacks
*alloc
,
116 VkImage
*out_image_h
)
119 RADV_FROM_HANDLE(radv_device
, device
, device_h
);
120 VkImage image_h
= VK_NULL_HANDLE
;
121 struct radv_image
*image
= NULL
;
122 struct radv_bo
*bo
= NULL
;
125 if (gralloc_info
->handle
->numFds
!= 1) {
126 return vk_errorf(device
->instance
, VK_ERROR_INVALID_EXTERNAL_HANDLE
,
127 "VkNativeBufferANDROID::handle::numFds is %d, "
128 "expected 1", gralloc_info
->handle
->numFds
);
131 /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
132 * must exceed that of the gralloc handle, and we do not own the gralloc
135 int dma_buf
= gralloc_info
->handle
->data
[0];
137 VkDeviceMemory memory_h
;
139 const VkImportMemoryFdInfoKHR import_info
= {
140 .sType
= VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR
,
141 .handleType
= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT
,
142 .fd
= os_dupfd_cloexec(dma_buf
),
145 /* Find the first VRAM memory type, or GART for PRIME images. */
146 int memory_type_index
= -1;
147 for (int i
= 0; i
< device
->physical_device
->memory_properties
.memoryTypeCount
; ++i
) {
148 bool is_local
= !!(device
->physical_device
->memory_properties
.memoryTypes
[i
].propertyFlags
& VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
150 memory_type_index
= i
;
156 if (memory_type_index
== -1)
157 memory_type_index
= 0;
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
,
169 if (result
!= VK_SUCCESS
)
172 struct radeon_bo_metadata md
;
173 device
->ws
->buffer_get_metadata(radv_device_memory_from_handle(memory_h
)->bo
, &md
);
175 VkImageCreateInfo updated_base_info
= *base_info
;
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
,
183 updated_base_info
.pNext
= &external_memory_info
;
185 result
= radv_image_create(device_h
,
186 &(struct radv_image_create_info
) {
187 .vk_info
= &updated_base_info
,
188 .no_metadata_planes
= true,
194 if (result
!= VK_SUCCESS
)
195 goto fail_create_image
;
197 image
= radv_image_from_handle(image_h
);
199 radv_image_override_offset_stride(device
, image
, 0, gralloc_info
->stride
);
201 radv_BindImageMemory(device_h
, image_h
, memory_h
, 0);
203 image
->owned_memory
= memory_h
;
204 /* Don't clobber the out-parameter until success is certain. */
205 *out_image_h
= image_h
;
210 radv_FreeMemory(device_h
, memory_h
, alloc
);
214 VkResult
radv_GetSwapchainGrallocUsageANDROID(
217 VkImageUsageFlags imageUsage
,
220 RADV_FROM_HANDLE(radv_device
, device
, device_h
);
221 struct radv_physical_device
*phys_dev
= device
->physical_device
;
222 VkPhysicalDevice phys_dev_h
= radv_physical_device_to_handle(phys_dev
);
227 /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
228 * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
229 * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
231 * TODO(jessehall): I think these are right, but haven't thought hard
232 * about it. Do we need to query the driver for support of any of
235 * Any disagreement between this function and the hardcoded
236 * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
237 * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
240 const VkPhysicalDeviceImageFormatInfo2 image_format_info
= {
241 .sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2
,
243 .type
= VK_IMAGE_TYPE_2D
,
244 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
248 VkImageFormatProperties2 image_format_props
= {
249 .sType
= VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2
,
252 /* Check that requested format and usage are supported. */
253 result
= radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h
,
254 &image_format_info
, &image_format_props
);
255 if (result
!= VK_SUCCESS
) {
256 return vk_errorf(device
->instance
, result
,
257 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
258 "inside %s", __func__
);
261 if (unmask32(&imageUsage
, VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
262 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
))
263 *grallocUsage
|= GRALLOC_USAGE_HW_RENDER
;
265 if (unmask32(&imageUsage
, VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
266 VK_IMAGE_USAGE_SAMPLED_BIT
|
267 VK_IMAGE_USAGE_STORAGE_BIT
|
268 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
))
269 *grallocUsage
|= GRALLOC_USAGE_HW_TEXTURE
;
271 /* All VkImageUsageFlags not explicitly checked here are unsupported for
272 * gralloc swapchains.
274 if (imageUsage
!= 0) {
275 return vk_errorf(device
->instance
, VK_ERROR_FORMAT_NOT_SUPPORTED
,
276 "unsupported VkImageUsageFlags(0x%x) for gralloc "
277 "swapchain", imageUsage
);
281 * FINISHME: Advertise all display-supported formats. Mostly
282 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
283 * what we need for 30-bit colors.
285 if (format
== VK_FORMAT_B8G8R8A8_UNORM
||
286 format
== VK_FORMAT_B5G6R5_UNORM_PACK16
) {
287 *grallocUsage
|= GRALLOC_USAGE_HW_FB
|
288 GRALLOC_USAGE_HW_COMPOSER
|
289 GRALLOC_USAGE_EXTERNAL_DISP
;
292 if (*grallocUsage
== 0)
293 return VK_ERROR_FORMAT_NOT_SUPPORTED
;
298 VkResult
radv_GetSwapchainGrallocUsage2ANDROID(
301 VkImageUsageFlags imageUsage
,
302 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage
,
303 uint64_t* grallocConsumerUsage
,
304 uint64_t* grallocProducerUsage
)
306 /* Before level 26 (Android 8.0/Oreo) the loader uses
307 * vkGetSwapchainGrallocUsageANDROID. */
308 #if ANDROID_API_LEVEL >= 26
309 RADV_FROM_HANDLE(radv_device
, device
, device_h
);
310 struct radv_physical_device
*phys_dev
= device
->physical_device
;
311 VkPhysicalDevice phys_dev_h
= radv_physical_device_to_handle(phys_dev
);
314 *grallocConsumerUsage
= 0;
315 *grallocProducerUsage
= 0;
317 if (swapchainImageUsage
& VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID
)
318 return vk_errorf(device
->instance
, VK_ERROR_FORMAT_NOT_SUPPORTED
,
319 "The Vulkan loader tried to query shared presentable image support");
321 const VkPhysicalDeviceImageFormatInfo2 image_format_info
= {
322 .sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2
,
324 .type
= VK_IMAGE_TYPE_2D
,
325 .tiling
= VK_IMAGE_TILING_OPTIMAL
,
329 VkImageFormatProperties2 image_format_props
= {
330 .sType
= VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2
,
333 /* Check that requested format and usage are supported. */
334 result
= radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h
,
335 &image_format_info
, &image_format_props
);
336 if (result
!= VK_SUCCESS
) {
337 return vk_errorf(device
->instance
, result
,
338 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
339 "inside %s", __func__
);
342 if (unmask32(&imageUsage
, VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
343 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
)) {
344 *grallocProducerUsage
|= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET
;
345 *grallocConsumerUsage
|= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET
;
348 if (unmask32(&imageUsage
, VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
349 VK_IMAGE_USAGE_SAMPLED_BIT
|
350 VK_IMAGE_USAGE_STORAGE_BIT
|
351 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
)) {
352 *grallocConsumerUsage
|= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE
;
355 if (imageUsage
!= 0) {
356 return vk_errorf(device
->instance
, VK_ERROR_FORMAT_NOT_SUPPORTED
,
357 "unsupported VkImageUsageFlags(0x%x) for gralloc "
358 "swapchain", imageUsage
);
362 * FINISHME: Advertise all display-supported formats. Mostly
363 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
364 * what we need for 30-bit colors.
366 if (format
== VK_FORMAT_B8G8R8A8_UNORM
||
367 format
== VK_FORMAT_B5G6R5_UNORM_PACK16
) {
368 *grallocProducerUsage
|= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET
;
369 *grallocConsumerUsage
|= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER
;
372 if (!*grallocProducerUsage
&& !*grallocConsumerUsage
)
373 return VK_ERROR_FORMAT_NOT_SUPPORTED
;
377 *grallocConsumerUsage
= 0;
378 *grallocProducerUsage
= 0;
379 return VK_ERROR_FORMAT_NOT_SUPPORTED
;
384 radv_AcquireImageANDROID(
388 VkSemaphore semaphore
,
391 VkResult semaphore_result
= VK_SUCCESS
, fence_result
= VK_SUCCESS
;
393 if (semaphore
!= VK_NULL_HANDLE
) {
394 int semaphore_fd
= nativeFenceFd
>= 0 ? os_dupfd_cloexec(nativeFenceFd
) : nativeFenceFd
;
395 semaphore_result
= radv_ImportSemaphoreFdKHR(device
,
396 &(VkImportSemaphoreFdInfoKHR
) {
397 .sType
= VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR
,
398 .flags
= VK_SEMAPHORE_IMPORT_TEMPORARY_BIT
,
400 .semaphore
= semaphore
,
404 if (fence
!= VK_NULL_HANDLE
) {
405 int fence_fd
= nativeFenceFd
>= 0 ? os_dupfd_cloexec(nativeFenceFd
) : nativeFenceFd
;
406 fence_result
= radv_ImportFenceFdKHR(device
,
407 &(VkImportFenceFdInfoKHR
) {
408 .sType
= VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR
,
409 .flags
= VK_FENCE_IMPORT_TEMPORARY_BIT
,
415 close(nativeFenceFd
);
417 if (semaphore_result
!= VK_SUCCESS
)
418 return semaphore_result
;
423 radv_QueueSignalReleaseImageANDROID(
425 uint32_t waitSemaphoreCount
,
426 const VkSemaphore
* pWaitSemaphores
,
430 RADV_FROM_HANDLE(radv_queue
, queue
, _queue
);
431 VkResult result
= VK_SUCCESS
;
433 if (waitSemaphoreCount
== 0) {
435 *pNativeFenceFd
= -1;
441 for (uint32_t i
= 0; i
< waitSemaphoreCount
; ++i
) {
443 result
= radv_GetSemaphoreFdKHR(radv_device_to_handle(queue
->device
),
444 &(VkSemaphoreGetFdInfoKHR
) {
445 .sType
= VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR
,
446 .handleType
= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
,
447 .semaphore
= pWaitSemaphores
[i
],
449 if (result
!= VK_SUCCESS
) {
457 else if (tmp_fd
>= 0) {
458 sync_accumulate("radv", &fd
, tmp_fd
);
463 if (pNativeFenceFd
) {
464 *pNativeFenceFd
= fd
;
465 } else if (fd
>= 0) {
467 /* We still need to do the exports, to reset the semaphores, but
468 * otherwise we don't wait on them. */
474 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
477 /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
478 AHARDWAREBUFFER_USAGE_CAMERA_MASK
= 0x00060000U
,
481 static inline VkFormat
482 vk_format_from_android(unsigned android_format
, unsigned android_usage
)
484 switch (android_format
) {
485 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
:
486 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM
:
487 return VK_FORMAT_R8G8B8A8_UNORM
;
488 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM
:
489 return VK_FORMAT_R8G8B8_UNORM
;
490 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM
:
491 return VK_FORMAT_R5G6B5_UNORM_PACK16
;
492 case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT
:
493 return VK_FORMAT_R16G16B16A16_SFLOAT
;
494 case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM
:
495 return VK_FORMAT_A2B10G10R10_UNORM_PACK32
;
496 case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420
:
497 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
;
498 case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED
:
499 if (android_usage
& AHARDWAREBUFFER_USAGE_CAMERA_MASK
)
500 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
;
502 return VK_FORMAT_R8G8B8_UNORM
;
503 case AHARDWAREBUFFER_FORMAT_BLOB
:
505 return VK_FORMAT_UNDEFINED
;
509 static inline unsigned
510 android_format_from_vk(unsigned vk_format
)
513 case VK_FORMAT_R8G8B8A8_UNORM
:
514 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
;
515 case VK_FORMAT_R8G8B8_UNORM
:
516 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM
;
517 case VK_FORMAT_R5G6B5_UNORM_PACK16
:
518 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM
;
519 case VK_FORMAT_R16G16B16A16_SFLOAT
:
520 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT
;
521 case VK_FORMAT_A2B10G10R10_UNORM_PACK32
:
522 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM
;
523 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
:
524 return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420
;
526 return AHARDWAREBUFFER_FORMAT_BLOB
;
531 radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create
,
532 const VkImageUsageFlags vk_usage
)
534 uint64_t ahb_usage
= 0;
535 if (vk_usage
& VK_IMAGE_USAGE_SAMPLED_BIT
)
536 ahb_usage
|= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
;
538 if (vk_usage
& VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
)
539 ahb_usage
|= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
;
541 if (vk_usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
)
542 ahb_usage
|= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT
;
544 if (vk_create
& VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
)
545 ahb_usage
|= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP
;
547 if (vk_create
& VK_IMAGE_CREATE_PROTECTED_BIT
)
548 ahb_usage
|= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT
;
550 /* No usage bits set - set at least one GPU usage. */
552 ahb_usage
= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
;
557 get_ahb_buffer_format_properties(
559 const struct AHardwareBuffer
*buffer
,
560 VkAndroidHardwareBufferFormatPropertiesANDROID
*pProperties
)
562 RADV_FROM_HANDLE(radv_device
, device
, device_h
);
564 /* Get a description of buffer contents . */
565 AHardwareBuffer_Desc desc
;
566 AHardwareBuffer_describe(buffer
, &desc
);
568 /* Verify description. */
569 const uint64_t gpu_usage
=
570 AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE
|
571 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT
|
572 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
;
574 /* "Buffer must be a valid Android hardware buffer object with at least
575 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
577 if (!(desc
.usage
& (gpu_usage
)))
578 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
580 /* Fill properties fields based on description. */
581 VkAndroidHardwareBufferFormatPropertiesANDROID
*p
= pProperties
;
583 p
->format
= vk_format_from_android(desc
.format
, desc
.usage
);
584 p
->externalFormat
= (uint64_t) (uintptr_t) p
->format
;
586 VkFormatProperties format_properties
;
587 radv_GetPhysicalDeviceFormatProperties(
588 radv_physical_device_to_handle(device
->physical_device
),
589 p
->format
, &format_properties
);
591 if (desc
.usage
& AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
)
592 p
->formatFeatures
= format_properties
.linearTilingFeatures
;
594 p
->formatFeatures
= format_properties
.optimalTilingFeatures
;
596 /* "Images can be created with an external format even if the Android hardware
597 * buffer has a format which has an equivalent Vulkan format to enable
598 * consistent handling of images from sources that might use either category
599 * of format. However, all images created with an external format are subject
600 * to the valid usage requirements associated with external formats, even if
601 * the Android hardware buffer’s format has a Vulkan equivalent."
603 * "The formatFeatures member *must* include
604 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
605 * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
606 * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
608 assert(p
->formatFeatures
& VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
);
610 p
->formatFeatures
|= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT
;
612 /* "Implementations may not always be able to determine the color model,
613 * numerical range, or chroma offsets of the image contents, so the values
614 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
615 * Applications should treat these values as sensible defaults to use in
616 * the absence of more reliable information obtained through some other
619 p
->samplerYcbcrConversionComponents
.r
= VK_COMPONENT_SWIZZLE_IDENTITY
;
620 p
->samplerYcbcrConversionComponents
.g
= VK_COMPONENT_SWIZZLE_IDENTITY
;
621 p
->samplerYcbcrConversionComponents
.b
= VK_COMPONENT_SWIZZLE_IDENTITY
;
622 p
->samplerYcbcrConversionComponents
.a
= VK_COMPONENT_SWIZZLE_IDENTITY
;
624 p
->suggestedYcbcrModel
= VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601
;
625 p
->suggestedYcbcrRange
= VK_SAMPLER_YCBCR_RANGE_ITU_FULL
;
627 p
->suggestedXChromaOffset
= VK_CHROMA_LOCATION_MIDPOINT
;
628 p
->suggestedYChromaOffset
= VK_CHROMA_LOCATION_MIDPOINT
;
634 radv_GetAndroidHardwareBufferPropertiesANDROID(
636 const struct AHardwareBuffer
*buffer
,
637 VkAndroidHardwareBufferPropertiesANDROID
*pProperties
)
639 RADV_FROM_HANDLE(radv_device
, dev
, device_h
);
640 struct radv_physical_device
*pdevice
= dev
->physical_device
;
642 VkAndroidHardwareBufferFormatPropertiesANDROID
*format_prop
=
643 vk_find_struct(pProperties
->pNext
,
644 ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID
);
646 /* Fill format properties of an Android hardware buffer. */
648 get_ahb_buffer_format_properties(device_h
, buffer
, format_prop
);
650 /* NOTE - We support buffers with only one handle but do not error on
651 * multiple handle case. Reason is that we want to support YUV formats
652 * where we have many logical planes but they all point to the same
653 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
655 const native_handle_t
*handle
=
656 AHardwareBuffer_getNativeHandle(buffer
);
657 int dma_buf
= (handle
&& handle
->numFds
) ? handle
->data
[0] : -1;
659 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
661 /* All memory types. */
662 uint32_t memory_types
= (1u << pdevice
->memory_properties
.memoryTypeCount
) - 1;
664 pProperties
->allocationSize
= lseek(dma_buf
, 0, SEEK_END
);
665 pProperties
->memoryTypeBits
= memory_types
;
671 radv_GetMemoryAndroidHardwareBufferANDROID(
673 const VkMemoryGetAndroidHardwareBufferInfoANDROID
*pInfo
,
674 struct AHardwareBuffer
**pBuffer
)
676 RADV_FROM_HANDLE(radv_device_memory
, mem
, pInfo
->memory
);
678 /* This should always be set due to the export handle types being set on
680 assert(mem
->android_hardware_buffer
);
682 /* Some quotes from Vulkan spec:
684 * "If the device memory was created by importing an Android hardware
685 * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
686 * Android hardware buffer object."
688 * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
689 * have been included in VkExportMemoryAllocateInfo::handleTypes when
690 * memory was created."
692 *pBuffer
= mem
->android_hardware_buffer
;
693 /* Increase refcount. */
694 AHardwareBuffer_acquire(mem
->android_hardware_buffer
);
701 radv_select_android_external_format(const void *next
, VkFormat default_format
)
703 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
704 const VkExternalFormatANDROID
*android_format
=
705 vk_find_struct_const(next
, EXTERNAL_FORMAT_ANDROID
);
707 if (android_format
&& android_format
->externalFormat
) {
708 return (VkFormat
)android_format
->externalFormat
;
712 return default_format
;
717 radv_import_ahb_memory(struct radv_device
*device
,
718 struct radv_device_memory
*mem
,
720 const VkImportAndroidHardwareBufferInfoANDROID
*info
)
722 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
723 /* Import from AHardwareBuffer to radv_device_memory. */
724 const native_handle_t
*handle
=
725 AHardwareBuffer_getNativeHandle(info
->buffer
);
727 /* NOTE - We support buffers with only one handle but do not error on
728 * multiple handle case. Reason is that we want to support YUV formats
729 * where we have many logical planes but they all point to the same
730 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
732 int dma_buf
= (handle
&& handle
->numFds
) ? handle
->data
[0] : -1;
734 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
736 uint64_t alloc_size
= 0;
737 mem
->bo
= device
->ws
->buffer_from_fd(device
->ws
, dma_buf
,
738 priority
, &alloc_size
);
740 return VK_ERROR_OUT_OF_HOST_MEMORY
;
743 struct radeon_bo_metadata metadata
;
744 device
->ws
->buffer_get_metadata(mem
->bo
, &metadata
);
746 struct radv_image_create_info create_info
= {
747 .no_metadata_planes
= true,
748 .bo_metadata
= &metadata
751 VkResult result
= radv_image_create_layout(device
, create_info
, mem
->image
);
752 if (result
!= VK_SUCCESS
) {
753 device
->ws
->buffer_destroy(mem
->bo
);
758 if (alloc_size
< mem
->image
->size
) {
759 device
->ws
->buffer_destroy(mem
->bo
);
761 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
763 } else if (mem
->buffer
) {
764 if (alloc_size
< mem
->buffer
->size
) {
765 device
->ws
->buffer_destroy(mem
->bo
);
767 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
771 /* "If the vkAllocateMemory command succeeds, the implementation must
772 * acquire a reference to the imported hardware buffer, which it must
773 * release when the device memory object is freed. If the command fails,
774 * the implementation must not retain a reference."
776 AHardwareBuffer_acquire(info
->buffer
);
777 mem
->android_hardware_buffer
= info
->buffer
;
780 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
781 return VK_ERROR_EXTENSION_NOT_PRESENT
;
786 radv_create_ahb_memory(struct radv_device
*device
,
787 struct radv_device_memory
*mem
,
789 const VkMemoryAllocateInfo
*pAllocateInfo
)
791 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
792 const VkMemoryDedicatedAllocateInfo
*dedicated_info
=
793 vk_find_struct_const(pAllocateInfo
->pNext
,
794 MEMORY_DEDICATED_ALLOCATE_INFO
);
802 /* If caller passed dedicated information. */
803 if (dedicated_info
&& dedicated_info
->image
) {
804 RADV_FROM_HANDLE(radv_image
, image
, dedicated_info
->image
);
805 w
= image
->info
.width
;
806 h
= image
->info
.height
;
807 layers
= image
->info
.array_size
;
808 format
= android_format_from_vk(image
->vk_format
);
809 usage
= radv_ahb_usage_from_vk_usage(image
->flags
, image
->usage
);
810 } else if (dedicated_info
&& dedicated_info
->buffer
) {
811 RADV_FROM_HANDLE(radv_buffer
, buffer
, dedicated_info
->buffer
);
813 format
= AHARDWAREBUFFER_FORMAT_BLOB
;
814 usage
= AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN
|
815 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN
;
817 w
= pAllocateInfo
->allocationSize
;
818 format
= AHARDWAREBUFFER_FORMAT_BLOB
;
819 usage
= AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN
|
820 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN
;
823 struct AHardwareBuffer
*android_hardware_buffer
= NULL
;
824 struct AHardwareBuffer_Desc desc
= {
832 if (AHardwareBuffer_allocate(&desc
, &android_hardware_buffer
) != 0)
833 return VK_ERROR_OUT_OF_HOST_MEMORY
;
835 mem
->android_hardware_buffer
= android_hardware_buffer
;
837 const struct VkImportAndroidHardwareBufferInfoANDROID import_info
= {
838 .buffer
= mem
->android_hardware_buffer
,
841 VkResult result
= radv_import_ahb_memory(device
, mem
, priority
, &import_info
);
842 if (result
!= VK_SUCCESS
)
843 AHardwareBuffer_release(mem
->android_hardware_buffer
);
845 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
846 return VK_ERROR_EXTENSION_NOT_PRESENT
;
850 bool radv_android_gralloc_supports_format(VkFormat format
, VkImageUsageFlagBits usage
) {
851 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
852 /* Ideally we check Gralloc for what it supports and then merge that with the radv
853 format support, but there is no easy gralloc query besides just creating an image.
854 That seems a bit on the expensive side, so just hardcode for now. */
855 /* TODO: Add multi-plane formats after confirming everything works between radeonsi
858 case VK_FORMAT_R8G8B8A8_UNORM
:
859 case VK_FORMAT_R5G6B5_UNORM_PACK16
:
861 case VK_FORMAT_R8_UNORM
:
862 case VK_FORMAT_R8G8_UNORM
:
863 return !(usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
);