lavapipe: Add AHB extension

Implement `VK_ANDROID_external_memory_android_hardware_buffer` on
lavapipe.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29344>
This commit is contained in:
Lucas Fryzek 2024-05-24 08:28:01 +01:00 committed by Marge Bot
parent a4de39c10d
commit cebb2bf266
3 changed files with 92 additions and 0 deletions

View file

@ -30,6 +30,8 @@
#include <hardware/hardware.h>
#include <hardware/hwvulkan.h>
#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vk_icd.h>
#include "util/libsync.h"
#include "util/os_file.h"
@ -37,6 +39,7 @@
#include "vk_fence.h"
#include "vk_semaphore.h"
#include "vk_android.h"
static int
lvp_hal_open(const struct hw_module_t *mod,
@ -175,3 +178,45 @@ lvp_QueueSignalReleaseImageANDROID(VkQueue _queue,
return VK_SUCCESS;
}
VkResult
lvp_import_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
const VkImportAndroidHardwareBufferInfoANDROID *info)
{
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;
uint64_t size;
int result = device->pscreen->import_memory_fd(device->pscreen, dma_buf, (struct pipe_memory_allocation**)&mem->pmem, &size, true);
if (!result)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
AHardwareBuffer_acquire(info->buffer);
mem->android_hardware_buffer = info->buffer;
mem->size = size;
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
return VK_SUCCESS;
}
VkResult
lvp_create_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
const VkMemoryAllocateInfo *pAllocateInfo)
{
mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
if (mem->android_hardware_buffer == NULL)
return VK_ERROR_OUT_OF_HOST_MEMORY;
const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
.buffer = mem->android_hardware_buffer,
};
VkResult result = lvp_import_ahb_memory(device, mem, &import_info);
/* Release a reference to avoid leak for AHB allocation. */
AHardwareBuffer_release(mem->android_hardware_buffer);
return result;
}

View file

@ -1270,6 +1270,8 @@ lvp_physical_device_init(struct lvp_physical_device *device,
device->vk.supported_extensions.KHR_external_semaphore_fd = true;
device->vk.supported_extensions.KHR_external_fence_fd = true;
}
if (supported_dmabuf_bits & DRM_PRIME_CAP_IMPORT)
device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer = true;
#endif
/* SNORM blending on llvmpipe fails CTS - disable by default */
@ -1860,6 +1862,9 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
struct lvp_device_memory *mem;
ASSERTED const VkExportMemoryAllocateInfo *export_info = NULL;
ASSERTED const VkImportMemoryFdInfoKHR *import_info = NULL;
#if DETECT_OS_ANDROID
ASSERTED const VkImportAndroidHardwareBufferInfoANDROID *ahb_import_info = NULL;
#endif
const VkImportMemoryHostPointerInfoEXT *host_ptr_info = NULL;
VkResult error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
@ -1890,6 +1895,12 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
priority = get_mem_priority(prio->priority);
break;
}
#if DETECT_OS_ANDROID
case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID: {
ahb_import_info = (VkImportAndroidHardwareBufferInfoANDROID*)ext;
break;
}
#endif
default:
break;
}
@ -1912,6 +1923,11 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DEFAULT;
mem->backed_fd = -1;
mem->size = pAllocateInfo->allocationSize;
#if DETECT_OS_ANDROID
mem->android_hardware_buffer = NULL;
#endif
if (host_ptr_info) {
mem->mem_alloc = (struct llvmpipe_memory_allocation) {
.cpu_addr = host_ptr_info->pHostPointer,
@ -1920,6 +1936,18 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
mem->map = host_ptr_info->pHostPointer;
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_USER_PTR;
}
#if DETECT_OS_ANDROID
else if(ahb_import_info) {
error = lvp_import_ahb_memory(device, mem, ahb_import_info);
if (error != VK_SUCCESS)
goto fail;
} else if(export_info &&
(export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
error = lvp_create_ahb_memory(device, mem, pAllocateInfo);
if (error != VK_SUCCESS)
goto fail;
}
#endif
#ifdef PIPE_MEMORY_FD
else if(import_info && import_info->handleType) {
bool dmabuf = import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;

View file

@ -49,6 +49,10 @@
#include "drm-uapi/drm_fourcc.h"
#endif
#if DETECT_OS_ANDROID
#include <vndk/hardware_buffer.h>
#endif
/* Pre-declarations needed for WSI entrypoints */
struct wl_surface;
struct wl_display;
@ -239,6 +243,12 @@ struct lvp_device_memory {
void * map;
enum lvp_device_memory_type memory_type;
int backed_fd;
#ifdef PIPE_MEMORY_FD
struct llvmpipe_memory_allocation *alloc;
#endif
#if DETECT_OS_ANDROID
struct AHardwareBuffer *android_hardware_buffer;
#endif
};
struct lvp_pipe_sync {
@ -778,6 +788,15 @@ lvp_nir_lower_sparse_residency(struct nir_shader *shader);
enum vk_cmd_type
lvp_nv_dgc_token_to_cmd_type(const VkIndirectCommandsLayoutTokenNV *token);
#if DETECT_OS_ANDROID
VkResult
lvp_import_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
const VkImportAndroidHardwareBufferInfoANDROID *info);
VkResult
lvp_create_ahb_memory(struct lvp_device *device, struct lvp_device_memory *mem,
const VkMemoryAllocateInfo *pAllocateInfo);
#endif
#ifdef __cplusplus
}
#endif