Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> --- src/intel/vulkan/anv_android.c | 97 ++++++++++++++++++++++++++++++++++++++++++ src/intel/vulkan/anv_device.c | 48 ++++++++++++++++++++- src/intel/vulkan/anv_private.h | 18 ++++++++ 3 files changed, 162 insertions(+), 1 deletion(-)
diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index 6c0c8cc793..d1eb0b2e8b 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -187,6 +187,103 @@ anv_GetAndroidHardwareBufferPropertiesANDROID( return VK_SUCCESS; } +VkResult +anv_GetMemoryAndroidHardwareBufferANDROID( + VkDevice device_h, + const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo, + struct AHardwareBuffer **pBuffer) +{ + ANV_FROM_HANDLE(anv_device_memory, mem, pInfo->memory); + + /* Some quotes from Vulkan spec: + * + * "If the device memory was created by importing an Android hardware + * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same + * Android hardware buffer object." + * + * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must + * have been included in VkExportMemoryAllocateInfoKHR::handleTypes when + * memory was created." + */ + if (mem->ahw) { + *pBuffer = mem->ahw; + /* Increase refcount. */ + AHardwareBuffer_acquire(mem->ahw); + return VK_SUCCESS; + } + + return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR; +} + +/* + * Called from anv_AllocateMemory when import AHardwareBuffer. + */ +VkResult +anv_import_ahw_memory(VkDevice device_h, + struct anv_device_memory *mem, + const VkImportAndroidHardwareBufferInfoANDROID *info) +{ + ANV_FROM_HANDLE(anv_device, device, device_h); + + /* Get a description of buffer contents. */ + AHardwareBuffer_Desc desc; + AHardwareBuffer_describe(info->buffer, &desc); + VkResult result = VK_SUCCESS; + + /* Import from AHardwareBuffer to anv_device_memory. */ + const native_handle_t *handle = + AHardwareBuffer_getNativeHandle(info->buffer); + + int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1; + if (dma_buf < 0) + return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR; + + result = anv_bo_cache_import(device, &device->bo_cache, + dma_buf, &mem->bo); + if (result != VK_SUCCESS) + return result; + + close(dma_buf); + + /* "If the vkAllocateMemory command succeeds, the implementation must + * acquire a reference to the imported hardware buffer, which it must + * release when the device memory object is freed. If the command fails, + * the implementation must not retain a reference." + */ + AHardwareBuffer_acquire(info->buffer); + mem->ahw = info->buffer; + + return result; +} + +VkResult +anv_create_ahw_memory(VkDevice device_h, + struct anv_device_memory *mem, + const VkMemoryDedicatedAllocateInfo *info) +{ + ANV_FROM_HANDLE(anv_device, dev, device_h); + ANV_FROM_HANDLE(anv_image, image, info->image); + + struct AHardwareBuffer *ahw = NULL; + + /* Copy properties from the image. */ + struct AHardwareBuffer_Desc desc = { + .width = image->extent.width, + .height = image->extent.height, + .layers = 1, + .format = android_format_from_vk(image->vk_format), + .usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT, + .stride = 0, + }; + + if (AHardwareBuffer_allocate(&desc, &ahw) != 0) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + mem->ahw = ahw; + + return VK_SUCCESS; +} + VkResult anv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info, diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 374fc16c4c..63e3ddf171 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -1929,14 +1929,55 @@ VkResult anv_AllocateMemory( mem->type = &pdevice->memory.types[pAllocateInfo->memoryTypeIndex]; mem->map = NULL; mem->map_size = 0; + mem->ahw = NULL; + + /* Check if we need to support Android HW buffer export. If so, + * create AHardwareBuffer and import memory from it. + */ + bool android_export = false; + const VkExportMemoryAllocateInfo *export_info = + vk_find_struct_const(pAllocateInfo->pNext, + EXPORT_MEMORY_ALLOCATE_INFO); + + if (export_info && export_info->handleTypes & + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) + android_export = true; + + const VkMemoryDedicatedAllocateInfo *dedicated_info = + vk_find_struct_const(pAllocateInfo->pNext, + MEMORY_DEDICATED_ALLOCATE_INFO); + + /* Android memory import. */ + const struct VkImportAndroidHardwareBufferInfoANDROID *ahw_info = + vk_find_struct_const(pAllocateInfo->pNext, + IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID); const VkImportMemoryFdInfoKHR *fd_info = vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR); + /* Android export support required. */ + if (android_export && (dedicated_info && dedicated_info->image)) { +#ifdef ANDROID + anv_create_ahw_memory(device, mem, dedicated_info); + + const struct VkImportAndroidHardwareBufferInfoANDROID import_info = { + .buffer = mem->ahw, + }; + + result = anv_import_ahw_memory(device, mem, &import_info); + if (result != VK_SUCCESS) + goto fail; +#endif + } else if (ahw_info) { +#ifdef ANDROID + result = anv_import_ahw_memory(device, mem, ahw_info); + if (result != VK_SUCCESS) + goto fail; /* The Vulkan spec permits handleType to be 0, in which case the struct is * ignored. */ - if (fd_info && fd_info->handleType) { +#endif + } else if (fd_info && fd_info->handleType) { /* At the moment, we support only the below handle types. */ assert(fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || @@ -2097,6 +2138,11 @@ void anv_FreeMemory( anv_bo_cache_release(device, &device->bo_cache, mem->bo); +#ifdef ANDROID + if (mem->ahw) + AHardwareBuffer_release(mem->ahw); +#endif + vk_free2(&device->alloc, pAllocator, mem); } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index df769a13c6..1fe3c38191 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -80,6 +80,11 @@ struct gen_l3_config; #include "common/intel_log.h" #include "wsi_common.h" +#ifdef ANDROID +#include <vndk/hardware_buffer.h> +#include "vulkan/vulkan_android.h" +#endif + /* Allowing different clear colors requires us to perform a depth resolve at * the end of certain render passes. This is because while slow clears store * the clear color in the HiZ buffer, fast clears (without a resolve) don't. @@ -1190,6 +1195,11 @@ struct anv_device_memory { struct anv_memory_type * type; VkDeviceSize map_size; void * map; + + /* If set, we are holding reference to AHardwareBuffer + * which we must release when memory is freed. + */ + struct AHardwareBuffer * ahw; }; /** @@ -2864,6 +2874,14 @@ VkResult anv_image_from_gralloc(VkDevice device_h, const VkNativeBufferANDROID *gralloc_info, const VkAllocationCallbacks *alloc, VkImage *pImage); + +VkResult anv_import_ahw_memory(VkDevice device_h, + struct anv_device_memory *mem, + const VkImportAndroidHardwareBufferInfoANDROID *info); + +VkResult anv_create_ahw_memory(VkDevice device_h, + struct anv_device_memory *mem, + const VkMemoryDedicatedAllocateInfo *info); #endif const struct anv_surface * -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev