turnip: Support AHardwareBuffer
Signed-off-by: tarsin <yuanqingxiang233@163.com> [rob: various fixes for android-cts failures] Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Roman Stratiienko <r.stratiienko@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29090>
This commit is contained in:
@@ -5,8 +5,10 @@
|
||||
|
||||
#include "tu_android.h"
|
||||
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/hwvulkan.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "util/u_gralloc/u_gralloc.h"
|
||||
#include "vk_android.h"
|
||||
@@ -78,4 +80,3 @@ tu_hal_close(struct hw_device_t *dev)
|
||||
vk_android_destroy_ugralloc();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@@ -45,6 +45,7 @@
|
||||
|
||||
#if DETECT_OS_ANDROID
|
||||
#include "util/u_gralloc/u_gralloc.h"
|
||||
#include <vndk/hardware_buffer.h>
|
||||
#endif
|
||||
|
||||
static int
|
||||
@@ -296,6 +297,7 @@ get_device_extensions(const struct tu_physical_device *device,
|
||||
|
||||
#if DETECT_OS_ANDROID
|
||||
if (vk_android_get_ugralloc() != NULL) {
|
||||
ext->ANDROID_external_memory_android_hardware_buffer = true,
|
||||
ext->ANDROID_native_buffer = true;
|
||||
}
|
||||
#endif
|
||||
@@ -2757,12 +2759,6 @@ tu_AllocateMemory(VkDevice _device,
|
||||
|
||||
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
||||
|
||||
if (pAllocateInfo->allocationSize == 0) {
|
||||
/* Apparently, this is allowed */
|
||||
*pMem = VK_NULL_HANDLE;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
struct tu_memory_heap *mem_heap = &device->physical_device->heap;
|
||||
uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
|
||||
if (mem_heap_used > mem_heap->size)
|
||||
@@ -2773,6 +2769,13 @@ tu_AllocateMemory(VkDevice _device,
|
||||
if (mem == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
if (pAllocateInfo->allocationSize == 0 && !mem->vk.ahardware_buffer) {
|
||||
vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
|
||||
/* Apparently, this is allowed */
|
||||
*pMem = VK_NULL_HANDLE;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
const VkImportMemoryFdInfoKHR *fd_info =
|
||||
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
|
||||
|
||||
@@ -2793,6 +2796,15 @@ tu_AllocateMemory(VkDevice _device,
|
||||
/* take ownership and close the fd */
|
||||
close(fd_info->fd);
|
||||
}
|
||||
} else if (mem->vk.ahardware_buffer) {
|
||||
#ifdef ANDROID
|
||||
const native_handle_t *handle = AHardwareBuffer_getNativeHandle(mem->vk.ahardware_buffer);
|
||||
assert(handle->numFds > 0);
|
||||
size_t size = lseek(handle->data[0], 0, SEEK_END);
|
||||
result = tu_bo_init_dmabuf(device, &mem->bo, size, handle->data[0]);
|
||||
#else
|
||||
result = VK_ERROR_FEATURE_NOT_PRESENT;
|
||||
#endif
|
||||
} else {
|
||||
uint64_t client_address = 0;
|
||||
BITMASK_ENUM(tu_bo_alloc_flags) alloc_flags = TU_BO_ALLOC_NO_FLAGS;
|
||||
|
@@ -8,13 +8,17 @@
|
||||
|
||||
#include "fdl/fd6_format_table.h"
|
||||
|
||||
#include "vk_android.h"
|
||||
#include "vk_enum_defines.h"
|
||||
#include "vk_util.h"
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
|
||||
#include "tu_android.h"
|
||||
#include "tu_device.h"
|
||||
#include "tu_image.h"
|
||||
|
||||
#include <vulkan/vulkan_android.h>
|
||||
|
||||
/* Map non-colorspace-converted YUV formats to RGB pipe formats where we can,
|
||||
* since our hardware doesn't support colorspace conversion.
|
||||
*
|
||||
@@ -685,6 +689,12 @@ tu_get_external_image_format_properties(
|
||||
handleType, pImageFormatInfo->type);
|
||||
}
|
||||
break;
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
|
||||
flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
|
||||
break;
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
|
||||
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
||||
@@ -717,6 +727,7 @@ tu_GetPhysicalDeviceImageFormatProperties2(
|
||||
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
|
||||
const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL;
|
||||
VkExternalImageFormatProperties *external_props = NULL;
|
||||
VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
|
||||
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
||||
VkFormatFeatureFlags format_feature_flags;
|
||||
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
||||
@@ -749,6 +760,9 @@ tu_GetPhysicalDeviceImageFormatProperties2(
|
||||
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
|
||||
external_props = (VkExternalImageFormatProperties *) s;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID:
|
||||
android_usage = (VkAndroidHardwareBufferUsageANDROID *) s;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
|
||||
cubic_props = (VkFilterCubicImageViewImageFormatPropertiesEXT *) s;
|
||||
break;
|
||||
@@ -789,6 +803,43 @@ tu_GetPhysicalDeviceImageFormatProperties2(
|
||||
}
|
||||
}
|
||||
|
||||
if (android_usage) {
|
||||
/* Don't expect gralloc to be able to allocate anything other than 3D: */
|
||||
if (base_info->type != VK_IMAGE_TYPE_2D) {
|
||||
result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
|
||||
"type (%u) unsupported for AHB", base_info->type);
|
||||
goto fail;
|
||||
}
|
||||
VkImageFormatProperties *props = &base_props->imageFormatProperties;
|
||||
if (!(props->sampleCounts & VK_SAMPLE_COUNT_1_BIT)) {
|
||||
result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
|
||||
"sampleCounts (%x) unsupported for AHB", props->sampleCounts);
|
||||
goto fail;
|
||||
}
|
||||
android_usage->androidHardwareBufferUsage =
|
||||
vk_image_usage_to_ahb_usage(base_info->flags, base_info->usage);
|
||||
uint32_t format = vk_image_format_to_ahb_format(base_info->format);
|
||||
if (!format) {
|
||||
result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
|
||||
"format (%u) unsupported for AHB", base_info->format);
|
||||
goto fail;
|
||||
}
|
||||
/* We can't advertise support for anything that gralloc cannot allocate
|
||||
* so we are stuck without any better option than attempting a test
|
||||
* allocation:
|
||||
*/
|
||||
if (!vk_ahb_probe_format(base_info->format, base_info->flags, base_info->usage)) {
|
||||
result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
|
||||
"format (%x) with flags (%x) and usage (%x) unsupported for AHB",
|
||||
base_info->format, base_info->flags, base_info->usage);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* AHBs with mipmap usage will ignore this property */
|
||||
props->maxMipLevels = 1;
|
||||
props->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
if (ycbcr_props)
|
||||
ycbcr_props->combinedImageSamplerDescriptorCount = 1;
|
||||
|
||||
|
@@ -765,6 +765,15 @@ tu_CreateImage(VkDevice _device,
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
/* This section is removed by the optimizer for non-ANDROID builds */
|
||||
if (vk_image_is_android_hardware_buffer(&image->vk)) {
|
||||
/* At this time, an AHB handle is not yet provided.
|
||||
* Image layout will be filled up during vkBindImageMemory2
|
||||
*/
|
||||
*pImage = tu_image_to_handle(image);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
result = tu_image_update_layout(device, image, modifier,
|
||||
plane_layouts);
|
||||
if (result != VK_SUCCESS)
|
||||
@@ -841,12 +850,26 @@ tu_BindImageMemory2(VkDevice _device,
|
||||
#endif
|
||||
|
||||
if (mem) {
|
||||
VkResult result;
|
||||
if (vk_image_is_android_hardware_buffer(&image->vk)) {
|
||||
VkImageDrmFormatModifierExplicitCreateInfoEXT eci;
|
||||
VkSubresourceLayout a_plane_layouts[TU_MAX_PLANE_COUNT];
|
||||
result = vk_android_get_ahb_layout(mem->vk.ahardware_buffer,
|
||||
&eci, a_plane_layouts,
|
||||
TU_MAX_PLANE_COUNT);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
result = tu_image_update_layout(device, image, eci.drmFormatModifier, a_plane_layouts);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
image->bo = mem->bo;
|
||||
image->iova = mem->bo->iova + pBindInfos[i].memoryOffset;
|
||||
|
||||
if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
|
||||
if (!mem->bo->map) {
|
||||
VkResult result = tu_bo_map(device, mem->bo, NULL);
|
||||
result = tu_bo_map(device, mem->bo, NULL);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
@@ -132,4 +132,8 @@ tu_fragment_density_map_sample(const struct tu_image_view *fdm,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t layers, struct tu_frag_area *areas);
|
||||
|
||||
VkResult
|
||||
tu_image_update_layout(struct tu_device *device, struct tu_image *image,
|
||||
uint64_t modifier, const VkSubresourceLayout *plane_layouts);
|
||||
|
||||
#endif /* TU_IMAGE_H */
|
||||
|
Reference in New Issue
Block a user