mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
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:
parent
4b024a15f2
commit
99753001f3
5 changed files with 99 additions and 8 deletions
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
#include "tu_android.h"
|
#include "tu_android.h"
|
||||||
|
|
||||||
|
#include <android/hardware_buffer.h>
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include <hardware/hwvulkan.h>
|
#include <hardware/hwvulkan.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "util/u_gralloc/u_gralloc.h"
|
#include "util/u_gralloc/u_gralloc.h"
|
||||||
#include "vk_android.h"
|
#include "vk_android.h"
|
||||||
|
|
@ -78,4 +80,3 @@ tu_hal_close(struct hw_device_t *dev)
|
||||||
vk_android_destroy_ugralloc();
|
vk_android_destroy_ugralloc();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#if DETECT_OS_ANDROID
|
#if DETECT_OS_ANDROID
|
||||||
#include "util/u_gralloc/u_gralloc.h"
|
#include "util/u_gralloc/u_gralloc.h"
|
||||||
|
#include <vndk/hardware_buffer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -296,6 +297,7 @@ get_device_extensions(const struct tu_physical_device *device,
|
||||||
|
|
||||||
#if DETECT_OS_ANDROID
|
#if DETECT_OS_ANDROID
|
||||||
if (vk_android_get_ugralloc() != NULL) {
|
if (vk_android_get_ugralloc() != NULL) {
|
||||||
|
ext->ANDROID_external_memory_android_hardware_buffer = true,
|
||||||
ext->ANDROID_native_buffer = true;
|
ext->ANDROID_native_buffer = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2757,12 +2759,6 @@ tu_AllocateMemory(VkDevice _device,
|
||||||
|
|
||||||
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
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;
|
struct tu_memory_heap *mem_heap = &device->physical_device->heap;
|
||||||
uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
|
uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
|
||||||
if (mem_heap_used > mem_heap->size)
|
if (mem_heap_used > mem_heap->size)
|
||||||
|
|
@ -2773,6 +2769,13 @@ tu_AllocateMemory(VkDevice _device,
|
||||||
if (mem == NULL)
|
if (mem == NULL)
|
||||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
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 =
|
const VkImportMemoryFdInfoKHR *fd_info =
|
||||||
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
|
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 */
|
/* take ownership and close the fd */
|
||||||
close(fd_info->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 {
|
} else {
|
||||||
uint64_t client_address = 0;
|
uint64_t client_address = 0;
|
||||||
BITMASK_ENUM(tu_bo_alloc_flags) alloc_flags = TU_BO_ALLOC_NO_FLAGS;
|
BITMASK_ENUM(tu_bo_alloc_flags) alloc_flags = TU_BO_ALLOC_NO_FLAGS;
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,17 @@
|
||||||
|
|
||||||
#include "fdl/fd6_format_table.h"
|
#include "fdl/fd6_format_table.h"
|
||||||
|
|
||||||
|
#include "vk_android.h"
|
||||||
#include "vk_enum_defines.h"
|
#include "vk_enum_defines.h"
|
||||||
#include "vk_util.h"
|
#include "vk_util.h"
|
||||||
#include "drm-uapi/drm_fourcc.h"
|
#include "drm-uapi/drm_fourcc.h"
|
||||||
|
|
||||||
|
#include "tu_android.h"
|
||||||
#include "tu_device.h"
|
#include "tu_device.h"
|
||||||
#include "tu_image.h"
|
#include "tu_image.h"
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_android.h>
|
||||||
|
|
||||||
/* Map non-colorspace-converted YUV formats to RGB pipe formats where we can,
|
/* Map non-colorspace-converted YUV formats to RGB pipe formats where we can,
|
||||||
* since our hardware doesn't support colorspace conversion.
|
* since our hardware doesn't support colorspace conversion.
|
||||||
*
|
*
|
||||||
|
|
@ -685,6 +689,12 @@ tu_get_external_image_format_properties(
|
||||||
handleType, pImageFormatInfo->type);
|
handleType, pImageFormatInfo->type);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
|
||||||
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
||||||
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
||||||
|
|
@ -717,6 +727,7 @@ tu_GetPhysicalDeviceImageFormatProperties2(
|
||||||
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
|
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
|
||||||
const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL;
|
const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL;
|
||||||
VkExternalImageFormatProperties *external_props = NULL;
|
VkExternalImageFormatProperties *external_props = NULL;
|
||||||
|
VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
|
||||||
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
||||||
VkFormatFeatureFlags format_feature_flags;
|
VkFormatFeatureFlags format_feature_flags;
|
||||||
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
||||||
|
|
@ -749,6 +760,9 @@ tu_GetPhysicalDeviceImageFormatProperties2(
|
||||||
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
|
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
|
||||||
external_props = (VkExternalImageFormatProperties *) s;
|
external_props = (VkExternalImageFormatProperties *) s;
|
||||||
break;
|
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:
|
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
|
||||||
cubic_props = (VkFilterCubicImageViewImageFormatPropertiesEXT *) s;
|
cubic_props = (VkFilterCubicImageViewImageFormatPropertiesEXT *) s;
|
||||||
break;
|
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)
|
if (ycbcr_props)
|
||||||
ycbcr_props->combinedImageSamplerDescriptorCount = 1;
|
ycbcr_props->combinedImageSamplerDescriptorCount = 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -765,6 +765,15 @@ tu_CreateImage(VkDevice _device,
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
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,
|
result = tu_image_update_layout(device, image, modifier,
|
||||||
plane_layouts);
|
plane_layouts);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
|
|
@ -841,12 +850,26 @@ tu_BindImageMemory2(VkDevice _device,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mem) {
|
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->bo = mem->bo;
|
||||||
image->iova = mem->bo->iova + pBindInfos[i].memoryOffset;
|
image->iova = mem->bo->iova + pBindInfos[i].memoryOffset;
|
||||||
|
|
||||||
if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
|
if (image->vk.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
|
||||||
if (!mem->bo->map) {
|
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)
|
if (result != VK_SUCCESS)
|
||||||
return result;
|
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 width, uint32_t height,
|
||||||
uint32_t layers, struct tu_frag_area *areas);
|
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 */
|
#endif /* TU_IMAGE_H */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue